taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit cb66e904aa520cc71da99ba0aa2906a935151a9f
parent 7f19c1318a9ee9dfb09349ef65a2bbcdde1c08d7
Author: Florian Dold <dold@taler.net>
Date:   Thu, 20 Aug 2026 19:06:43 +0200

wallet-core: bind open-banking URLs into account signatures

Diffstat:
Mpackages/taler-wallet-core/src/exchanges.test.ts | 30+++++++++++++++++++++++++++++-
Mpackages/taler-wallet-core/src/exchanges.ts | 32++++++++++++++++++++++----------
2 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/packages/taler-wallet-core/src/exchanges.test.ts b/packages/taler-wallet-core/src/exchanges.test.ts @@ -17,7 +17,10 @@ import assert from "node:assert"; import { test } from "node:test"; import { WalletCoin } from "./db-common.js"; -import { filterCoinsByExchangeMasterPub } from "./exchanges.js"; +import { + filterCoinsByExchangeMasterPub, + makeWireAccountValidationRequest, +} from "./exchanges.js"; test("denomination loss processing is scoped to one exchange master key", () => { const current = { @@ -43,3 +46,28 @@ test("denomination loss processing is scoped to one exchange master key", () => [current], ); }); + +test("wire validation covers both protocol v34 gateway URLs", () => { + const request = makeWireAccountValidationRequest( + { + payto_uri: "payto://iban/DE123", + conversion_url: "https://conversion.example/", + open_banking_gateway: "https://open-banking.example/", + prepared_transfer_url: "https://transfer.example/", + credit_restrictions: [], + debit_restrictions: [], + master_sig: "master-signature" as any, + }, + 34, + "master-public-key", + ); + + assert.strictEqual( + request.openBankingGatewayUrl, + "https://open-banking.example/", + ); + assert.strictEqual( + request.wireTransferGatewayUrl, + "https://transfer.example/", + ); +}); diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts @@ -58,6 +58,7 @@ import { ExchangeTosStatus, ExchangeUpdateStatus, ExchangeWalletKycStatus, + ExchangeWireAccount, ExchangesListResponse, FeeDescription, GetExchangeEntryByUrlRequest, @@ -805,6 +806,24 @@ export async function forgetExchangeTermsOfService( * * Throw an exception if they are invalid. */ +export function makeWireAccountValidationRequest( + account: ExchangeWireAccount, + versionCurrent: number, + masterPublicKey: string, +) { + return { + masterPub: masterPublicKey, + paytoUri: account.payto_uri, + sig: account.master_sig, + versionCurrent, + conversionUrl: account.conversion_url, + openBankingGatewayUrl: account.open_banking_gateway, + creditRestrictions: account.credit_restrictions, + debitRestrictions: account.debit_restrictions, + wireTransferGatewayUrl: account.prepared_transfer_url, + }; +} + async function validateWireInfo( wex: WalletExecutionContext, versionCurrent: number, @@ -817,16 +836,9 @@ async function validateWireInfo( if (wex.ws.config.testing.insecureTrustExchange) { isValid = true; } else { - const { valid: v } = await wex.ws.cryptoApi.isValidWireAccount({ - masterPub: masterPublicKey, - paytoUri: a.payto_uri, - sig: a.master_sig, - versionCurrent, - conversionUrl: a.conversion_url, - creditRestrictions: a.credit_restrictions, - debitRestrictions: a.debit_restrictions, - wireTransferGatewayUrl: a.prepared_transfer_url, - }); + const { valid: v } = await wex.ws.cryptoApi.isValidWireAccount( + makeWireAccountValidationRequest(a, versionCurrent, masterPublicKey), + ); isValid = v; } if (!isValid) {