commit ce43cdb43bd272898ac24e44b1eb3d82a1ca5e0c
parent 88b48211f9c2c1ccd03451376ef29998e7f55fd8
Author: Florian Dold <florian@dold.me>
Date: Wed, 25 Mar 2026 14:22:22 +0100
wallet-core: support wire account signatures for exchange protocol v34
Diffstat:
3 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/packages/taler-util/src/http-client/exchange-client.ts b/packages/taler-util/src/http-client/exchange-client.ts
@@ -146,7 +146,7 @@ export enum TalerExchangeCacheEviction {
* Client library for the GNU Taler exchange service.
*/
export class TalerExchangeHttpClient {
- public static readonly SUPPORTED_EXCHANGE_PROTOCOL_VERSION = "31:0:6";
+ public static readonly SUPPORTED_EXCHANGE_PROTOCOL_VERSION = "34:0:9";
private httpLib: HttpRequestLibrary;
private cacheEvictor: CacheEvictor<TalerExchangeCacheEviction>;
private preventCompression: boolean;
diff --git a/packages/taler-util/src/types-taler-exchange.ts b/packages/taler-util/src/types-taler-exchange.ts
@@ -149,7 +149,6 @@ export const codecForDenominationPubKey = () =>
.alternative(DenomKeyType.ClauseSchnorr, codecForCsDenominationPubKey())
.build("DenominationPubKey");
-
/**
* Signature by the auditor that a particular denomination key is audited.
*/
@@ -772,6 +771,18 @@ export interface ExchangeWireAccount {
// conversion is applicable.
conversion_url?: string;
+ // Open banking gateway base URL where wallets can
+ // initiate wire transfers to withdraw
+ // digital cash from this exchange.
+ // @since protocol **v34**.
+ open_banking_gateway?: string;
+
+ // Wire transfer gateway base URL where wallets and merchants can
+ // request (short) wire transfer subjects to wire funds to this
+ // exchange without having to encode the full public key.
+ // @since protocol **v34**.
+ wire_transfer_gateway?: string;
+
// Restrictions that apply to bank accounts that would send
// funds to the exchange (crediting this exchange bank account).
// Optional, empty array for unrestricted.
@@ -798,6 +809,8 @@ export interface ExchangeWireAccount {
export const codecForExchangeWireAccount = (): Codec<ExchangeWireAccount> =>
buildCodecForObject<ExchangeWireAccount>()
.property("conversion_url", codecOptional(codecForStringURL()))
+ .property("open_banking_gateway", codecOptional(codecForStringURL()))
+ .property("wire_transfer_gateway", codecOptional(codecForStringURL()))
.property("credit_restrictions", codecForList(codecForAny()))
.property("debit_restrictions", codecForList(codecForAny()))
.property("master_sig", codecForEddsaSignature())
@@ -1788,7 +1801,7 @@ export interface ExchangeVersionResponse {
currency_specification: CurrencySpecification;
// Names of supported KYC requirements.
- supported_kyc_requirements: string[];
+ supported_kyc_requirements?: string[];
// Bank-specific dialect for the AML SPA. Determines
// which set of forms is available as well as statistics
@@ -2475,7 +2488,10 @@ export const codecForExchangeConfig = (): Codec<ExchangeVersionResponse> =>
.property("implementation", codecOptional(codecForURN()))
.property("currency", codecForString())
.property("currency_specification", codecForCurrencySpecificiation())
- .property("supported_kyc_requirements", codecForList(codecForString()))
+ .property(
+ "supported_kyc_requirements",
+ codecOptional(codecForList(codecForString())),
+ )
.property("aml_spa_dialect", codecOptional(codecForAmlSpaDialect))
.deprecatedProperty("shopping_url")
.deprecatedProperty("wallet_balance_limit_without_kyc")
@@ -3254,7 +3270,7 @@ export type PurseConflict =
| PurseCreateConflict
| PurseDepositConflict
| PurseContractConflict;
-
+
export type PurseConflictPartial =
| PurseCreateConflict
| PurseDepositConflict
diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts
@@ -719,6 +719,8 @@ export interface WireAccountValidationRequest {
sig: string;
masterPub: string;
conversionUrl?: string;
+ openBankingGatewayUrl?: string;
+ wireTransferGatewayUrl?: string;
debitRestrictions?: any[];
creditRestrictions?: any[];
}
@@ -793,6 +795,14 @@ export interface TransferPubResponse {
transferPriv: string;
}
+function hashStringOrNull(s?: string): Uint8Array {
+ if (s) {
+ return hash(stringToBytes(s + "\0"));
+ } else {
+ return new Uint8Array(64);
+ }
+}
+
/**
* JS-native implementation of the Taler crypto worker operations.
*/
@@ -1258,13 +1268,11 @@ export const nativeCryptoR: TalerCryptoInterfaceR = {
const pb = buildSigPS(TalerSignaturePurpose.MASTER_WIRE_DETAILS);
pb.put(paytoHash);
if (req.versionCurrent >= 15) {
- let conversionUrlHash;
- if (!req.conversionUrl) {
- conversionUrlHash = new Uint8Array(64);
- } else {
- conversionUrlHash = hash(stringToBytes(req.conversionUrl + "\0"));
+ pb.put(hashStringOrNull(req.conversionUrl));
+ if (req.versionCurrent >= 34) {
+ pb.put(hashStringOrNull(req.openBankingGatewayUrl));
+ pb.put(hashStringOrNull(req.wireTransferGatewayUrl));
}
- pb.put(conversionUrlHash);
pb.put(hash(stringToBytes(canonicalJson(req.debitRestrictions) + "\0")));
pb.put(hash(stringToBytes(canonicalJson(req.creditRestrictions) + "\0")));
}