taler-typescript-core

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

commit 250e2cbcf9a370643ac1020943844722eb8306f4
parent d9544b558919d780f095c0219f4c3e4579be9bdf
Author: Florian Dold <florian@dold.me>
Date:   Fri, 24 Jul 2026 17:26:30 +0200

add more convenient subcommand for peer-send

Diffstat:
Mpackages/taler-wallet-cli/src/index.ts | 91++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 83 insertions(+), 8 deletions(-)

diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts @@ -19,7 +19,6 @@ */ import { AbsoluteTime, - addPaytoQueryParams, AgeRestriction, Amounts, AmountString, @@ -33,13 +32,13 @@ import { ExchangeTosStatus, getErrorDetailFromException, getRandomBytes, + getSampleWalletCoreTransactions, InitRequest, j2s, Logger, NotificationType, Paytos, Result, - getSampleWalletCoreTransactions, setDangerousTimetravel, setGlobalLogLevelFromString, summarizeTalerErrorDetail, @@ -50,6 +49,7 @@ import { TransactionMinorState, TransactionType, WalletNotification, + WithdrawalType, } from "@gnu-taler/taler-util"; import { clk } from "@gnu-taler/taler-util/clk"; import { @@ -760,6 +760,67 @@ walletCli }); }); +walletCli + .subcommand("payPush", "peer-send", { + help: "Initiate a peer-push payment.", + }) + .requiredArgument("amount", clk.AMOUNT, { + help: "Amount to pay", + }) + .maybeOption("summary", ["--summary"], clk.STRING, { + help: "Summary to use in the contract terms.", + }) + .maybeOption("purseExpiration", ["--purse-expiration"], clk.STRING) + .action(async (args) => { + let purseExpiration: AbsoluteTime; + + if (args.payPush.purseExpiration) { + purseExpiration = AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromPrettyString(args.payPush.purseExpiration), + ); + } else { + purseExpiration = AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ hours: 1 }), + ); + } + + await withWallet(args, { lazyTaskLoop: true }, async (wallet) => { + const resp = await wallet.client.call( + WalletApiOperation.InitiatePeerPushDebit, + { + partialContractTerms: { + amount: args.payPush.amount, + summary: args.payPush.summary ?? "Payment", + purse_expiration: AbsoluteTime.toProtocolTimestamp(purseExpiration), + }, + }, + ); + await wallet.client.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: resp.transactionId, + txState: { + major: TransactionMajorState.Pending, + minor: TransactionMinorState.Ready, + }, + }); + const txDet = await wallet.client.call( + WalletApiOperation.GetTransactionById, + { + transactionId: resp.transactionId, + }, + ); + if (txDet.type !== TransactionType.PeerPushDebit) { + throw Error("assertion failed"); + } + if (txDet.talerUri == null) { + throw Error("assertion failed"); + } + console.log("peer payment ready to send"); + console.log(txDet.talerUri); + }); + }); + const withdrawCli = walletCli.subcommand("withdraw", "withdraw", { help: "Withdraw with a taler://withdraw/ URI", }); @@ -1142,13 +1203,27 @@ withdrawCli forceReservePriv: args.withdrawManually.forcedReservePriv, }, ); - const reservePub = resp.reservePub; - const completePaytoUri = addPaytoQueryParams(acct.paytoUri, { - amount: args.withdrawManually.amount, - message: `Taler top-up ${reservePub}`, + await wallet.client.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: resp.transactionId, + txState: { + major: TransactionMajorState.Pending, + minor: TransactionMinorState.ExchangeWaitReserve, + }, }); - console.log("Created reserve", reservePub); - console.log("Payto URI", completePaytoUri); + const txDet = await wallet.client.call( + WalletApiOperation.GetTransactionById, + { + transactionId: resp.transactionId, + }, + ); + if (txDet.type !== TransactionType.Withdrawal) { + throw Error("assertion failed"); + } + if (txDet.withdrawalDetails.type !== WithdrawalType.ManualTransfer) { + throw Error("assertion failed"); + } + console.log("transfer accounts:"); + console.log(j2s(txDet.withdrawalDetails.exchangeCreditAccountDetails)); }); });