diff options
Diffstat (limited to 'src/operations')
-rw-r--r-- | src/operations/reserves.ts | 31 | ||||
-rw-r--r-- | src/operations/transactions.ts | 110 | ||||
-rw-r--r-- | src/operations/withdraw.ts | 4 |
3 files changed, 98 insertions, 47 deletions
diff --git a/src/operations/reserves.ts b/src/operations/reserves.ts index 2761dfaf9..ff20ce9ba 100644 --- a/src/operations/reserves.ts +++ b/src/operations/reserves.ts @@ -53,7 +53,6 @@ import { processWithdrawGroup, getBankWithdrawalInfo, denomSelectionInfoToState, - getWithdrawDenomList, } from "./withdraw"; import { guardOperationException, @@ -106,22 +105,25 @@ export async function createReserve( let bankInfo: ReserveBankInfo | undefined; if (req.bankWithdrawStatusUrl) { - const denomSelInfo = await selectWithdrawalDenoms( - ws, - canonExchange, - req.amount, - ); - const denomSel = denomSelectionInfoToState(denomSelInfo); bankInfo = { statusUrl: req.bankWithdrawStatusUrl, - amount: req.amount, - bankWithdrawalGroupId: encodeCrock(getRandomBytes(32)), - withdrawalStarted: false, - denomSel, }; } + const initialWithdrawalGroupId = encodeCrock(getRandomBytes(32)); + + const denomSelInfo = await selectWithdrawalDenoms( + ws, + canonExchange, + req.amount, + ); + const initialDenomSel = denomSelectionInfoToState(denomSelInfo); + const reserveRecord: ReserveRecord = { + instructedAmount: req.amount, + initialWithdrawalGroupId, + initialDenomSel, + initialWithdrawalStarted: false, timestampCreated: now, exchangeBaseUrl: canonExchange, reservePriv: keypair.priv, @@ -750,10 +752,9 @@ async function depleteReserve( let withdrawalGroupId: string; - const bankInfo = newReserve.bankInfo; - if (bankInfo && !bankInfo.withdrawalStarted) { - withdrawalGroupId = bankInfo.bankWithdrawalGroupId; - bankInfo.withdrawalStarted = true; + if (!newReserve.initialWithdrawalStarted) { + withdrawalGroupId = newReserve.initialWithdrawalGroupId; + newReserve.initialWithdrawalStarted = true; } else { withdrawalGroupId = encodeCrock(randomBytes(32)); } diff --git a/src/operations/transactions.ts b/src/operations/transactions.ts index 9a3d48bb3..f2845cb18 100644 --- a/src/operations/transactions.ts +++ b/src/operations/transactions.ts @@ -32,7 +32,10 @@ import { Transaction, TransactionType, PaymentStatus, + WithdrawalType, + WithdrawalDetails, } from "../types/transactions"; +import { WithdrawalDetailsResponse } from "../types/walletTypes"; /** * Create an event ID from the type and the primary key for the event. @@ -156,6 +159,7 @@ export async function getTransactions( Stores.reserveUpdatedEvents, Stores.recoupGroups, ], + // Report withdrawals that are currently in progress. async (tx) => { tx.iter(Stores.withdrawalGroups).forEachAsync(async (wsr) => { if ( @@ -171,34 +175,62 @@ export async function getTransactions( return; } - let amountRaw: AmountJson | undefined = undefined; - - if (wsr.source.type === WithdrawalSourceType.Reserve) { - const r = await tx.get(Stores.reserves, wsr.source.reservePub); - if (r?.bankInfo?.amount) { - amountRaw = r.bankInfo.amount; + switch (wsr.source.type) { + case WithdrawalSourceType.Reserve: { + const r = await tx.get(Stores.reserves, wsr.source.reservePub); + if (!r) { + break; + } + let amountRaw: AmountJson | undefined = undefined; + if (wsr.withdrawalGroupId === r.initialWithdrawalGroupId) { + amountRaw = r.instructedAmount; + } else { + amountRaw = wsr.denomsSel.totalWithdrawCost; + } + let withdrawalDetails: WithdrawalDetails; + if (r.bankInfo) { + withdrawalDetails = { + type: WithdrawalType.TalerBankIntegrationApi, + confirmed: true, + bankConfirmationUrl: r.bankInfo.confirmUrl, + }; + } else { + const exchange = await tx.get(Stores.exchanges, r.exchangeBaseUrl); + if (!exchange) { + // FIXME: report somehow + break; + } + withdrawalDetails = { + type: WithdrawalType.ManualTransfer, + reservePublicKey: r.reservePub, + exchangePaytoUris: exchange.wireInfo?.accounts.map((x) => x.payto_uri) ?? [], + }; + } + transactions.push({ + type: TransactionType.Withdrawal, + amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue), + amountRaw: Amounts.stringify(amountRaw), + withdrawalDetails, + exchangeBaseUrl: wsr.exchangeBaseUrl, + pending: !wsr.timestampFinish, + timestamp: wsr.timestampStart, + transactionId: makeEventId( + TransactionType.Withdrawal, + wsr.withdrawalGroupId, + ), + }); } + break; + default: + // Tips are reported via their own event + break; } - if (!amountRaw) { - amountRaw = wsr.denomsSel.totalWithdrawCost; - } - - transactions.push({ - type: TransactionType.Withdrawal, - amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue), - amountRaw: Amounts.stringify(amountRaw), - confirmed: true, - exchangeBaseUrl: wsr.exchangeBaseUrl, - pending: !wsr.timestampFinish, - timestamp: wsr.timestampStart, - transactionId: makeEventId( - TransactionType.Withdrawal, - wsr.withdrawalGroupId, - ), - }); }); - tx.iter(Stores.reserves).forEach((r) => { + // Report pending withdrawals based on reserves that + // were created, but where the actual withdrawal group has + // not started yet. + tx.iter(Stores.reserves).forEachAsync(async (r) => { if (shouldSkipCurrency(transactionsRequest, r.currency)) { return; } @@ -213,23 +245,41 @@ export async function getTransactions( default: return; } - if (!r.bankInfo) { + if (r.initialWithdrawalStarted) { return; } + let withdrawalDetails: WithdrawalDetails; + if (r.bankInfo) { + withdrawalDetails = { + type: WithdrawalType.TalerBankIntegrationApi, + confirmed: false, + bankConfirmationUrl: r.bankInfo.confirmUrl, + } + } else { + const exchange = await tx.get(Stores.exchanges, r.exchangeBaseUrl); + if (!exchange) { + // FIXME: report somehow + return; + } + withdrawalDetails = { + type: WithdrawalType.ManualTransfer, + reservePublicKey: r.reservePub, + exchangePaytoUris: exchange.wireInfo?.accounts.map((x) => x.payto_uri) ?? [], + }; + } transactions.push({ type: TransactionType.Withdrawal, - confirmed: false, - amountRaw: Amounts.stringify(r.bankInfo.amount), + amountRaw: Amounts.stringify(r.instructedAmount), amountEffective: Amounts.stringify( - r.bankInfo.denomSel.totalCoinValue, + r.initialDenomSel.totalCoinValue, ), exchangeBaseUrl: r.exchangeBaseUrl, pending: true, timestamp: r.timestampCreated, - bankConfirmationUrl: r.bankInfo.confirmUrl, + withdrawalDetails: withdrawalDetails, transactionId: makeEventId( TransactionType.Withdrawal, - r.bankInfo.bankWithdrawalGroupId, + r.initialWithdrawalGroupId, ), }); }); diff --git a/src/operations/withdraw.ts b/src/operations/withdraw.ts index 284743415..fd850f140 100644 --- a/src/operations/withdraw.ts +++ b/src/operations/withdraw.ts @@ -32,7 +32,7 @@ import { import { BankWithdrawDetails, ExchangeWithdrawDetails, - WithdrawDetails, + WithdrawalDetailsResponse, OperationError, } from "../types/walletTypes"; import { @@ -708,7 +708,7 @@ export async function getWithdrawDetailsForUri( ws: InternalWalletState, talerWithdrawUri: string, maybeSelectedExchange?: string, -): Promise<WithdrawDetails> { +): Promise<WithdrawalDetailsResponse> { const info = await getBankWithdrawalInfo(ws, talerWithdrawUri); let rci: ExchangeWithdrawDetails | undefined = undefined; if (maybeSelectedExchange) { |