aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/util
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-06-16 09:40:45 -0300
committerSebastian <sebasjm@gmail.com>2023-06-16 09:40:45 -0300
commit444c5427f41f8030b117a7d3589219abfa60bd1c (patch)
treef33b276528a0369452f25987522328b46f8f8552 /packages/taler-wallet-core/src/util
parentd97f440f255966c4231c6c4923a3fff9662a58fd (diff)
downloadwallet-core-444c5427f41f8030b117a7d3589219abfa60bd1c.tar.xz
remove some type literal and pretty
Diffstat (limited to 'packages/taler-wallet-core/src/util')
-rw-r--r--packages/taler-wallet-core/src/util/coinSelection.test.ts74
-rw-r--r--packages/taler-wallet-core/src/util/coinSelection.ts84
-rw-r--r--packages/taler-wallet-core/src/util/denominations.ts4
3 files changed, 112 insertions, 50 deletions
diff --git a/packages/taler-wallet-core/src/util/coinSelection.test.ts b/packages/taler-wallet-core/src/util/coinSelection.test.ts
index 7f4164aa9..448982c7f 100644
--- a/packages/taler-wallet-core/src/util/coinSelection.test.ts
+++ b/packages/taler-wallet-core/src/util/coinSelection.test.ts
@@ -15,6 +15,8 @@
*/
import test, { ExecutionContext } from "ava";
import {
+ AmountMode,
+ OperationType,
calculatePlanFormAvailableCoins,
selectCoinForOperation,
} from "./coinSelection.js";
@@ -24,6 +26,7 @@ import {
AmountJson,
Amounts,
Duration,
+ TransactionAmountMode,
TransactionType,
} from "@gnu-taler/taler-util";
@@ -67,10 +70,15 @@ test("get effective 2", (t) => {
[kudos(2), 5],
[kudos(5), 5],
];
- const result = selectCoinForOperation("credit", kudos(2), "net", {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- });
+ const result = selectCoinForOperation(
+ OperationType.Credit,
+ kudos(2),
+ AmountMode.Net,
+ {
+ list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
+ exchanges: {},
+ },
+ );
expect(t, result.coins).deep.equal(["KUDOS:2"]);
t.assert(result.refresh === undefined);
});
@@ -80,10 +88,15 @@ test("get raw 4", (t) => {
[kudos(2), 5],
[kudos(5), 5],
];
- const result = selectCoinForOperation("credit", kudos(4), "gross", {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- });
+ const result = selectCoinForOperation(
+ OperationType.Credit,
+ kudos(4),
+ AmountMode.Gross,
+ {
+ list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
+ exchanges: {},
+ },
+ );
expect(t, result.coins).deep.equal(["KUDOS:2", "KUDOS:2"]);
t.assert(result.refresh === undefined);
@@ -94,10 +107,15 @@ test("send effective 6", (t) => {
[kudos(2), 5],
[kudos(5), 5],
];
- const result = selectCoinForOperation("debit", kudos(6), "gross", {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- });
+ const result = selectCoinForOperation(
+ OperationType.Debit,
+ kudos(6),
+ AmountMode.Gross,
+ {
+ list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
+ exchanges: {},
+ },
+ );
expect(t, result.coins).deep.equal(["KUDOS:5"]);
t.assert(result.refresh?.selected === "KUDOS:2");
@@ -108,10 +126,15 @@ test("send raw 6", (t) => {
[kudos(2), 5],
[kudos(5), 5],
];
- const result = selectCoinForOperation("debit", kudos(6), "gross", {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- });
+ const result = selectCoinForOperation(
+ OperationType.Debit,
+ kudos(6),
+ AmountMode.Gross,
+ {
+ list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
+ exchanges: {},
+ },
+ );
expect(t, result.coins).deep.equal(["KUDOS:5"]);
t.assert(result.refresh?.selected === "KUDOS:2");
@@ -122,10 +145,15 @@ test("send raw 20 (not enough)", (t) => {
[kudos(2), 1],
[kudos(5), 2],
];
- const result = selectCoinForOperation("debit", kudos(20), "gross", {
- list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
- exchanges: {},
- });
+ const result = selectCoinForOperation(
+ OperationType.Debit,
+ kudos(20),
+ AmountMode.Gross,
+ {
+ list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
+ exchanges: {},
+ },
+ );
expect(t, result.coins).deep.equal(["KUDOS:5", "KUDOS:5", "KUDOS:2"]);
t.assert(result.refresh === undefined);
@@ -147,7 +175,7 @@ test("deposit effective 2 ", (t) => {
const result = calculatePlanFormAvailableCoins(
TransactionType.Deposit,
kudos(2),
- "effective",
+ TransactionAmountMode.Effective,
{
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
exchanges: {
@@ -173,7 +201,7 @@ test("deposit raw 2 ", (t) => {
const result = calculatePlanFormAvailableCoins(
TransactionType.Deposit,
kudos(2),
- "raw",
+ TransactionAmountMode.Raw,
{
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
exchanges: {
@@ -199,7 +227,7 @@ test("withdraw raw 21 ", (t) => {
const result = calculatePlanFormAvailableCoins(
TransactionType.Withdrawal,
kudos(21),
- "raw",
+ TransactionAmountMode.Raw,
{
list: coinList.map(([v, t]) => defaultFeeConfig(v, t)),
exchanges: {
diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts
index f6d8abcd4..c5a810c4f 100644
--- a/packages/taler-wallet-core/src/util/coinSelection.ts
+++ b/packages/taler-wallet-core/src/util/coinSelection.ts
@@ -46,6 +46,7 @@ import {
PayCoinSelection,
PayMerchantInsufficientBalanceDetails,
strcmp,
+ TransactionAmountMode,
TransactionType,
} from "@gnu-taler/taler-util";
import {
@@ -818,7 +819,7 @@ function getCoinsFilter(req: GetPlanForOperationRequest): CoinsFilter {
export function calculatePlanFormAvailableCoins(
transactionType: TransactionType,
amount: AmountJson,
- mode: "effective" | "raw",
+ mode: TransactionAmountMode,
availableCoins: AvailableCoins,
) {
const operationType = getOperationType(transactionType);
@@ -828,7 +829,9 @@ export function calculatePlanFormAvailableCoins(
usableCoins = selectCoinForOperation(
operationType,
amount,
- mode === "effective" ? "net" : "gross",
+ mode === TransactionAmountMode.Effective
+ ? AmountMode.Net
+ : AmountMode.Gross,
availableCoins,
);
break;
@@ -839,11 +842,11 @@ export function calculatePlanFormAvailableCoins(
//are from that exchange
const wireFee = Object.values(availableCoins.exchanges)[0].wireFee!;
- if (mode === "effective") {
+ if (mode === TransactionAmountMode.Effective) {
usableCoins = selectCoinForOperation(
operationType,
amount,
- "gross",
+ AmountMode.Gross,
availableCoins,
);
@@ -857,7 +860,7 @@ export function calculatePlanFormAvailableCoins(
usableCoins = selectCoinForOperation(
operationType,
adjustedAmount,
- "net",
+ AmountMode.Net,
availableCoins,
);
@@ -914,6 +917,27 @@ export async function getPlanForOperation(
}
/**
+ * If the operation going to be plan subtracts
+ * or adds amount in the wallet db
+ */
+export enum OperationType {
+ Credit = "credit",
+ Debit = "debit",
+}
+
+/**
+ * How the amount should be interpreted
+ * net = without fee
+ * gross = with fee
+ *
+ * Net value is always lower than gross
+ */
+export enum AmountMode {
+ Net = "net",
+ Gross = "gross",
+}
+
+/**
*
* @param op defined which fee are we taking into consideration: deposits or withdraw
* @param limit the total amount limit of the operation
@@ -922,9 +946,9 @@ export async function getPlanForOperation(
* @returns
*/
export function selectCoinForOperation(
- op: "debit" | "credit",
+ op: OperationType,
limit: AmountJson,
- mode: "net" | "gross",
+ mode: AmountMode,
coins: AvailableCoins,
): SelectedCoins {
const result: SelectedCoins = {
@@ -951,8 +975,11 @@ export function selectCoinForOperation(
iterateDenoms: while (denomIdx < coins.list.length) {
const denom = coins.list[denomIdx];
let total =
- op === "credit" ? Number.MAX_SAFE_INTEGER : denom.totalAvailable ?? 0;
- const opFee = op === "credit" ? denom.denomWithdraw : denom.denomDeposit;
+ op === OperationType.Credit
+ ? Number.MAX_SAFE_INTEGER
+ : denom.totalAvailable ?? 0;
+ const opFee =
+ op === OperationType.Credit ? denom.denomWithdraw : denom.denomDeposit;
const contribution = Amounts.sub(denom.value, opFee).amount;
if (Amounts.isZero(contribution)) {
@@ -969,7 +996,7 @@ export function selectCoinForOperation(
contribution,
).amount;
- const progress = mode === "gross" ? nextValue : nextContribution;
+ const progress = mode === AmountMode.Gross ? nextValue : nextContribution;
if (Amounts.cmp(progress, limit) === 1) {
//the current coin is more than we need, try next denom
@@ -1008,14 +1035,15 @@ export function selectCoinForOperation(
// we made it
return result;
}
- if (op === "credit") {
+ if (op === OperationType.Credit) {
//doing withdraw there is no way to cover the gap
return result;
}
//tried all the coins but there is a gap
//doing deposit we can try refreshing coins
- const total = mode === "gross" ? result.totalValue : result.totalContribution;
+ const total =
+ mode === AmountMode.Gross ? result.totalValue : result.totalContribution;
const gap = Amounts.sub(limit, total).amount;
//about recursive calls
@@ -1027,7 +1055,7 @@ export function selectCoinForOperation(
refreshIteration: while (refreshIdx < coins.list.length) {
const d = coins.list[refreshIdx];
const denomContribution =
- mode === "gross"
+ mode === AmountMode.Gross
? Amounts.sub(d.value, d.denomRefresh).amount
: Amounts.sub(d.value, d.denomDeposit, d.denomRefresh).amount;
@@ -1038,7 +1066,7 @@ export function selectCoinForOperation(
}
const changeCost = selectCoinForOperation(
- "credit",
+ OperationType.Credit,
changeAfterDeposit,
mode,
coins,
@@ -1067,7 +1095,7 @@ export function selectCoinForOperation(
refreshIdx++;
}
if (choice) {
- if (mode === "gross") {
+ if (mode === AmountMode.Gross) {
result.totalValue = Amounts.add(result.totalValue, gap).amount;
result.totalContribution = Amounts.add(
result.totalContribution,
@@ -1096,9 +1124,9 @@ export function selectCoinForOperation(
}
type CompareCoinsFunction = (d1: CoinInfo, d2: CoinInfo) => -1 | 0 | 1;
-function buildRankingForCoins(op: "debit" | "credit"): CompareCoinsFunction {
+function buildRankingForCoins(op: OperationType): CompareCoinsFunction {
function getFee(d: CoinInfo) {
- return op === "credit" ? d.denomWithdraw : d.denomDeposit;
+ return op === OperationType.Credit ? d.denomWithdraw : d.denomDeposit;
}
//different exchanges may have different wireFee
//ranking should take the relative contribution in the exchange
@@ -1116,28 +1144,32 @@ function buildRankingForCoins(op: "debit" | "credit"): CompareCoinsFunction {
};
}
-function getOperationType(txType: TransactionType): "credit" | "debit" {
+function getOperationType(txType: TransactionType): OperationType {
const operationType =
txType === TransactionType.Withdrawal
- ? ("credit" as const)
+ ? OperationType.Credit
: txType === TransactionType.Deposit
- ? ("debit" as const)
+ ? OperationType.Debit
: undefined;
if (!operationType) {
- throw Error(`operation type ${txType} not supported`);
+ throw Error(`operation type ${txType} not yet supported`);
}
return operationType;
}
function getAmountsWithFee(
- op: "debit" | "credit",
+ op: OperationType,
value: AmountJson,
contribution: AmountJson,
details: any,
): GetPlanForOperationResponse {
return {
- rawAmount: Amounts.stringify(op === "credit" ? value : contribution),
- effectiveAmount: Amounts.stringify(op === "credit" ? contribution : value),
+ rawAmount: Amounts.stringify(
+ op === OperationType.Credit ? value : contribution,
+ ),
+ effectiveAmount: Amounts.stringify(
+ op === OperationType.Credit ? contribution : value,
+ ),
details,
};
}
@@ -1202,7 +1234,7 @@ interface CoinsFilter {
*/
async function getAvailableCoins(
ws: InternalWalletState,
- op: "credit" | "debit",
+ op: OperationType,
currency: string,
filters: CoinsFilter = {},
): Promise<AvailableCoins> {
@@ -1286,7 +1318,7 @@ async function getAvailableCoins(
let creditDeadline = AbsoluteTime.never();
let debitDeadline = AbsoluteTime.never();
//4.- filter coins restricted by age
- if (op === "credit") {
+ if (op === OperationType.Credit) {
const ds = await tx.denominations.indexes.byExchangeBaseUrl.getAll(
exchangeBaseUrl,
);
diff --git a/packages/taler-wallet-core/src/util/denominations.ts b/packages/taler-wallet-core/src/util/denominations.ts
index 2b2faa458..76716cf7a 100644
--- a/packages/taler-wallet-core/src/util/denominations.ts
+++ b/packages/taler-wallet-core/src/util/denominations.ts
@@ -458,7 +458,9 @@ export function isWithdrawableDenom(
): boolean {
const now = AbsoluteTime.now();
const start = AbsoluteTime.fromProtocolTimestamp(d.stampStart);
- const withdrawExpire = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw);
+ const withdrawExpire = AbsoluteTime.fromProtocolTimestamp(
+ d.stampExpireWithdraw,
+ );
const started = AbsoluteTime.cmp(now, start) >= 0;
let lastPossibleWithdraw: AbsoluteTime;
if (denomselAllowLate) {