diff options
Diffstat (limited to 'packages/taler-wallet-core/src/deposits.ts')
-rw-r--r-- | packages/taler-wallet-core/src/deposits.ts | 107 |
1 files changed, 59 insertions, 48 deletions
diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts index a8612744f..05a5d780a 100644 --- a/packages/taler-wallet-core/src/deposits.ts +++ b/packages/taler-wallet-core/src/deposits.ts @@ -39,10 +39,10 @@ import { Logger, MerchantContractTerms, NotificationType, - PayCoinSelection, PrepareDepositRequest, PrepareDepositResponse, RefreshReason, + SelectedProspectiveCoin, TalerError, TalerErrorCode, TalerPreciseTimestamp, @@ -1155,11 +1155,8 @@ async function trackDeposit( /** * Check if creating a deposit group is possible and calculate * the associated fees. - * - * FIXME: This should be renamed to checkDepositGroup, - * as it doesn't prepare anything */ -export async function prepareDepositGroup( +export async function checkDepositGroup( wex: WalletExecutionContext, req: PrepareDepositRequest, ): Promise<PrepareDepositResponse> { @@ -1168,6 +1165,7 @@ export async function prepareDepositGroup( throw Error("invalid payto URI"); } const amount = Amounts.parseOrThrow(req.amount); + const currency = Amounts.currencyOf(amount); const exchangeInfos: ExchangeHandle[] = []; @@ -1231,28 +1229,39 @@ export async function prepareDepositGroup( prevPayCoins: [], }); - if (payCoinSel.type !== "success") { - throw TalerError.fromDetail( - TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE, - { - insufficientBalanceDetails: payCoinSel.insufficientBalanceDetails, - }, - ); + let selCoins: SelectedProspectiveCoin[] | undefined = undefined; + + switch (payCoinSel.type) { + case "failure": + throw TalerError.fromDetail( + TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE, + { + insufficientBalanceDetails: payCoinSel.insufficientBalanceDetails, + }, + ); + case "prospective": + selCoins = payCoinSel.result.prospectiveCoins; + break; + case "success": + selCoins = payCoinSel.coinSel.coins; + break; + default: + assertUnreachable(payCoinSel); } - const totalDepositCost = await getTotalPaymentCost(wex, payCoinSel.coinSel); + const totalDepositCost = await getTotalPaymentCost(wex, currency, selCoins); const effectiveDepositAmount = await getCounterpartyEffectiveDepositAmount( wex, p.targetType, - payCoinSel.coinSel, + selCoins, ); const fees = await getTotalFeesForDepositAmount( wex, p.targetType, amount, - payCoinSel.coinSel, + selCoins, ); return { @@ -1280,6 +1289,7 @@ export async function createDepositGroup( } const amount = Amounts.parseOrThrow(req.amount); + const currency = amount.currency; const exchangeInfos: { url: string; master_pub: string }[] = []; @@ -1350,16 +1360,28 @@ export async function createDepositGroup( prevPayCoins: [], }); - if (payCoinSel.type !== "success") { - throw TalerError.fromDetail( - TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE, - { - insufficientBalanceDetails: payCoinSel.insufficientBalanceDetails, - }, - ); + switch (payCoinSel.type) { + case "success": + break; + case "failure": + throw TalerError.fromDetail( + TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE, + { + insufficientBalanceDetails: payCoinSel.insufficientBalanceDetails, + }, + ); + case "prospective": + // FIXME: Here we need to create the deposit group without a full coin selection! + throw Error("insufficient balance (pending refresh)"); + default: + assertUnreachable(payCoinSel); } - const totalDepositCost = await getTotalPaymentCost(wex, payCoinSel.coinSel); + const totalDepositCost = await getTotalPaymentCost( + wex, + currency, + payCoinSel.coinSel.coins, + ); let depositGroupId: string; if (req.transactionId) { @@ -1400,7 +1422,7 @@ export async function createDepositGroup( await getCounterpartyEffectiveDepositAmount( wex, p.targetType, - payCoinSel.coinSel, + payCoinSel.coinSel.coins, ); const depositGroup: DepositGroupRecord = { @@ -1500,7 +1522,7 @@ export async function createDepositGroup( export async function getCounterpartyEffectiveDepositAmount( wex: WalletExecutionContext, wireType: string, - pcs: PayCoinSelection, + pcs: SelectedProspectiveCoin[], ): Promise<AmountJson> { const amt: AmountJson[] = []; const fees: AmountJson[] = []; @@ -1509,23 +1531,19 @@ export async function getCounterpartyEffectiveDepositAmount( await wex.db.runReadOnlyTx( ["coins", "denominations", "exchangeDetails", "exchanges"], async (tx) => { - for (let i = 0; i < pcs.coins.length; i++) { - const coin = await tx.coins.get(pcs.coins[i].coinPub); - if (!coin) { - throw Error("can't calculate deposit amount, coin not found"); - } + for (let i = 0; i < pcs.length; i++) { const denom = await getDenomInfo( wex, tx, - coin.exchangeBaseUrl, - coin.denomPubHash, + pcs[i].exchangeBaseUrl, + pcs[i].denomPubHash, ); if (!denom) { throw Error("can't find denomination to calculate deposit amount"); } - amt.push(Amounts.parseOrThrow(pcs.coins[i].contribution)); + amt.push(Amounts.parseOrThrow(pcs[i].contribution)); fees.push(Amounts.parseOrThrow(denom.feeDeposit)); - exchangeSet.add(coin.exchangeBaseUrl); + exchangeSet.add(pcs[i].exchangeBaseUrl); } for (const exchangeUrl of exchangeSet.values()) { @@ -1564,7 +1582,7 @@ async function getTotalFeesForDepositAmount( wex: WalletExecutionContext, wireType: string, total: AmountJson, - pcs: PayCoinSelection, + pcs: SelectedProspectiveCoin[], ): Promise<DepositGroupFees> { const wireFee: AmountJson[] = []; const coinFee: AmountJson[] = []; @@ -1575,33 +1593,26 @@ async function getTotalFeesForDepositAmount( await wex.db.runReadOnlyTx( ["coins", "denominations", "exchanges", "exchangeDetails"], async (tx) => { - for (let i = 0; i < pcs.coins.length; i++) { - const coin = await tx.coins.get(pcs.coins[i].coinPub); - if (!coin) { - throw Error("can't calculate deposit amount, coin not found"); - } + for (let i = 0; i < pcs.length; i++) { const denom = await getDenomInfo( wex, tx, - coin.exchangeBaseUrl, - coin.denomPubHash, + pcs[i].exchangeBaseUrl, + pcs[i].denomPubHash, ); if (!denom) { throw Error("can't find denomination to calculate deposit amount"); } coinFee.push(Amounts.parseOrThrow(denom.feeDeposit)); - exchangeSet.add(coin.exchangeBaseUrl); + exchangeSet.add(pcs[i].exchangeBaseUrl); const allDenoms = await getCandidateWithdrawalDenomsTx( wex, tx, - coin.exchangeBaseUrl, + pcs[i].exchangeBaseUrl, currency, ); - const amountLeft = Amounts.sub( - denom.value, - pcs.coins[i].contribution, - ).amount; + const amountLeft = Amounts.sub(denom.value, pcs[i].contribution).amount; const refreshCost = getTotalRefreshCost( allDenoms, denom, |