taler-typescript-core

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

commit 050f83209862511b4dfc83dda871960cd9129423
parent 4a4977f9b8fc501ef6c6120c35bf5c2f216383dd
Author: Florian Dold <florian@dold.me>
Date:   Thu,  5 Jun 2025 12:39:30 +0200

-missing file

Diffstat:
Apackages/taler-harness/src/integrationtests/test-tops-peer.ts | 195+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 195 insertions(+), 0 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-tops-peer.ts b/packages/taler-harness/src/integrationtests/test-tops-peer.ts @@ -0,0 +1,195 @@ +/* + This file is part of GNU Taler + (C) 2025 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 { + AbsoluteTime, + AccessToken, + Duration, + j2s, + Logger, + succeedOrThrow, + TransactionMajorState, + TransactionMinorState, + TransactionType, +} from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { withdrawViaBankV3 } from "../harness/environments.js"; +import { startFakeChallenger } from "../harness/fake-challenger.js"; +import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; +import { createTopsEnvironment } from "../harness/tops.js"; + +const logger = new Logger("test-tops-aml.ts"); + +export async function runTopsPeerTest(t: GlobalTestState) { + // Set up test environment + + const { + walletClient, + bankClient, + exchange, + amlKeypair, + merchant, + exchangeBankAccount, + wireGatewayApi, + exchangeApi, + } = await createTopsEnvironment(t); + + const challenger = await startFakeChallenger({ + port: 6001, + addressType: "postal-ch", + }); + + t.logStep("starting withdrawal"); + + // Withdrawal below threshold succeeds! + const wres = await withdrawViaBankV3(t, { + amount: "CHF:20", + bankClient, + exchange, + walletClient, + }); + + await wres.withdrawalFinishedCond; + + t.logStep("withdrawal done"); + + const peerResp = await walletClient.call( + WalletApiOperation.InitiatePeerPushDebit, + { + partialContractTerms: { + amount: "CHF:5", + purse_expiration: AbsoluteTime.toProtocolTimestamp( + AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ minutes: 5 }), + ), + ), + summary: "Test", + }, + }, + ); + + await walletClient.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: peerResp.transactionId, + txState: { + major: TransactionMajorState.Pending, + minor: TransactionMinorState.Ready, + }, + }); + + t.logStep("p2p ready"); + + const pushDebitTxDet = await walletClient.call( + WalletApiOperation.GetTransactionById, + { + transactionId: peerResp.transactionId, + }, + ); + t.assertDeepEqual(pushDebitTxDet.type, TransactionType.PeerPushDebit); + const talerUri = pushDebitTxDet.talerUri; + t.assertTrue(typeof talerUri === "string"); + + const prepareResp = await walletClient.call( + WalletApiOperation.PreparePeerPushCredit, + { + talerUri, + }, + ); + + await walletClient.call(WalletApiOperation.ConfirmPeerPushCredit, { + transactionId: prepareResp.transactionId, + }); + + t.logStep("p2p confirmed"); + + await walletClient.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: prepareResp.transactionId, + txState: { + major: TransactionMajorState.Pending, + minor: TransactionMinorState.MergeKycRequired, + }, + }); + + const pushCreditTxDet = await walletClient.call( + WalletApiOperation.GetTransactionById, + { + transactionId: prepareResp.transactionId, + }, + ); + + const accessToken = pushCreditTxDet.kycAccessToken; + + t.assertTrue(typeof accessToken === "string"); + + const infoResp = await exchangeApi.checkKycInfo(accessToken as AccessToken); + + console.log(j2s(infoResp)); + + t.assertDeepEqual(infoResp.case, "ok"); + + const myId = infoResp.body.requirements.find((x) => + x.description.includes("TAN letter"), + )?.id; + t.assertTrue(!!myId); + + const startResp = succeedOrThrow( + await exchangeApi.startExternalKycProcess(myId, {}), + ); + console.log(`start resp`, j2s(startResp)); + + let challengerRedirectUrl = startResp.redirect_url; + + const resp = await harnessHttpLib.fetch(challengerRedirectUrl); + const respJson = await resp.json(); + console.log(`challenger resp: ${j2s(respJson)}`); + + const nonce = respJson.nonce; + t.assertTrue(typeof nonce === "string"); + const proofRedirectUrl = respJson.redirect_url; + + challenger.fakeVerification(nonce, { + CONTACT_NAME: "Richard Stallman", + ADDRESS_LINES: "Bundesgasse 1\n1234 Bern", + }); + + console.log("nonce", nonce); + console.log("proof redirect URL", proofRedirectUrl); + + const proofResp = await harnessHttpLib.fetch(proofRedirectUrl, { + redirect: "manual", + }); + console.log("proof status:", proofResp.status); + if (proofResp.status === 404) { + console.log(j2s(await proofResp.text())); + } + t.assertDeepEqual(proofResp.status, 303); + + const infoResp2 = await exchangeApi.checkKycInfo(accessToken as AccessToken); + + console.log(j2s(infoResp2)); + + if ( + infoResp2.case === "ok" && + infoResp2.body.requirements[0].form === "accept-tos" + ) { + t.fail("requirements include ToS, but client wants to do p2p"); + } +} + +runTopsPeerTest.suites = ["wallet"];