/* This file is part of GNU Taler (C) 2024 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see */ /** * Imports. */ import { codecForAccountKycRedirects, codecForQueryInstancesResponse, j2s, Logger, MerchantAccountKycRedirectsResponse, parsePaytoUri, WireGatewayApiClient, } from "@gnu-taler/taler-util"; import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http"; import { createKycTestkudosEnvironment } from "../harness/environments.js"; import { delayMs, GlobalTestState, harnessHttpLib, } from "../harness/harness.js"; const logger = new Logger(`test-kyc-merchant-activate-bank-account.ts`); export async function runKycMerchantActivateBankAccountTest( t: GlobalTestState, ) { // Set up test environment const { merchant, bankClient, exchangeBankAccount } = await createKycTestkudosEnvironment(t, { adjustExchangeConfig(config) { config.setString("exchange", "enable_kyc", "yes"); // no kyc deposit requirement, the exchange // just need the merchant to prove the that it is the // legal owner of the account making a simple // wire transfer }, }); let accountPub: string; { const instanceUrl = new URL("private", merchant.makeInstanceBaseUrl()); const resp = await harnessHttpLib.fetch(instanceUrl.href); const parsedResp = await readSuccessResponseJsonOrThrow( resp, codecForQueryInstancesResponse(), ); accountPub = parsedResp.merchant_pub; } let kycRespOne: MerchantAccountKycRedirectsResponse | undefined = undefined; while (1) { const kycStatusUrl = new URL("private/kyc", merchant.makeInstanceBaseUrl()) .href; logger.info(`requesting GET ${kycStatusUrl}`); const resp = await harnessHttpLib.fetch(kycStatusUrl); if (resp.status === 200) { kycRespOne = await readSuccessResponseJsonOrThrow( resp, codecForAccountKycRedirects(), ); break; } // Wait 500ms await delayMs(500); } t.assertTrue(!!kycRespOne); logger.info(`mechant kyc status: ${j2s(kycRespOne)}`); // the exchange replies with 404 // meaning that the bank account is not yet known by the exchange t.assertDeepEqual(kycRespOne.kyc_data[0].exchange_http_status, 404); // prove that we own the account by sending some money from // the merchant account bankClient.setAuth({ username: "merchant-default", password: "merchant-default", }); await bankClient.registerAccountExtended({ name: "merchant-default", password: "merchant-default", username: "merchant-default", payto_uri: kycRespOne.kyc_data[0].payto_uri, //this bank user needs to have the same payto that the exchange is asking from }); const wireGatewayApiClient = new WireGatewayApiClient( exchangeBankAccount.wireGatewayApiBaseUrl, { auth: { username: "admin", password: "admin-password", }, }, ); const kycauthPayto = kycRespOne.kyc_data[0].payto_kycauths![0]; logger.info(`kycauth payto: ${kycauthPayto}`); const p = parsePaytoUri(kycauthPayto); const msgAccountPub = p?.params["message"]; t.assertTrue(!!accountPub); // FIXME: This is kinda brittle, would be better to pick out // what looks like a public key from the message. t.assertDeepEqual(`KYC:${accountPub}`, msgAccountPub); await wireGatewayApiClient.adminAddKycauth({ amount: "TESTKUDOS:0.1", debitAccountPayto: kycRespOne.kyc_data[0].payto_uri, accountPub, }); let kycRespTwo: MerchantAccountKycRedirectsResponse | undefined = undefined; // Loop requesting the KYC status. // The merchant currently doesn't support long-polling for this. while (true) { const kycStatusLongpollUrl = new URL( "private/kyc", merchant.makeInstanceBaseUrl(), ); kycStatusLongpollUrl.searchParams.set("lpt", "1"); const resp = await harnessHttpLib.fetch(kycStatusLongpollUrl.href); t.assertDeepEqual(resp.status, 200); const parsedResp = await readSuccessResponseJsonOrThrow( resp, codecForAccountKycRedirects(), ); logger.info(`kyc resp 2: ${j2s(parsedResp)}`); if (parsedResp.kyc_data[0].payto_kycauths == null) { kycRespTwo = parsedResp; break; } // Wait 500ms await delayMs(500); } t.assertTrue(!!kycRespTwo); t.assertDeepEqual(kycRespTwo.kyc_data[0].exchange_http_status, 200); } runKycMerchantActivateBankAccountTest.suites = ["wallet", "merchant", "kyc"];