diff options
author | Florian Dold <florian@dold.me> | 2024-05-23 19:50:59 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-05-23 19:50:59 +0200 |
commit | cdcedf65595393fc186eb2012d3ae6cd55540f59 (patch) | |
tree | 88c4eecce4673c1c2b7b3b6eaadfb4b7f8df0ce8 /packages/taler-wallet-core | |
parent | 527716758f154eb863acb0052f004dd23313f765 (diff) | |
download | wallet-core-cdcedf65595393fc186eb2012d3ae6cd55540f59.tar.xz |
wallet-core: support bank-integrated withdrawal with amount selection by wallet
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r-- | packages/taler-wallet-core/src/db.ts | 1 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/shepherd.ts | 8 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 5 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/withdraw.ts | 58 |
4 files changed, 58 insertions, 14 deletions
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 44c241aed..640d94753 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -1439,6 +1439,7 @@ export interface WgInfoBankIntegrated { * a Taler-integrated bank. */ bankInfo: ReserveBankInfo; + /** * Info about withdrawal accounts, possibly including currency conversion. */ diff --git a/packages/taler-wallet-core/src/shepherd.ts b/packages/taler-wallet-core/src/shepherd.ts index dbdd7aac5..d662bd7ae 100644 --- a/packages/taler-wallet-core/src/shepherd.ts +++ b/packages/taler-wallet-core/src/shepherd.ts @@ -382,7 +382,13 @@ export class TaskSchedulerImpl implements TaskScheduler { }); switch (res.type) { case TaskRunResultType.Error: { - logger.trace(`Shepherd for ${taskId} got error result.`); + if (logger.shouldLogTrace()) { + logger.trace( + `Shepherd for ${taskId} got error result: ${j2s( + res.errorDetail, + )}`, + ); + } const retryRecord = await storePendingTaskError( this.ws, taskId, diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index c17a2b467..3455d451b 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -724,7 +724,9 @@ async function dispatchRequestInternal( const req = codecForInitRequest().decode(payload); if (logger.shouldLogTrace()) { - const initType = wex.ws.initCalled ? "repeat initialization" : "first initialization"; + const initType = wex.ws.initCalled + ? "repeat initialization" + : "first initialization"; logger.trace(`init request (${initType}): ${j2s(req)}`); } @@ -997,6 +999,7 @@ async function dispatchRequestInternal( talerWithdrawUri: req.talerWithdrawUri, forcedDenomSel: req.forcedDenomSel, restrictAge: req.restrictAge, + amount: req.amount, }); } case WalletApiOperation.ConfirmWithdrawal: { diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts index 4a7c7873c..16289b1ef 100644 --- a/packages/taler-wallet-core/src/withdraw.ts +++ b/packages/taler-wallet-core/src/withdraw.ts @@ -857,10 +857,16 @@ export async function getBankWithdrawalInfo( } const { body: status } = resp; + let amount: AmountJson | undefined; + if (status.amount) { + amount = Amounts.parseOrThrow(status.amount); + } + return { operationId: uriResult.withdrawalOperationId, apiBaseUrl: uriResult.bankIntegrationApiBaseUrl, - amount: Amounts.parseOrThrow(status.amount), + currency: config.currency, + amount, confirmTransferUrl: status.confirm_transfer_url, senderWire: status.sender_wire, suggestedExchange: status.suggested_exchange, @@ -2262,7 +2268,7 @@ export async function getWithdrawalDetailsForUri( } } - const currency = Amounts.currencyOf(info.amount); + const currency = info.currency; const listExchangesResp = await listExchanges(wex); const possibleExchanges = listExchangesResp.exchanges.filter((x) => { @@ -2277,7 +2283,8 @@ export async function getWithdrawalDetailsForUri( operationId: info.operationId, confirmTransferUrl: info.confirmTransferUrl, status: info.status, - amount: Amounts.stringify(info.amount), + currency, + amount: info.amount ? Amounts.stringify(info.amount) : undefined, defaultExchangeBaseUrl: info.suggestedExchange, possibleExchanges, }; @@ -2379,6 +2386,7 @@ export function getBankAbortUrl(talerWithdrawUri: string): string { async function registerReserveWithBank( wex: WalletExecutionContext, withdrawalGroupId: string, + isFlexibleAmount: boolean, ): Promise<void> { const withdrawalGroup = await wex.db.runReadOnlyTx( { storeNames: ["withdrawalGroups"] }, @@ -2407,7 +2415,11 @@ async function registerReserveWithBank( const reqBody = { reserve_pub: withdrawalGroup.reservePub, selected_exchange: bankInfo.exchangePaytoUri, - }; + } as any; + if (isFlexibleAmount) { + reqBody.amount = withdrawalGroup.instructedAmount; + } + logger.trace(`isFlexibleAmount: ${isFlexibleAmount}`); logger.info(`registering reserve with bank: ${j2s(reqBody)}`); const httpResp = await wex.http.fetch(bankStatusUrl, { method: "POST", @@ -2516,7 +2528,9 @@ async function processBankRegisterReserve( // FIXME: Put confirm transfer URL in the DB! - await registerReserveWithBank(wex, withdrawalGroupId); + const isFlexibleAmount = status.amount == null; + + await registerReserveWithBank(wex, withdrawalGroupId, isFlexibleAmount); return TaskRunResult.progress(); } @@ -2985,7 +2999,7 @@ export async function confirmWithdrawal( const confirmUrl = withdrawalGroup.wgInfo.bankInfo.confirmUrl; /** - * The only reasong this to be undefined is because it is an old wallet + * The only reason this could be undefined is because it is an old wallet * database before adding the wireType field was added */ let wtypes: string[]; @@ -3025,7 +3039,7 @@ export async function confirmWithdrawal( req.forcedDenomSel, ); - ctx.transition({}, async (rec) => { + await ctx.transition({}, async (rec) => { if (!rec) { return TransitionResult.stay(); } @@ -3060,7 +3074,6 @@ export async function confirmWithdrawal( }); await wex.taskScheduler.resetTaskRetries(ctx.taskId); - wex.taskScheduler.startShepherdTask(ctx.taskId); } /** @@ -3080,6 +3093,7 @@ export async function acceptWithdrawalFromUri( selectedExchange: string; forcedDenomSel?: ForcedDenomSel; restrictAge?: number; + amount?: AmountLike; }, ): Promise<AcceptWithdrawalResponse> { const selectedExchange = req.selectedExchange; @@ -3124,17 +3138,37 @@ export async function acceptWithdrawalFromUri( withdrawInfo.wireTypes, ); + let amount: AmountJson; + if (withdrawInfo.amount == null) { + if (req.amount == null) { + throw Error( + "amount required, as withdrawal operation has flexible amount", + ); + } + amount = Amounts.parseOrThrow(req.amount); + } else { + if ( + req.amount != null && + Amounts.cmp(req.amount, withdrawInfo.amount) != 0 + ) { + throw Error( + "mismatched amount, amount is fixed by bank but client provided different amount", + ); + } + amount = withdrawInfo.amount; + } + const withdrawalAccountList = await fetchWithdrawalAccountInfo( wex, { exchange, - instructedAmount: withdrawInfo.amount, + instructedAmount: amount, }, CancellationToken.CONTINUE, ); const withdrawalGroup = await internalCreateWithdrawalGroup(wex, { - amount: withdrawInfo.amount, + amount, exchangeBaseUrl: req.selectedExchange, wgInfo: { withdrawalType: WithdrawalRecordType.BankIntegrated, @@ -3162,10 +3196,10 @@ export async function acceptWithdrawalFromUri( hintTransactionId: ctx.transactionId, }); - await waitWithdrawalRegistered(wex, ctx); - wex.taskScheduler.startShepherdTask(ctx.taskId); + await waitWithdrawalRegistered(wex, ctx); + return { reservePub: withdrawalGroup.reservePub, confirmTransferUrl: withdrawInfo.confirmTransferUrl, |