aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations/withdraw.ts
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-03-31 12:27:05 -0300
committerSebastian <sebasjm@gmail.com>2023-03-31 12:27:17 -0300
commitb0cc65e17f2348f46ae1c9b88b69abae11266899 (patch)
tree41a8b4a14c4fe99eea8e285d43b01f972ea7226b /packages/taler-wallet-core/src/operations/withdraw.ts
parent7ebcb30b9f9a573a04dc19a99df739aefb677c15 (diff)
downloadwallet-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.ts162
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.
*