diff options
Diffstat (limited to 'packages/taler-wallet-core/src/operations')
-rw-r--r-- | packages/taler-wallet-core/src/operations/pay-merchant.ts | 48 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/operations/refresh.ts | 57 |
2 files changed, 97 insertions, 8 deletions
diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index 5d58f4c2f..a81311702 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -30,11 +30,13 @@ import { AbsoluteTime, AmountJson, Amounts, + AmountString, codecForAbortResponse, codecForMerchantContractTerms, codecForMerchantOrderRefundPickupResponse, codecForMerchantOrderStatusPaid, codecForMerchantPayResponse, + codecForMerchantPostOrderResponse, codecForProposal, CoinDepositPermission, CoinRefreshRequest, @@ -53,12 +55,15 @@ import { MerchantCoinRefundStatus, MerchantContractTerms, MerchantPayResponse, + MerchantUsingTemplateDetails, NotificationType, + parsePayTemplateUri, parsePayUri, parseTalerUri, PayCoinSelection, PreparePayResult, PreparePayResultType, + PreparePayTemplateRequest, randomBytes, RefreshReason, SharePaymentResult, @@ -1209,6 +1214,49 @@ export async function preparePayForUri( return checkPaymentByProposalId(ws, proposalId, uriResult.sessionId); } +export async function preparePayForTemplate( + ws: InternalWalletState, + req: PreparePayTemplateRequest, +): Promise<PreparePayResult> { + const url = parsePayTemplateUri(req.talerPayTemplateUri); + const templateDetails: MerchantUsingTemplateDetails = {}; + if (!url) { + throw Error("invalid taler-template URI"); + } + if ( + url.templateParams.amount !== undefined && + typeof url.templateParams.amount === "string" + ) { + templateDetails.amount = (req.templateParams.amount ?? + url.templateParams.amount) as AmountString | undefined; + } + if ( + url.templateParams.summary !== undefined && + typeof url.templateParams.summary === "string" + ) { + templateDetails.summary = + req.templateParams.summary ?? url.templateParams.summary; + } + const reqUrl = new URL(`templates/${url.templateId}`, url.merchantBaseUrl); + const httpReq = await ws.http.fetch(reqUrl.href, { + method: "POST", + body: templateDetails, + }); + const resp = await readSuccessResponseJsonOrThrow( + httpReq, + codecForMerchantPostOrderResponse(), + ); + + const payUri = stringifyPayUri({ + merchantBaseUrl: url.merchantBaseUrl, + orderId: resp.order_id, + sessionId: "", + claimToken: resp.token, + }); + + return await preparePayForUri(ws, payUri); +} + /** * Generate deposit permissions for a purchase. * diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index a8bcb28d1..390433f66 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -36,6 +36,7 @@ import { ExchangeProtocolVersion, ExchangeRefreshRevealRequest, fnutil, + ForceRefreshRequest, getErrorDetailFromException, getRandomBytes, HashCodeString, @@ -79,8 +80,6 @@ import { } from "../db.js"; import { getCandidateWithdrawalDenomsTx, - isWithdrawableDenom, - PendingTaskType, RefreshSessionRecord, timestampPreciseToDb, timestampProtocolFromDb, @@ -93,13 +92,8 @@ import { import { assertUnreachable } from "../util/assertUnreachable.js"; import { selectWithdrawalDenominations } from "../util/coinSelection.js"; import { checkDbInvariant } from "../util/invariants.js"; +import { GetReadOnlyAccess, GetReadWriteAccess } from "../util/query.js"; import { - DbReadWriteTransaction, - GetReadOnlyAccess, - GetReadWriteAccess, -} from "../util/query.js"; -import { - constructTaskIdentifier, makeCoinAvailable, makeCoinsVisible, TaskRunResult, @@ -1449,3 +1443,50 @@ export async function abortRefreshGroup( ws.workAvailable.trigger(); notifyTransition(ws, transactionId, transitionInfo); } + +export async function forceRefresh( + ws: InternalWalletState, + req: ForceRefreshRequest, +): Promise<{ refreshGroupId: RefreshGroupId }> { + if (req.coinPubList.length == 0) { + throw Error("refusing to create empty refresh group"); + } + const refreshGroupId = await ws.db + .mktx((x) => [ + x.refreshGroups, + x.coinAvailability, + x.denominations, + x.coins, + ]) + .runReadWrite(async (tx) => { + let coinPubs: CoinRefreshRequest[] = []; + for (const c of req.coinPubList) { + const coin = await tx.coins.get(c); + if (!coin) { + throw Error(`coin (pubkey ${c}) not found`); + } + const denom = await ws.getDenomInfo( + ws, + tx, + coin.exchangeBaseUrl, + coin.denomPubHash, + ); + checkDbInvariant(!!denom); + coinPubs.push({ + coinPub: c, + amount: denom?.value, + }); + } + return await createRefreshGroup( + ws, + tx, + Amounts.currencyOf(coinPubs[0].amount), + coinPubs, + RefreshReason.Manual, + ); + }); + + return { + refreshGroupId, + }; +} |