commit 3b6993113a944e0013c4e5f1128ba20351de51b5
parent 7fe0c88e35e3cb9e3d8619f9334c64b71aa1b270
Author: Florian Dold <florian@dold.me>
Date: Wed, 20 Aug 2025 13:54:35 +0200
wallet-core: auto-select choice in confirmPay when v1 flag disabled
Diffstat:
2 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/packages/taler-util/src/contract-terms.ts b/packages/taler-util/src/contract-terms.ts
@@ -32,6 +32,7 @@ import {
import {
MerchantContractTerms,
MerchantContractTermsV0,
+ MerchantContractTermsV1,
MerchantContractTokenKind,
MerchantContractVersion,
} from "./types-taler-merchant.js";
@@ -320,6 +321,22 @@ export namespace ContractTermsUtil {
};
}
+ export function getV0CompatChoiceIndex(terms: MerchantContractTermsV1): number | undefined {
+ // Select the first choice that doesn't have
+ // and non-currency inputs.
+ let firstGood: number | undefined = undefined;
+ for (let i = 0; i < terms.choices.length; i++) {
+ if (terms.choices[i].inputs.length == 0) {
+ firstGood = i;
+ break;
+ }
+ }
+ if (firstGood != null) {
+ return firstGood;
+ }
+ return undefined;
+ }
+
/**
* Try to downgrade contract terms in the v1 format to the v0 format.
* Returns undefined if downgrading is not possible. This can happen
@@ -332,16 +349,8 @@ export namespace ContractTermsUtil {
if (terms.version !== MerchantContractVersion.V1) {
return undefined;
}
- // Select the first choice that doesn't have
- // and non-currency inputs.
- let firstGood = -1;
- for (let i = 0; i < terms.choices.length; i++) {
- if (terms.choices[i].inputs.length == 0) {
- firstGood = i;
- break;
- }
- }
- if (firstGood < 0) {
+ const firstGood = getV0CompatChoiceIndex(terms);
+ if (firstGood == null) {
return undefined;
}
return {
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -2786,8 +2786,9 @@ export async function confirmPay(
if (
choiceIndex !== undefined &&
choiceIndex !== existingPurchase.choiceIndex
- )
+ ) {
throw Error(`cannot change choice index of existing purchase`);
+ }
logger.trace("confirmPay: submitting payment for existing purchase");
const ctx = new PayMerchantTransactionContext(
@@ -2809,6 +2810,18 @@ export async function confirmPay(
logger.trace("confirmPay: purchase record does not exist yet");
const contractTerms = d.contractTerms;
+
+ if (
+ choiceIndex == null &&
+ contractTerms.version === MerchantContractVersion.V1 &&
+ !wex.ws.config.features.enableV1Contracts
+ ) {
+ choiceIndex = ContractTermsUtil.getV0CompatChoiceIndex(contractTerms);
+ if (choiceIndex == null) {
+ throw Error("unable to confirm payment, contracts v1 support required");
+ }
+ }
+
const { available, amountRaw, maxFee } = ContractTermsUtil.extractAmounts(
contractTerms,
choiceIndex,