diff options
author | Florian Dold <florian@dold.me> | 2024-06-13 18:19:20 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-06-13 18:22:23 +0200 |
commit | 10aa5e767a35d39d6612f5e4addf4e04f3241a42 (patch) | |
tree | 70d62dbbe02a9257e0af988a09de8cc0ee9ba557 /packages/taler-wallet-core/src/pay-peer-common.ts | |
parent | 955b957ef6d7d27d444d363cf80ea8942233f97c (diff) | |
download | wallet-core-10aa5e767a35d39d6612f5e4addf4e04f3241a42.tar.xz |
wallet-core: introduce coin history store, spend coins transactionally
Diffstat (limited to 'packages/taler-wallet-core/src/pay-peer-common.ts')
-rw-r--r-- | packages/taler-wallet-core/src/pay-peer-common.ts | 77 |
1 files changed, 46 insertions, 31 deletions
diff --git a/packages/taler-wallet-core/src/pay-peer-common.ts b/packages/taler-wallet-core/src/pay-peer-common.ts index a1729ced7..636dd4156 100644 --- a/packages/taler-wallet-core/src/pay-peer-common.ts +++ b/packages/taler-wallet-core/src/pay-peer-common.ts @@ -31,7 +31,11 @@ import { codecOptional, } from "@gnu-taler/taler-util"; import { SpendCoinDetails } from "./crypto/cryptoImplementation.js"; -import { DbPeerPushPaymentCoinSelection, ReserveRecord } from "./db.js"; +import { + DbPeerPushPaymentCoinSelection, + ReserveRecord, + WalletDbReadOnlyTransaction, +} from "./db.js"; import { getTotalRefreshCost } from "./refresh.js"; import { WalletExecutionContext, getDenomInfo } from "./wallet.js"; @@ -74,6 +78,38 @@ export async function queryCoinInfosForSelection( return infos; } +export async function getTotalPeerPaymentCostInTx( + wex: WalletExecutionContext, + tx: WalletDbReadOnlyTransaction<["coins", "denominations"]>, + pcs: SelectedProspectiveCoin[], +): Promise<AmountJson> { + const costs: AmountJson[] = []; + for (let i = 0; i < pcs.length; i++) { + const denomInfo = await getDenomInfo( + wex, + tx, + pcs[i].exchangeBaseUrl, + pcs[i].denomPubHash, + ); + if (!denomInfo) { + throw Error( + "can't calculate payment cost, denomination for coin not found", + ); + } + const amountLeft = Amounts.sub(denomInfo.value, pcs[i].contribution).amount; + const refreshCost = await getTotalRefreshCost( + wex, + tx, + denomInfo, + amountLeft, + ); + costs.push(Amounts.parseOrThrow(pcs[i].contribution)); + costs.push(refreshCost); + } + const zero = Amounts.zeroOfAmount(pcs[0].contribution); + return Amounts.sum([zero, ...costs]).amount; +} + export async function getTotalPeerPaymentCost( wex: WalletExecutionContext, pcs: SelectedProspectiveCoin[], @@ -81,34 +117,7 @@ export async function getTotalPeerPaymentCost( return wex.db.runReadOnlyTx( { storeNames: ["coins", "denominations"] }, async (tx) => { - const costs: AmountJson[] = []; - for (let i = 0; i < pcs.length; i++) { - const denomInfo = await getDenomInfo( - wex, - tx, - pcs[i].exchangeBaseUrl, - pcs[i].denomPubHash, - ); - if (!denomInfo) { - throw Error( - "can't calculate payment cost, denomination for coin not found", - ); - } - const amountLeft = Amounts.sub( - denomInfo.value, - pcs[i].contribution, - ).amount; - const refreshCost = await getTotalRefreshCost( - wex, - tx, - denomInfo, - amountLeft, - ); - costs.push(Amounts.parseOrThrow(pcs[i].contribution)); - costs.push(refreshCost); - } - const zero = Amounts.zeroOfAmount(pcs[0].contribution); - return Amounts.sum([zero, ...costs]).amount; + return getTotalPeerPaymentCostInTx(wex, tx, pcs); }, ); } @@ -143,7 +152,10 @@ export async function getMergeReserveInfo( checkDbInvariant(!!ex, `no exchange record for ${req.exchangeBaseUrl}`); if (ex.currentMergeReserveRowId != null) { const reserve = await tx.reserves.get(ex.currentMergeReserveRowId); - checkDbInvariant(!!reserve, `reserver ${ex.currentMergeReserveRowId} missing in db`); + checkDbInvariant( + !!reserve, + `reserver ${ex.currentMergeReserveRowId} missing in db`, + ); return reserve; } const reserve: ReserveRecord = { @@ -151,7 +163,10 @@ export async function getMergeReserveInfo( reservePub: newReservePair.pub, }; const insertResp = await tx.reserves.put(reserve); - checkDbInvariant(typeof insertResp.key === "number", `reserve key is not a number`); + checkDbInvariant( + typeof insertResp.key === "number", + `reserve key is not a number`, + ); reserve.rowId = insertResp.key; ex.currentMergeReserveRowId = reserve.rowId; await tx.exchanges.put(ex); |