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:
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) {