diff options
author | Florian Dold <florian@dold.me> | 2022-09-14 21:27:03 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2022-09-14 21:27:03 +0200 |
commit | a66b636dee2ed531bb5119feced80d6569d99176 (patch) | |
tree | d19b83739531220051ab850bfe3dd9478f7fca6b /packages/taler-wallet-core/src/operations | |
parent | c021876b41bff11ad28c3a43808795fa0d02ce99 (diff) | |
download | wallet-core-a66b636dee2ed531bb5119feced80d6569d99176.tar.xz |
wallet-core: restructure denomination record for easier querying
Diffstat (limited to 'packages/taler-wallet-core/src/operations')
10 files changed, 252 insertions, 197 deletions
diff --git a/packages/taler-wallet-core/src/operations/backup/export.ts b/packages/taler-wallet-core/src/operations/backup/export.ts index fb1fbf90b..35d5e6ef7 100644 --- a/packages/taler-wallet-core/src/operations/backup/export.ts +++ b/packages/taler-wallet-core/src/operations/backup/export.ts @@ -62,6 +62,7 @@ import { AbortStatus, CoinSourceType, CoinStatus, + DenominationRecord, ProposalStatus, RefreshCoinStatus, RefundState, @@ -221,10 +222,10 @@ export async function exportBackup( backupDenoms.push({ coins: backupCoinsByDenom[denom.denomPubHash] ?? [], denom_pub: denom.denomPub, - fee_deposit: Amounts.stringify(denom.feeDeposit), - fee_refresh: Amounts.stringify(denom.feeRefresh), - fee_refund: Amounts.stringify(denom.feeRefund), - fee_withdraw: Amounts.stringify(denom.feeWithdraw), + fee_deposit: Amounts.stringify(denom.fees.feeDeposit), + fee_refresh: Amounts.stringify(denom.fees.feeRefresh), + fee_refund: Amounts.stringify(denom.fees.feeRefund), + fee_withdraw: Amounts.stringify(denom.fees.feeWithdraw), is_offered: denom.isOffered, is_revoked: denom.isRevoked, master_sig: denom.masterSig, @@ -232,7 +233,7 @@ export async function exportBackup( stamp_expire_legal: denom.stampExpireLegal, stamp_expire_withdraw: denom.stampExpireWithdraw, stamp_start: denom.stampStart, - value: Amounts.stringify(denom.value), + value: Amounts.stringify(DenominationRecord.getValue(denom)), list_issue_date: denom.listIssueDate, }); }); diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts index 53e45918e..53dc50f3b 100644 --- a/packages/taler-wallet-core/src/operations/backup/import.ts +++ b/packages/taler-wallet-core/src/operations/backup/import.ts @@ -38,6 +38,7 @@ import { CoinSource, CoinSourceType, CoinStatus, + DenominationRecord, DenominationVerificationStatus, DenomSelectionState, OperationStatus, @@ -108,7 +109,10 @@ async function recoverPayCoinSelection( coinRecord.denomPubHash, ]); checkBackupInvariant(!!denom); - totalDepositFees = Amounts.add(totalDepositFees, denom.feeDeposit).amount; + totalDepositFees = Amounts.add( + totalDepositFees, + denom.fees.feeDeposit, + ).amount; if (!coveredExchanges.has(coinRecord.exchangeBaseUrl)) { const exchangeDetails = await getExchangeDetails( @@ -175,16 +179,19 @@ async function getDenomSelStateFromBackup( denomPubHash: string; count: number; }[] = []; - let totalCoinValue = Amounts.getZero(d0.value.currency); - let totalWithdrawCost = Amounts.getZero(d0.value.currency); + let totalCoinValue = Amounts.getZero(d0.currency); + let totalWithdrawCost = Amounts.getZero(d0.currency); for (const s of sel) { const d = await tx.denominations.get([exchangeBaseUrl, s.denom_pub_hash]); checkBackupInvariant(!!d); - totalCoinValue = Amounts.add(totalCoinValue, d.value).amount; + totalCoinValue = Amounts.add( + totalCoinValue, + DenominationRecord.getValue(d), + ).amount; totalWithdrawCost = Amounts.add( totalWithdrawCost, - d.value, - d.feeWithdraw, + DenominationRecord.getValue(d), + d.fees.feeWithdraw, ).amount; } return { @@ -352,17 +359,25 @@ export async function importBackup( `importing backup denomination: ${j2s(backupDenomination)}`, ); + const value = Amounts.parseOrThrow(backupDenomination.value); + await tx.denominations.put({ denomPub: backupDenomination.denom_pub, denomPubHash: denomPubHash, exchangeBaseUrl: backupExchangeDetails.base_url, exchangeMasterPub: backupExchangeDetails.master_public_key, - feeDeposit: Amounts.parseOrThrow(backupDenomination.fee_deposit), - feeRefresh: Amounts.parseOrThrow(backupDenomination.fee_refresh), - feeRefund: Amounts.parseOrThrow(backupDenomination.fee_refund), - feeWithdraw: Amounts.parseOrThrow( - backupDenomination.fee_withdraw, - ), + fees: { + feeDeposit: Amounts.parseOrThrow( + backupDenomination.fee_deposit, + ), + feeRefresh: Amounts.parseOrThrow( + backupDenomination.fee_refresh, + ), + feeRefund: Amounts.parseOrThrow(backupDenomination.fee_refund), + feeWithdraw: Amounts.parseOrThrow( + backupDenomination.fee_withdraw, + ), + }, isOffered: backupDenomination.is_offered, isRevoked: backupDenomination.is_revoked, masterSig: backupDenomination.master_sig, @@ -371,7 +386,9 @@ export async function importBackup( stampExpireWithdraw: backupDenomination.stamp_expire_withdraw, stampStart: backupDenomination.stamp_start, verificationStatus: DenominationVerificationStatus.VerifiedGood, - value: Amounts.parseOrThrow(backupDenomination.value), + currency: value.currency, + amountFrac: value.fraction, + amountVal: value.value, listIssueDate: backupDenomination.list_issue_date, }); } @@ -648,7 +665,7 @@ export async function importBackup( executionTime: backupRefund.execution_time, obtainedTime: backupRefund.obtained_time, refundAmount: Amounts.parseOrThrow(backupRefund.refund_amount), - refundFee: denom.feeRefund, + refundFee: denom.fees.feeRefund, rtransactionId: backupRefund.rtransaction_id, totalRefreshCostBound: Amounts.parseOrThrow( backupRefund.total_refresh_cost_bound, diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index 6d63def59..612de8240 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -44,6 +44,7 @@ import { URL, } from "@gnu-taler/taler-util"; import { + DenominationRecord, DepositGroupRecord, OperationAttemptResult, OperationStatus, @@ -636,7 +637,10 @@ export async function getTotalFeesForDepositAmount( const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl .iter(coin.exchangeBaseUrl) .filter((x) => - Amounts.isSameCurrency(x.value, pcs.coinContributions[i]), + Amounts.isSameCurrency( + DenominationRecord.getValue(x), + pcs.coinContributions[i], + ), ); const amountLeft = Amounts.sub( denom.value, diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 504978441..ca85ff465 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -81,15 +81,18 @@ function denominationRecordFromKeys( let denomPub: DenominationPubKey; denomPub = denomIn.denom_pub; const denomPubHash = encodeCrock(hashDenomPub(denomPub)); + const value = Amounts.parseOrThrow(denomIn.value); const d: DenominationRecord = { denomPub, denomPubHash, exchangeBaseUrl, exchangeMasterPub, - feeDeposit: Amounts.parseOrThrow(denomIn.fee_deposit), - feeRefresh: Amounts.parseOrThrow(denomIn.fee_refresh), - feeRefund: Amounts.parseOrThrow(denomIn.fee_refund), - feeWithdraw: Amounts.parseOrThrow(denomIn.fee_withdraw), + fees: { + feeDeposit: Amounts.parseOrThrow(denomIn.fee_deposit), + feeRefresh: Amounts.parseOrThrow(denomIn.fee_refresh), + feeRefund: Amounts.parseOrThrow(denomIn.fee_refund), + feeWithdraw: Amounts.parseOrThrow(denomIn.fee_withdraw), + }, isOffered: true, isRevoked: false, masterSig: denomIn.master_sig, @@ -98,7 +101,9 @@ function denominationRecordFromKeys( stampExpireWithdraw: denomIn.stamp_expire_withdraw, stampStart: denomIn.stamp_start, verificationStatus: DenominationVerificationStatus.Unverified, - value: Amounts.parseOrThrow(denomIn.value), + amountFrac: value.fraction, + amountVal: value.value, + currency: value.currency, listIssueDate, }; return d; diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts index bd7b1f7f0..5a0d3cee3 100644 --- a/packages/taler-wallet-core/src/operations/pay.ts +++ b/packages/taler-wallet-core/src/operations/pay.ts @@ -141,13 +141,20 @@ export async function getTotalPaymentCost( const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl .iter(coin.exchangeBaseUrl) .filter((x) => - Amounts.isSameCurrency(x.value, pcs.coinContributions[i]), + Amounts.isSameCurrency( + DenominationRecord.getValue(x), + pcs.coinContributions[i], + ), ); const amountLeft = Amounts.sub( - denom.value, + DenominationRecord.getValue(denom), pcs.coinContributions[i], ).amount; - const refreshCost = getTotalRefreshCost(allDenoms, denom, amountLeft); + const refreshCost = getTotalRefreshCost( + allDenoms, + DenominationRecord.toDenomInfo(denom), + amountLeft, + ); costs.push(pcs.coinContributions[i]); costs.push(refreshCost); } @@ -303,7 +310,7 @@ export async function getCandidatePayCoins( if (!denom) { throw Error("db inconsistent"); } - if (denom.value.currency !== currency) { + if (denom.currency !== currency) { logger.warn( `same pubkey for different currencies at exchange ${exchange.baseUrl}`, ); @@ -314,10 +321,10 @@ export async function getCandidatePayCoins( } candidateCoins.push({ availableAmount: coin.currentAmount, - value: denom.value, + value: DenominationRecord.getValue(denom), coinPub: coin.coinPub, denomPub: denom.denomPub, - feeDeposit: denom.feeDeposit, + feeDeposit: denom.fees.feeDeposit, exchangeBaseUrl: denom.exchangeBaseUrl, ageCommitmentProof: coin.ageCommitmentProof, }); @@ -949,7 +956,7 @@ async function handleInsufficientFunds( coinPub, contribution: contrib, exchangeBaseUrl: coin.exchangeBaseUrl, - feeDeposit: denom.feeDeposit, + feeDeposit: denom.fees.feeDeposit, }); } }); @@ -1269,7 +1276,7 @@ export async function generateDepositPermissions( denomKeyType: denom.denomPub.cipher, denomSig: coin.denomSig, exchangeBaseUrl: coin.exchangeBaseUrl, - feeDeposit: denom.feeDeposit, + feeDeposit: denom.fees.feeDeposit, merchantPub: contractData.merchantPub, refundDeadline: contractData.refundDeadline, spendAmount: payCoinSel.coinContributions[i], diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index d1c366cd0..2d9ad2c05 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -112,7 +112,11 @@ export function getTotalRefreshCost( const resultingAmount = Amounts.add( Amounts.getZero(withdrawAmount.currency), ...withdrawDenoms.selectedDenoms.map( - (d) => Amounts.mult(denomMap[d.denomPubHash].value, d.count).amount, + (d) => + Amounts.mult( + DenominationRecord.getValue(denomMap[d.denomPubHash]), + d.count, + ).amount, ), ).amount; const totalCost = Amounts.sub(amountLeft, resultingAmount).amount; diff --git a/packages/taler-wallet-core/src/operations/refund.ts b/packages/taler-wallet-core/src/operations/refund.ts index 5ee0680d7..f028dfbf1 100644 --- a/packages/taler-wallet-core/src/operations/refund.ts +++ b/packages/taler-wallet-core/src/operations/refund.ts @@ -51,6 +51,7 @@ import { import { AbortStatus, CoinStatus, + DenominationRecord, OperationAttemptResult, PurchaseRecord, RefundReason, @@ -148,7 +149,7 @@ async function applySuccessfulRefund( } refreshCoinsMap[coin.coinPub] = { coinPub: coin.coinPub }; const refundAmount = Amounts.parseOrThrow(r.refund_amount); - const refundFee = denom.feeRefund; + const refundFee = denom.fees.feeRefund; coin.status = CoinStatus.Dormant; coin.currentAmount = Amounts.add(coin.currentAmount, refundAmount).amount; coin.currentAmount = Amounts.sub(coin.currentAmount, refundFee).amount; @@ -162,12 +163,12 @@ async function applySuccessfulRefund( const amountLeft = Amounts.sub( Amounts.add(coin.currentAmount, Amounts.parseOrThrow(r.refund_amount)) .amount, - denom.feeRefund, + denom.fees.feeRefund, ).amount; const totalRefreshCostBound = getTotalRefreshCost( allDenoms, - denom, + DenominationRecord.toDenomInfo(denom), amountLeft, ); @@ -176,7 +177,7 @@ async function applySuccessfulRefund( obtainedTime: AbsoluteTime.toTimestamp(AbsoluteTime.now()), executionTime: r.execution_time, refundAmount: Amounts.parseOrThrow(r.refund_amount), - refundFee: denom.feeRefund, + refundFee: denom.fees.feeRefund, totalRefreshCostBound, coinPub: r.coin_pub, rtransactionId: r.rtransaction_id, @@ -214,12 +215,12 @@ async function storePendingRefund( const amountLeft = Amounts.sub( Amounts.add(coin.currentAmount, Amounts.parseOrThrow(r.refund_amount)) .amount, - denom.feeRefund, + denom.fees.feeRefund, ).amount; const totalRefreshCostBound = getTotalRefreshCost( allDenoms, - denom, + DenominationRecord.toDenomInfo(denom), amountLeft, ); @@ -228,7 +229,7 @@ async function storePendingRefund( obtainedTime: AbsoluteTime.toTimestamp(AbsoluteTime.now()), executionTime: r.execution_time, refundAmount: Amounts.parseOrThrow(r.refund_amount), - refundFee: denom.feeRefund, + refundFee: denom.fees.feeRefund, totalRefreshCostBound, coinPub: r.coin_pub, rtransactionId: r.rtransaction_id, @@ -267,12 +268,12 @@ async function storeFailedRefund( const amountLeft = Amounts.sub( Amounts.add(coin.currentAmount, Amounts.parseOrThrow(r.refund_amount)) .amount, - denom.feeRefund, + denom.fees.feeRefund, ).amount; const totalRefreshCostBound = getTotalRefreshCost( allDenoms, - denom, + DenominationRecord.toDenomInfo(denom), amountLeft, ); @@ -281,7 +282,7 @@ async function storeFailedRefund( obtainedTime: TalerProtocolTimestamp.now(), executionTime: r.execution_time, refundAmount: Amounts.parseOrThrow(r.refund_amount), - refundFee: denom.feeRefund, + refundFee: denom.fees.feeRefund, totalRefreshCostBound, coinPub: r.coin_pub, rtransactionId: r.rtransaction_id, @@ -314,7 +315,7 @@ async function storeFailedRefund( coin.currentAmount = Amounts.add(coin.currentAmount, contrib).amount; coin.currentAmount = Amounts.sub( coin.currentAmount, - denom.feeRefund, + denom.fees.feeRefund, ).amount; } refreshCoinsMap[coin.coinPub] = { coinPub: coin.coinPub }; diff --git a/packages/taler-wallet-core/src/operations/tip.ts b/packages/taler-wallet-core/src/operations/tip.ts index f70e2d02b..c8f327a56 100644 --- a/packages/taler-wallet-core/src/operations/tip.ts +++ b/packages/taler-wallet-core/src/operations/tip.ts @@ -306,7 +306,7 @@ export async function processTip( coinIndex: i, walletTipId: walletTipId, }, - currentAmount: denom.value, + currentAmount: DenominationRecord.getValue(denom), denomPubHash: denom.denomPubHash, denomSig: { cipher: DenomKeyType.Rsa, rsa_signature: denomSigRsa.sig }, exchangeBaseUrl: tipRecord.exchangeBaseUrl, diff --git a/packages/taler-wallet-core/src/operations/withdraw.test.ts b/packages/taler-wallet-core/src/operations/withdraw.test.ts index 9f9146719..70b4f73c0 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.test.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.test.ts @@ -38,25 +38,27 @@ test("withdrawal selection bug repro", (t) => { "Q21FQSSG4FXNT96Z14CHXM8N1RZAG9GPHAV8PRWS0PZAAVWH7PBW6R97M2CH19KKP65NNSWXY7B6S53PT3CBM342E357ZXDDJ8RDVW8", exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeMasterPub: "", - feeDeposit: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefresh: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefund: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeWithdraw: { - currency: "KUDOS", - fraction: 1000000, - value: 0, + fees: { + feeDeposit: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefresh: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefund: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeWithdraw: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, }, isOffered: true, isRevoked: false, @@ -75,11 +77,9 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - value: { - currency: "KUDOS", - fraction: 0, - value: 1000, - }, + currency: "KUDOS", + amountFrac: 0, + amountVal: 1000, listIssueDate: { t_s: 0 }, }, { @@ -94,25 +94,27 @@ test("withdrawal selection bug repro", (t) => { "447WA23SCBATMABHA0793F92MYTBYVPYMMQHCPKMKVY5P7RZRFMQ6VRW0Y8HRA7177GTBT0TBT08R21DZD129AJ995H9G09XBFE55G8", exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeMasterPub: "", - feeDeposit: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefresh: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefund: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeWithdraw: { - currency: "KUDOS", - fraction: 1000000, - value: 0, + fees: { + feeDeposit: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefresh: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefund: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeWithdraw: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, }, isOffered: true, isRevoked: false, @@ -131,11 +133,9 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - value: { - currency: "KUDOS", - fraction: 0, - value: 10, - }, + amountFrac: 0, + amountVal: 10, + currency: "KUDOS", listIssueDate: { t_s: 0 }, }, { @@ -149,25 +149,27 @@ test("withdrawal selection bug repro", (t) => { "JS61DTKAFM0BX8Q4XV3ZSKB921SM8QK745Z2AFXTKFMBHHFNBD8TQ5ETJHFNDGBGX22FFN2A2ERNYG1SGSDQWNQHQQ2B14DBVJYJG8R", exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeMasterPub: "", - feeDeposit: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefresh: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefund: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeWithdraw: { - currency: "KUDOS", - fraction: 1000000, - value: 0, + fees: { + feeDeposit: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefresh: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefund: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeWithdraw: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, }, isOffered: true, isRevoked: false, @@ -186,11 +188,9 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - value: { - currency: "KUDOS", - fraction: 0, - value: 5, - }, + amountFrac: 0, + amountVal: 5, + currency: "KUDOS", listIssueDate: { t_s: 0 }, }, { @@ -205,25 +205,27 @@ test("withdrawal selection bug repro", (t) => { "8T51NEY81VMPQ180EQ5WR0YH7GMNNT90W55Q0514KZM18AZT71FHJGJHQXGK0WTA7ACN1X2SD0S53XPBQ1A9KH960R48VCVVM6E3TH8", exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeMasterPub: "", - feeDeposit: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefresh: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefund: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeWithdraw: { - currency: "KUDOS", - fraction: 1000000, - value: 0, + fees: { + feeDeposit: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefresh: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefund: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeWithdraw: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, }, isOffered: true, isRevoked: false, @@ -242,11 +244,9 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - value: { - currency: "KUDOS", - fraction: 0, - value: 1, - }, + amountFrac: 0, + amountVal: 1, + currency: "KUDOS", listIssueDate: { t_s: 0 }, }, { @@ -260,25 +260,27 @@ test("withdrawal selection bug repro", (t) => { "A41HW0Q2H9PCNMEWW0C0N45QAYVXZ8SBVRRAHE4W6X24SV1TH38ANTWDT80JXEBW9Z8PVPGT9GFV2EYZWJ5JW5W1N34NFNKHQSZ1PFR", exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeMasterPub: "", - feeDeposit: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefresh: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefund: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeWithdraw: { - currency: "KUDOS", - fraction: 1000000, - value: 0, + fees: { + feeDeposit: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefresh: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefund: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeWithdraw: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, }, isOffered: true, isRevoked: false, @@ -297,11 +299,9 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - value: { - currency: "KUDOS", - fraction: 10000000, - value: 0, - }, + amountFrac: 10000000, + amountVal: 0, + currency: "KUDOS", listIssueDate: { t_s: 0 }, }, { @@ -315,25 +315,27 @@ test("withdrawal selection bug repro", (t) => { "F5NGBX33DTV4595XZZVK0S2MA1VMXFEJQERE5EBP5DS4QQ9EFRANN7YHWC1TKSHT2K6CQWDBRES8D3DWR0KZF5RET40B4AZXZ0RW1ZG", exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeMasterPub: "", - feeDeposit: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefresh: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeRefund: { - currency: "KUDOS", - fraction: 1000000, - value: 0, - }, - feeWithdraw: { - currency: "KUDOS", - fraction: 1000000, - value: 0, + fees: { + feeDeposit: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefresh: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeRefund: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, + feeWithdraw: { + currency: "KUDOS", + fraction: 1000000, + value: 0, + }, }, isOffered: true, isRevoked: false, @@ -352,11 +354,9 @@ test("withdrawal selection bug repro", (t) => { t_s: 1585229388, }, verificationStatus: DenominationVerificationStatus.Unverified, - value: { - currency: "KUDOS", - fraction: 0, - value: 2, - }, + amountFrac: 0, + amountVal: 2, + currency: "KUDOS", listIssueDate: { t_s: 0 }, }, ]; diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index bee83265c..47252a7e4 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -243,11 +243,19 @@ export function selectWithdrawalDenominations( let totalWithdrawCost = Amounts.getZero(amountAvailable.currency); denoms = denoms.filter(isWithdrawableDenom); - denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value)); + denoms.sort((d1, d2) => + Amounts.cmp( + DenominationRecord.getValue(d2), + DenominationRecord.getValue(d1), + ), + ); for (const d of denoms) { let count = 0; - const cost = Amounts.add(d.value, d.feeWithdraw).amount; + const cost = Amounts.add( + DenominationRecord.getValue(d), + d.fees.feeWithdraw, + ).amount; for (;;) { if (Amounts.cmp(remaining, cost) < 0) { break; @@ -258,7 +266,7 @@ export function selectWithdrawalDenominations( if (count > 0) { totalCoinValue = Amounts.add( totalCoinValue, - Amounts.mult(d.value, count).amount, + Amounts.mult(DenominationRecord.getValue(d), count).amount, ).amount; totalWithdrawCost = Amounts.add( totalWithdrawCost, @@ -306,22 +314,30 @@ export function selectForcedWithdrawalDenominations( let totalWithdrawCost = Amounts.getZero(amountAvailable.currency); denoms = denoms.filter(isWithdrawableDenom); - denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value)); + 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(x.value, fds.value) == 0; + 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(denom.value, denom.feeWithdraw).amount; + const cost = Amounts.add( + DenominationRecord.getValue(denom), + denom.fees.feeWithdraw, + ).amount; totalCoinValue = Amounts.add( totalCoinValue, - Amounts.mult(denom.value, count).amount, + Amounts.mult(DenominationRecord.getValue(denom), count).amount, ).amount; totalWithdrawCost = Amounts.add( totalWithdrawCost, |