diff options
3 files changed, 172 insertions, 0 deletions
diff --git a/packages/taler-harness/src/integrationtests/test-kyc-merchant-activate-bank-account.ts b/packages/taler-harness/src/integrationtests/test-kyc-merchant-activate-bank-account.ts new file mode 100644 index 000000000..f5fb6c54f --- /dev/null +++ b/packages/taler-harness/src/integrationtests/test-kyc-merchant-activate-bank-account.ts @@ -0,0 +1,154 @@ +/* + 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 <http://www.gnu.org/licenses/> + */ + +/** + * Imports. + */ +import { + AmountString, + codecForAccountKycRedirects, + codecForKycProcessClientInformation, + codecForQueryInstancesResponse, + encodeCrock, + hashPaytoUri, + j2s, + Logger, + MerchantAccountKycRedirectsResponse, + TalerMerchantApi, + WireGatewayApiClient, +} from "@gnu-taler/taler-util"; +import { + readResponseJsonOrThrow, + readSuccessResponseJsonOrThrow, +} from "@gnu-taler/taler-util/http"; +import { + createKycTestkudosEnvironment, + postAmlDecisionNoRules, + withdrawViaBankV3, +} from "../harness/environments.js"; +import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; + +const logger = new Logger(`test-kyc-merchant-deposit.ts`); + +export async function runKycMerchantActivateBankAccountTest(t: GlobalTestState) { + // Set up test environment + + const { + merchant, + walletClient, + bankClient, + exchange, + exchangeBankAccount, + amlKeypair, + } = await createKycTestkudosEnvironment(t, { + adjustExchangeConfig(config) { + config.setString("exchange", "enable_kyc", "yes"); + + // no kyc depoist 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 new Promise<void>((resolve) => { + setTimeout(() => resolve(), 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" }) + 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 wireTransfer = await bankClient.makeTransaction("TESTKUDOS:1" as AmountString, kycRespOne.kyc_data[0].payto_kycauths![0]) + logger.info(`auth wire transfer: ${wireTransfer}`); + + let kycRespTwo: MerchantAccountKycRedirectsResponse | undefined = undefined; + + // We do this in a loop as a work-around. + // Not exactly the correct behavior from the merchant right now. + 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 new Promise<void>((resolve) => { + setTimeout(() => resolve(), 500); + }); + } + + t.assertTrue(!!kycRespTwo); + + t.assertDeepEqual(kycRespTwo.kyc_data[0].exchange_http_status, 200); + +} + +runKycMerchantActivateBankAccountTest.suites = ["wallet", "merchant", "kyc"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts index 3bc142f2d..0a5382e04 100644 --- a/packages/taler-harness/src/integrationtests/testrunner.ts +++ b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -144,6 +144,7 @@ import { runWithdrawalHugeTest } from "./test-withdrawal-huge.js"; import { runWithdrawalIdempotentTest } from "./test-withdrawal-idempotent.js"; import { runWithdrawalManualTest } from "./test-withdrawal-manual.js"; import { runWithdrawalPrepareTest } from "./test-withdrawal-prepare.js"; +import { runKycMerchantActivateBankAccountTest } from "./test-kyc-merchant-activate-bank-account.js"; /** * Test runner. @@ -278,6 +279,7 @@ const allTests: TestMainFunction[] = [ runRepurchaseTest, runWalletTransactionsTest, runKycWithdrawalVerbotenTest, + runKycMerchantActivateBankAccountTest, ]; export interface TestRunSpec { diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts index 67cde0c18..d45f338f3 100644 --- a/packages/taler-util/src/bank-api-client.ts +++ b/packages/taler-util/src/bank-api-client.ts @@ -23,6 +23,7 @@ */ import { AccountData, + AmountJson, AmountString, base64FromArrayBuffer, buildCodecForObject, @@ -37,6 +38,7 @@ import { opEmptySuccess, opKnownHttpFailure, opUnknownFailure, + PaytoString, RegisterAccountRequest, stringToBytes, TalerError, @@ -221,6 +223,20 @@ export class TalerCorebankApiClient { return readSuccessResponseJsonOrThrow(resp, codecForAny()); } + async makeTransaction(amount: AmountString, target: PaytoString): Promise<void> { + const reqUrl = new URL(`accounts/${this.args.auth!.username}/transactions`, this.baseUrl); + const resp = await this.httpLib.fetch(reqUrl.href, { + method: "POST", + headers: { + ...this.makeAuthHeader(), + }, + }); + + const res = await readSuccessResponseJsonOrThrow(resp, codecForAny()); + logger.info(`result: ${j2s(res)}`); + } + + async getTransactions(username: string): Promise<void> { const reqUrl = new URL(`accounts/${username}/transactions`, this.baseUrl); const resp = await this.httpLib.fetch(reqUrl.href, { |