summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/util/coinSelection.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/util/coinSelection.test.ts')
-rw-r--r--packages/taler-wallet-core/src/util/coinSelection.test.ts742
1 files changed, 0 insertions, 742 deletions
diff --git a/packages/taler-wallet-core/src/util/coinSelection.test.ts b/packages/taler-wallet-core/src/util/coinSelection.test.ts
index fddd217ea..b907eb160 100644
--- a/packages/taler-wallet-core/src/util/coinSelection.test.ts
+++ b/packages/taler-wallet-core/src/util/coinSelection.test.ts
@@ -22,746 +22,4 @@ import {
TransactionAmountMode,
} from "@gnu-taler/taler-util";
import test, { ExecutionContext } from "ava";
-import {
- CoinInfo,
- convertDepositAmountForAvailableCoins,
- convertWithdrawalAmountFromAvailableCoins,
- getMaxDepositAmountForAvailableCoins,
-} from "./coinSelection.js";
-
-function makeCurrencyHelper(currency: string) {
- return (sx: TemplateStringsArray, ...vx: any[]) => {
- const s = String.raw({ raw: sx }, ...vx);
- return Amounts.parseOrThrow(`${currency}:${s}`);
- };
-}
-
-const kudos = makeCurrencyHelper("kudos");
-
-function defaultFeeConfig(value: AmountJson, totalAvailable: number): CoinInfo {
- return {
- id: Amounts.stringify(value),
- denomDeposit: kudos`0.01`,
- denomRefresh: kudos`0.01`,
- denomWithdraw: kudos`0.01`,
- exchangeBaseUrl: "1",
- duration: Duration.getForever(),
- exchangePurse: undefined,
- exchangeWire: undefined,
- maxAge: AgeRestriction.AGE_UNRESTRICTED,
- totalAvailable,
- value,
- };
-}
-type Coin = [AmountJson, number];
-
-/**
- * Making a deposit with effective amount
- *
- */
-
-test("deposit effective 2", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`2`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "2");
- t.is(Amounts.stringifyValue(result.raw), "1.99");
-});
-
-test("deposit effective 10", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`10`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "10");
- t.is(Amounts.stringifyValue(result.raw), "9.98");
-});
-
-test("deposit effective 24", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`24`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "24");
- t.is(Amounts.stringifyValue(result.raw), "23.94");
-});
-
-test("deposit effective 40", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`40`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "35");
- t.is(Amounts.stringifyValue(result.raw), "34.9");
-});
-
-test("deposit with wire fee effective 2", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {
- one: {
- wireFee: kudos`0.1`,
- purseFee: kudos`0.00`,
- creditDeadline: AbsoluteTime.never(),
- debitDeadline: AbsoluteTime.never(),
- },
- },
- },
- kudos`2`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "2");
- t.is(Amounts.stringifyValue(result.raw), "1.89");
-});
-
-/**
- * Making a deposit with raw amount, using the result from effective
- *
- */
-
-test("deposit raw 1.99 (effective 2)", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`1.99`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "2");
- t.is(Amounts.stringifyValue(result.raw), "1.99");
-});
-
-test("deposit raw 9.98 (effective 10)", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`9.98`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "10");
- t.is(Amounts.stringifyValue(result.raw), "9.98");
-});
-
-test("deposit raw 23.94 (effective 24)", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`23.94`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "24");
- t.is(Amounts.stringifyValue(result.raw), "23.94");
-});
-
-test("deposit raw 34.9 (effective 40)", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`34.9`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "35");
- t.is(Amounts.stringifyValue(result.raw), "34.9");
-});
-
-test("deposit with wire fee raw 2", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {
- one: {
- wireFee: kudos`0.1`,
- purseFee: kudos`0.00`,
- creditDeadline: AbsoluteTime.never(),
- debitDeadline: AbsoluteTime.never(),
- },
- },
- },
- kudos`2`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "2");
- t.is(Amounts.stringifyValue(result.raw), "1.89");
-});
-
-/**
- * Calculating the max amount possible to deposit
- *
- */
-
-test("deposit max 35", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = getMaxDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {
- "2": {
- wireFee: kudos`0.00`,
- purseFee: kudos`0.00`,
- creditDeadline: AbsoluteTime.never(),
- debitDeadline: AbsoluteTime.never(),
- },
- },
- },
- "KUDOS",
- );
- t.is(Amounts.stringifyValue(result.raw), "34.9");
- t.is(Amounts.stringifyValue(result.effective), "35");
-});
-
-test("deposit max 35 with wirefee", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = getMaxDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {
- "2": {
- wireFee: kudos`1`,
- purseFee: kudos`0.00`,
- creditDeadline: AbsoluteTime.never(),
- debitDeadline: AbsoluteTime.never(),
- },
- },
- },
- "KUDOS",
- );
- t.is(Amounts.stringifyValue(result.raw), "33.9");
- t.is(Amounts.stringifyValue(result.effective), "35");
-});
-
-test("deposit max repeated denom", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 1],
- [kudos`2`, 1],
- [kudos`5`, 1],
- ];
- const result = getMaxDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {
- "2": {
- wireFee: kudos`0.00`,
- purseFee: kudos`0.00`,
- creditDeadline: AbsoluteTime.never(),
- debitDeadline: AbsoluteTime.never(),
- },
- },
- },
- "KUDOS",
- );
- t.is(Amounts.stringifyValue(result.raw), "8.97");
- t.is(Amounts.stringifyValue(result.effective), "9");
-});
-
-/**
- * Making a withdrawal with effective amount
- *
- */
-
-test("withdraw effective 2", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`2`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "2");
- t.is(Amounts.stringifyValue(result.raw), "2.01");
-});
-
-test("withdraw effective 10", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`10`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "10");
- t.is(Amounts.stringifyValue(result.raw), "10.02");
-});
-
-test("withdraw effective 24", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`24`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "24");
- t.is(Amounts.stringifyValue(result.raw), "24.06");
-});
-
-test("withdraw effective 40", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`40`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "40");
- t.is(Amounts.stringifyValue(result.raw), "40.08");
-});
-
-/**
- * Making a deposit with raw amount, using the result from effective
- *
- */
-
-test("withdraw raw 2.01 (effective 2)", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`2.01`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "2");
- t.is(Amounts.stringifyValue(result.raw), "2.01");
-});
-
-test("withdraw raw 10.02 (effective 10)", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`10.02`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "10");
- t.is(Amounts.stringifyValue(result.raw), "10.02");
-});
-
-test("withdraw raw 24.06 (effective 24)", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`24.06`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "24");
- t.is(Amounts.stringifyValue(result.raw), "24.06");
-});
-
-test("withdraw raw 40.08 (effective 40)", (t) => {
- const coinList: Coin[] = [
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`40.08`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "40");
- t.is(Amounts.stringifyValue(result.raw), "40.08");
-});
-
-test("withdraw raw 25", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 0],
- [kudos`1`, 0],
- [kudos`2`, 0],
- [kudos`5`, 0],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`25`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "24.8");
- t.is(Amounts.stringifyValue(result.raw), "24.94");
-});
-
-test("withdraw effective 24.8 (raw 25)", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 0],
- [kudos`1`, 0],
- [kudos`2`, 0],
- [kudos`5`, 0],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`24.8`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "24.8");
- t.is(Amounts.stringifyValue(result.raw), "24.94");
-});
-
-/**
- * Making a deposit with refresh
- *
- */
-
-test("deposit with refresh: effective 3", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 0],
- [kudos`1`, 0],
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`3`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "3.1");
- t.is(Amounts.stringifyValue(result.raw), "2.98");
- expectDefined(t, result.refresh);
- //FEES
- //deposit 2 x 0.01
- //refresh 1 x 0.01
- //withdraw 9 x 0.01
- //-----------------
- //op 0.12
-
- //coins sent 2 x 2.0
- //coins recv 9 x 0.1
- //-------------------
- //effective 3.10
- //raw 2.98
- t.is(Amounts.stringifyValue(result.refresh.selected.id), "2");
- t.deepEqual(asCoinList(result.refresh.coins), [[kudos`0.1`, 9]]);
-});
-
-test("deposit with refresh: raw 2.98 (effective 3)", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 0],
- [kudos`1`, 0],
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`2.98`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "3.2");
- t.is(Amounts.stringifyValue(result.raw), "3.09");
- expectDefined(t, result.refresh);
- //FEES
- //deposit 1 x 0.01
- //refresh 1 x 0.01
- //withdraw 8 x 0.01
- //-----------------
- //op 0.10
-
- //coins sent 1 x 2.0
- //coins recv 8 x 0.1
- //-------------------
- //effective 3.20
- //raw 3.09
- t.is(Amounts.stringifyValue(result.refresh.selected.id), "2");
- t.deepEqual(asCoinList(result.refresh.coins), [[kudos`0.1`, 8]]);
-});
-
-test("deposit with refresh: effective 3.2 (raw 2.98)", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 0],
- [kudos`1`, 0],
- [kudos`2`, 5],
- [kudos`5`, 5],
- ];
- const result = convertDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`3.2`,
- TransactionAmountMode.Effective,
- );
- t.is(Amounts.stringifyValue(result.effective), "3.3");
- t.is(Amounts.stringifyValue(result.raw), "3.2");
- expectDefined(t, result.refresh);
- //FEES
- //deposit 2 x 0.01
- //refresh 1 x 0.01
- //withdraw 7 x 0.01
- //-----------------
- //op 0.10
-
- //coins sent 2 x 2.0
- //coins recv 7 x 0.1
- //-------------------
- //effective 3.30
- //raw 3.20
- t.is(Amounts.stringifyValue(result.refresh.selected.id), "2");
- t.deepEqual(asCoinList(result.refresh.coins), [[kudos`0.1`, 7]]);
-});
-
-function expectDefined<T>(
- t: ExecutionContext,
- v: T | undefined,
-): asserts v is T {
- t.assert(v !== undefined);
-}
-
-function asCoinList(v: { info: CoinInfo; size: number }[]): any {
- return v.map((c) => {
- return [c.info.value, c.size];
- });
-}
-
-/**
- * regression tests
- */
-
-test("demo: withdraw raw 25", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 0],
- [kudos`1`, 0],
- [kudos`2`, 0],
- [kudos`5`, 0],
- [kudos`10`, 0],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`25`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "24.8");
- t.is(Amounts.stringifyValue(result.raw), "24.92");
- // coins received
- // 8 x 0.1
- // 2 x 0.2
- // 2 x 10.0
- // total effective 24.8
- // fee 12 x 0.01 = 0.12
- // total raw 24.92
- // left in reserve 25 - 24.92 == 0.08
-
- //current wallet impl: hides the left in reserve fee
- //shows fee = 0.2
-});
-
-test("demo: deposit max after withdraw raw 25", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 8],
- [kudos`1`, 0],
- [kudos`2`, 2],
- [kudos`5`, 0],
- [kudos`10`, 2],
- ];
- const result = getMaxDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {
- one: {
- wireFee: kudos`0.01`,
- purseFee: kudos`0.00`,
- creditDeadline: AbsoluteTime.never(),
- debitDeadline: AbsoluteTime.never(),
- },
- },
- },
- "KUDOS",
- );
- t.is(Amounts.stringifyValue(result.effective), "24.8");
- t.is(Amounts.stringifyValue(result.raw), "24.67");
-
- // 8 x 0.1
- // 2 x 0.2
- // 2 x 10.0
- // total effective 24.8
- // deposit fee 12 x 0.01 = 0.12
- // wire fee 0.01
- // total raw: 24.8 - 0.13 = 24.67
-
- // current wallet impl fee 0.14
-});
-
-test("demo: withdraw raw 13", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 0],
- [kudos`1`, 0],
- [kudos`2`, 0],
- [kudos`5`, 0],
- [kudos`10`, 0],
- ];
- const result = convertWithdrawalAmountFromAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- },
- kudos`13`,
- TransactionAmountMode.Raw,
- );
- t.is(Amounts.stringifyValue(result.effective), "12.8");
- t.is(Amounts.stringifyValue(result.raw), "12.9");
- // coins received
- // 8 x 0.1
- // 1 x 0.2
- // 1 x 10.0
- // total effective 12.8
- // fee 10 x 0.01 = 0.10
- // total raw 12.9
- // left in reserve 13 - 12.9 == 0.1
-
- //current wallet impl: hides the left in reserve fee
- //shows fee = 0.2
-});
-
-test("demo: deposit max after withdraw raw 13", (t) => {
- const coinList: Coin[] = [
- [kudos`0.1`, 8],
- [kudos`1`, 0],
- [kudos`2`, 1],
- [kudos`5`, 0],
- [kudos`10`, 1],
- ];
- const result = getMaxDepositAmountForAvailableCoins(
- {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {
- one: {
- wireFee: kudos`0.01`,
- purseFee: kudos`0.00`,
- creditDeadline: AbsoluteTime.never(),
- debitDeadline: AbsoluteTime.never(),
- },
- },
- },
- "KUDOS",
- );
- t.is(Amounts.stringifyValue(result.effective), "12.8");
- t.is(Amounts.stringifyValue(result.raw), "12.69");
-
- // 8 x 0.1
- // 1 x 0.2
- // 1 x 10.0
- // total effective 12.8
- // deposit fee 10 x 0.01 = 0.10
- // wire fee 0.01
- // total raw: 12.8 - 0.11 = 12.69
- // current wallet impl fee 0.14
-});