diff options
author | Sebastian <sebasjm@gmail.com> | 2023-03-31 12:27:05 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-03-31 12:27:17 -0300 |
commit | b0cc65e17f2348f46ae1c9b88b69abae11266899 (patch) | |
tree | 41a8b4a14c4fe99eea8e285d43b01f972ea7226b /packages/taler-wallet-core/src/operations/withdraw.ts | |
parent | 7ebcb30b9f9a573a04dc19a99df739aefb677c15 (diff) | |
download | wallet-core-b0cc65e17f2348f46ae1c9b88b69abae11266899.tar.xz |
move coin selection function to coinSelection.ts and added a test placeholder, and some fixes:
* selectCandidates was not save wire fee
* selectCandidates show check wire fee time range
Diffstat (limited to 'packages/taler-wallet-core/src/operations/withdraw.ts')
-rw-r--r-- | packages/taler-wallet-core/src/operations/withdraw.ts | 162 |
1 files changed, 5 insertions, 157 deletions
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 2c91d4184..643737e93 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -93,7 +93,6 @@ import { runLongpollAsync, runOperationWithErrorReporting, } from "../operations/common.js"; -import { walletCoreDebugFlags } from "../util/debugFlags.js"; import { HttpRequestLibrary, HttpResponse, @@ -123,6 +122,11 @@ import { getExchangeTrust, updateExchangeFromUrl, } from "./exchanges.js"; +import { + selectForcedWithdrawalDenominations, + selectWithdrawalDenominations, +} from "../util/coinSelection.js"; +import { isWithdrawableDenom } from "../index.js"; /** * Logger for this file. @@ -130,162 +134,6 @@ import { const logger = new Logger("operations/withdraw.ts"); /** - * Check if a denom is withdrawable based on the expiration time, - * revocation and offered state. - */ -export function isWithdrawableDenom(d: DenominationRecord): boolean { - const now = AbsoluteTime.now(); - const start = AbsoluteTime.fromTimestamp(d.stampStart); - const withdrawExpire = AbsoluteTime.fromTimestamp(d.stampExpireWithdraw); - const started = AbsoluteTime.cmp(now, start) >= 0; - let lastPossibleWithdraw: AbsoluteTime; - if (walletCoreDebugFlags.denomselAllowLate) { - lastPossibleWithdraw = start; - } else { - lastPossibleWithdraw = AbsoluteTime.subtractDuraction( - withdrawExpire, - durationFromSpec({ minutes: 5 }), - ); - } - const remaining = Duration.getRemaining(lastPossibleWithdraw, now); - const stillOkay = remaining.d_ms !== 0; - return started && stillOkay && !d.isRevoked && d.isOffered; -} - -/** - * Get a list of denominations (with repetitions possible) - * whose total value is as close as possible to the available - * amount, but never larger. - */ -export function selectWithdrawalDenominations( - amountAvailable: AmountJson, - denoms: DenominationRecord[], -): DenomSelectionState { - let remaining = Amounts.copy(amountAvailable); - - const selectedDenoms: { - count: number; - denomPubHash: string; - }[] = []; - - let totalCoinValue = Amounts.zeroOfCurrency(amountAvailable.currency); - let totalWithdrawCost = Amounts.zeroOfCurrency(amountAvailable.currency); - - denoms = denoms.filter(isWithdrawableDenom); - denoms.sort((d1, d2) => - Amounts.cmp( - DenominationRecord.getValue(d2), - DenominationRecord.getValue(d1), - ), - ); - - for (const d of denoms) { - let count = 0; - const cost = Amounts.add( - DenominationRecord.getValue(d), - d.fees.feeWithdraw, - ).amount; - for (;;) { - if (Amounts.cmp(remaining, cost) < 0) { - break; - } - remaining = Amounts.sub(remaining, cost).amount; - count++; - } - if (count > 0) { - totalCoinValue = Amounts.add( - totalCoinValue, - Amounts.mult(DenominationRecord.getValue(d), count).amount, - ).amount; - totalWithdrawCost = Amounts.add( - totalWithdrawCost, - Amounts.mult(cost, count).amount, - ).amount; - selectedDenoms.push({ - count, - denomPubHash: d.denomPubHash, - }); - } - - if (Amounts.isZero(remaining)) { - break; - } - } - - if (logger.shouldLogTrace()) { - logger.trace( - `selected withdrawal denoms for ${Amounts.stringify(totalCoinValue)}`, - ); - for (const sd of selectedDenoms) { - logger.trace(`denom_pub_hash=${sd.denomPubHash}, count=${sd.count}`); - } - logger.trace("(end of withdrawal denom list)"); - } - - return { - selectedDenoms, - totalCoinValue: Amounts.stringify(totalCoinValue), - totalWithdrawCost: Amounts.stringify(totalWithdrawCost), - }; -} - -export function selectForcedWithdrawalDenominations( - amountAvailable: AmountJson, - denoms: DenominationRecord[], - forcedDenomSel: ForcedDenomSel, -): DenomSelectionState { - const selectedDenoms: { - count: number; - denomPubHash: string; - }[] = []; - - let totalCoinValue = Amounts.zeroOfCurrency(amountAvailable.currency); - let totalWithdrawCost = Amounts.zeroOfCurrency(amountAvailable.currency); - - denoms = denoms.filter(isWithdrawableDenom); - denoms.sort((d1, d2) => - Amounts.cmp( - DenominationRecord.getValue(d2), - DenominationRecord.getValue(d1), - ), - ); - - for (const fds of forcedDenomSel.denoms) { - const count = fds.count; - const denom = denoms.find((x) => { - return Amounts.cmp(DenominationRecord.getValue(x), fds.value) == 0; - }); - if (!denom) { - throw Error( - `unable to find denom for forced selection (value ${fds.value})`, - ); - } - const cost = Amounts.add( - DenominationRecord.getValue(denom), - denom.fees.feeWithdraw, - ).amount; - totalCoinValue = Amounts.add( - totalCoinValue, - Amounts.mult(DenominationRecord.getValue(denom), count).amount, - ).amount; - totalWithdrawCost = Amounts.add( - totalWithdrawCost, - Amounts.mult(cost, count).amount, - ).amount; - selectedDenoms.push({ - count, - denomPubHash: denom.denomPubHash, - }); - } - - return { - selectedDenoms, - totalCoinValue: Amounts.stringify(totalCoinValue), - totalWithdrawCost: Amounts.stringify(totalWithdrawCost), - }; -} - -/** * Get information about a withdrawal from * a taler://withdraw URI by asking the bank. * |