aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/operations
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/operations')
-rw-r--r--packages/taler-wallet-core/src/operations/pay-merchant.ts48
-rw-r--r--packages/taler-wallet-core/src/operations/refresh.ts57
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,
+ };
+}