taler-typescript-core

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

commit 5b580579837ff6a9af91968b08e38d23f98e8de8
parent 5d4702c6d106705060f1bccbedd35bf3f7aacbc4
Author: Florian Dold <florian@dold.me>
Date:   Mon, 23 Feb 2026 20:46:41 +0100

extend merchant-kyc-auth-multi test

Diffstat:
Mpackages/taler-harness/src/integrationtests/test-merchant-kyc-auth-multi.ts | 249++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 145 insertions(+), 104 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-merchant-kyc-auth-multi.ts b/packages/taler-harness/src/integrationtests/test-merchant-kyc-auth-multi.ts @@ -18,6 +18,7 @@ * Imports. */ import { + AccessToken, Configuration, encodeCrock, getRandomBytes, @@ -28,14 +29,18 @@ import { succeedOrThrow, TalerMerchantInstanceHttpClient, TalerProtocolDuration, + TalerWireGatewayHttpClient, } from "@gnu-taler/taler-util"; import { configureCommonKyc, createKycTestkudosEnvironment, } from "../harness/environments.js"; import { + BankService, + ExchangeService, getTestHarnessPaytoForLabel, GlobalTestState, + MerchantService, } from "../harness/harness.js"; const myAmlConfig = ` @@ -88,6 +93,81 @@ function adjustExchangeConfig(config: Configuration) { const logger = new Logger("test-merchant-kyc-auth-multi.ts"); +async function doAccountKycAuth( + t: GlobalTestState, + args: { + exchange: ExchangeService; + merchant: MerchantService; + bank: BankService; + merchantInstId: string; + merchantInstPaytoUri: string; + merchantAccessToken: AccessToken; + wireGatewayApi: TalerWireGatewayHttpClient; + }, +): Promise<void> { + const { + merchant, + exchange, + merchantInstId, + merchantAccessToken, + merchantInstPaytoUri, + bank, + wireGatewayApi, + } = args; + const merchantClient = new TalerMerchantInstanceHttpClient( + merchant.makeInstanceBaseUrl(merchantInstId), + ); + { + const kycRes1 = succeedOrThrow( + await merchantClient.getCurrentInstanceKycStatus(merchantAccessToken, {}), + ); + console.log(`kyc res: ${j2s(kycRes1)}`); + t.assertDeepEqual(kycRes1.kycRequired, true); + const myRow = kycRes1.kyc_data.find( + (x) => x.exchange_url === exchange.baseUrl, + ); + t.assertTrue( + myRow?.payto_kycauths != null && myRow.payto_kycauths.length == 1, + ); + const authTxPayto = parsePaytoUriOrThrow(myRow.payto_kycauths[0]); + const authTxMessage = authTxPayto?.params["message"]; + t.assertTrue(typeof authTxMessage === "string"); + t.assertTrue(authTxMessage.startsWith("KYC:")); + const accountPub = authTxMessage.substring(4); + logger.info(`merchant account pub: ${accountPub}`); + await wireGatewayApi.addKycAuth({ + auth: bank.getAdminAuth(), + body: { + amount: "TESTKUDOS:0.1", + debit_account: merchantInstPaytoUri, + account_pub: accountPub, + }, + }); + } + + // Wait for auth transfer to be registered by the exchange + { + const kycStatus = await merchantClient.getCurrentInstanceKycStatus( + merchantAccessToken, + { + reason: KycStatusLongPollingReason.AUTH_TRANSFER, + timeout: 30000, + }, + ); + logger.info(`kyc status after transfer: ${j2s(kycStatus)}`); + t.assertDeepEqual(kycStatus.case, "ok"); + t.assertTrue(kycStatus.body.kycRequired === true); + const myRow = kycStatus.body.kyc_data.find( + (x) => + x.exchange_url === exchange.baseUrl && + x.payto_uri === merchantInstPaytoUri, + ); + t.assertTrue(myRow != null); + t.assertDeepEqual(myRow.status, "ready"); + t.assertTrue(typeof myRow.access_token === "string"); + } +} + /** * Test for multiple merchant instances using the same * bank account (with multiple public keys and thus KYC auth transfers). @@ -106,19 +186,17 @@ export async function runMerchantKycAuthMultiTest(t: GlobalTestState) { wireGatewayApi, } = await createKycTestkudosEnvironment(t, { adjustExchangeConfig }); - const merchantPayto = getTestHarnessPaytoForLabel("merchant-default"); - - await bankClient.registerAccountExtended({ - name: "merchant-default", - password: encodeCrock(getRandomBytes(32)), - username: "merchant-default", - payto_uri: merchantPayto, - }); - { const merchantInstId = "minst1"; const merchantInstPaytoUri = getTestHarnessPaytoForLabel(merchantInstId); + await bankClient.registerAccountExtended({ + name: merchantInstId, + password: encodeCrock(getRandomBytes(32)), + username: merchantInstId, + payto_uri: merchantInstPaytoUri, + }); + const m1Res = await merchant.addInstanceWithWireAccount( { id: merchantInstId, @@ -131,51 +209,53 @@ export async function runMerchantKycAuthMultiTest(t: GlobalTestState) { { adminAccessToken: merchantAdminAccessToken }, ); - await bankClient.registerAccountExtended({ - name: merchantInstId, - password: encodeCrock(getRandomBytes(32)), - username: merchantInstId, - payto_uri: merchantInstPaytoUri, - }); + const merchantAccessToken = m1Res.accessToken; await merchant.runExchangekeyupdateOnce(); await merchant.runKyccheckOnce(); + await doAccountKycAuth(t, { + exchange, + merchant, + bank, + merchantInstId, + merchantAccessToken, + merchantInstPaytoUri, + wireGatewayApi, + }); + const merchantClient = new TalerMerchantInstanceHttpClient( - merchant.makeInstanceBaseUrl("minst1"), + merchant.makeInstanceBaseUrl(merchantInstId), ); - { - const kycRes1 = succeedOrThrow( - await merchantClient.getCurrentInstanceKycStatus(m1Res.accessToken, {}), - ); - console.log(`kyc res: ${j2s(kycRes1)}`); - t.assertDeepEqual(kycRes1.kycRequired, true); - const myRow = kycRes1.kyc_data.find( - (x) => x.exchange_url === exchange.baseUrl, - ); - t.assertTrue( - myRow?.payto_kycauths != null && myRow.payto_kycauths.length == 1, - ); - const authTxPayto = parsePaytoUriOrThrow(myRow.payto_kycauths[0]); - const authTxMessage = authTxPayto?.params["message"]; - t.assertTrue(typeof authTxMessage === "string"); - t.assertTrue(authTxMessage.startsWith("KYC:")); - const accountPub = authTxMessage.substring(4); - logger.info(`merchant account pub: ${accountPub}`); - await wireGatewayApi.addKycAuth({ - auth: bank.getAdminAuth(), - body: { - amount: "TESTKUDOS:0.1", - debit_account: merchantInstPaytoUri, - account_pub: accountPub, - }, - }); - } - // Wait for auth transfer to be registered by the exchange + const accounts1 = succeedOrThrow( + await merchantClient.listBankAccounts(m1Res.accessToken), + ); + t.assertDeepEqual(accounts1.accounts.length, 1); + await merchantClient.deleteBankAccount( + merchantAccessToken, + accounts1.accounts[0].h_wire, + ); + const accounts2 = succeedOrThrow( + await merchantClient.listBankAccounts(m1Res.accessToken), + ); + console.log(`accounts after deletion: ${j2s(accounts2)}`); + + // Now re-add same account + await merchantClient.addBankAccount(m1Res.accessToken, { + payto_uri: merchantInstPaytoUri, + }); + + const accounts3 = succeedOrThrow( + await merchantClient.listBankAccounts(m1Res.accessToken), + ); + console.log(`accounts after re-adding: ${j2s(accounts3)}`); + + // Now we should now have to do KYC auth again, same instance, + // account was just re-added. { const kycStatus = await merchantClient.getCurrentInstanceKycStatus( - m1Res.accessToken, + merchantAccessToken, { reason: KycStatusLongPollingReason.AUTH_TRANSFER, timeout: 30000, @@ -185,7 +265,9 @@ export async function runMerchantKycAuthMultiTest(t: GlobalTestState) { t.assertDeepEqual(kycStatus.case, "ok"); t.assertTrue(kycStatus.body.kycRequired === true); const myRow = kycStatus.body.kyc_data.find( - (x) => x.exchange_url === exchange.baseUrl, + (x) => + x.exchange_url === exchange.baseUrl && + x.payto_uri === merchantInstPaytoUri, ); t.assertTrue(myRow != null); t.assertDeepEqual(myRow.status, "ready"); @@ -199,7 +281,14 @@ export async function runMerchantKycAuthMultiTest(t: GlobalTestState) { const merchantInstId = "minst2"; const merchantInstPaytoUri = getTestHarnessPaytoForLabel(merchantInstId); - const m1Res = await merchant.addInstanceWithWireAccount( + await bankClient.registerAccountExtended({ + name: merchantInstId, + password: encodeCrock(getRandomBytes(32)), + username: merchantInstId, + payto_uri: merchantInstPaytoUri, + }); + + const m2Res = await merchant.addInstanceWithWireAccount( { id: merchantInstId, name: merchantInstId, @@ -211,66 +300,18 @@ export async function runMerchantKycAuthMultiTest(t: GlobalTestState) { { adminAccessToken: merchantAdminAccessToken }, ); - await bankClient.registerAccountExtended({ - name: merchantInstId, - password: encodeCrock(getRandomBytes(32)), - username: merchantInstId, - payto_uri: merchantInstPaytoUri, - }); - await merchant.runExchangekeyupdateOnce(); await merchant.runKyccheckOnce(); - const merchantClient = new TalerMerchantInstanceHttpClient( - merchant.makeInstanceBaseUrl("minst1"), - ); - { - const kycRes1 = succeedOrThrow( - await merchantClient.getCurrentInstanceKycStatus(m1Res.accessToken, {}), - ); - console.log(`kyc res: ${j2s(kycRes1)}`); - t.assertDeepEqual(kycRes1.kycRequired, true); - const myRow = kycRes1.kyc_data.find( - (x) => x.exchange_url === exchange.baseUrl, - ); - t.assertTrue( - myRow?.payto_kycauths != null && myRow.payto_kycauths.length == 1, - ); - const authTxPayto = parsePaytoUriOrThrow(myRow.payto_kycauths[0]); - const authTxMessage = authTxPayto?.params["message"]; - t.assertTrue(typeof authTxMessage === "string"); - t.assertTrue(authTxMessage.startsWith("KYC:")); - const accountPub = authTxMessage.substring(4); - logger.info(`merchant account pub: ${accountPub}`); - await wireGatewayApi.addKycAuth({ - auth: bank.getAdminAuth(), - body: { - amount: "TESTKUDOS:0.1", - debit_account: merchantInstPaytoUri, - account_pub: accountPub, - }, - }); - } - - // Wait for auth transfer to be registered by the exchange - { - const kycStatus = await merchantClient.getCurrentInstanceKycStatus( - m1Res.accessToken, - { - reason: KycStatusLongPollingReason.AUTH_TRANSFER, - timeout: 30000, - }, - ); - logger.info(`kyc status after transfer: ${j2s(kycStatus)}`); - t.assertDeepEqual(kycStatus.case, "ok"); - t.assertTrue(kycStatus.body.kycRequired === true); - const myRow = kycStatus.body.kyc_data.find( - (x) => x.exchange_url === exchange.baseUrl, - ); - t.assertTrue(myRow != null); - t.assertDeepEqual(myRow.status, "ready"); - t.assertTrue(typeof myRow.access_token === "string"); - } + await doAccountKycAuth(t, { + exchange, + merchant, + bank, + merchantInstId, + merchantAccessToken: m2Res.accessToken, + merchantInstPaytoUri, + wireGatewayApi, + }); } t.logStep("second-account-ready");