commit 6d338f433599d06e03e7763d7ae0c5f66462432a
parent e50a3787345426de5d0169573df2e93f5b2be8b4
Author: Florian Dold <florian@dold.me>
Date: Tue, 26 Nov 2024 15:52:05 +0100
wallet-core: fix handling of scope info in pay transactions
Diffstat:
8 files changed, 50 insertions(+), 37 deletions(-)
diff --git a/packages/taler-harness/src/harness/environments.ts b/packages/taler-harness/src/harness/environments.ts
@@ -44,6 +44,7 @@ import {
TalerCorebankApiClient,
TalerMerchantApi,
TalerProtocolTimestamp,
+ TransactionIdStr,
TransactionMajorState,
WalletNotification,
} from "@gnu-taler/taler-util";
@@ -951,7 +952,7 @@ export async function makeTestPaymentV2(
instance?: string;
},
auth: WithAuthorization = {},
-): Promise<void> {
+): Promise<{ transactionId: TransactionIdStr }> {
// Set up order.
const { walletClient, merchant, instance } = args;
@@ -997,6 +998,10 @@ export async function makeTestPaymentV2(
});
t.assertTrue(orderStatus.order_status === "paid");
+
+ return {
+ transactionId: preparePayResult.transactionId,
+ };
}
/**
diff --git a/packages/taler-harness/src/integrationtests/test-currency-scope.ts b/packages/taler-harness/src/integrationtests/test-currency-scope.ts
@@ -21,6 +21,11 @@ import { Duration, TalerCorebankApiClient, j2s } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { defaultCoinConfig } from "../harness/denomStructures.js";
import {
+ createWalletDaemonWithClient,
+ makeTestPaymentV2,
+ withdrawViaBankV3,
+} from "../harness/environments.js";
+import {
BankService,
ExchangeService,
GlobalTestState,
@@ -29,11 +34,6 @@ import {
getTestHarnessPaytoForLabel,
setupDb,
} from "../harness/harness.js";
-import {
- createWalletDaemonWithClient,
- withdrawViaBankV2,
- withdrawViaBankV3,
-} from "../harness/environments.js";
/**
* Run test for basic, bank-integrated withdrawal and payment.
@@ -220,6 +220,23 @@ export async function runCurrencyScopeTest(t: GlobalTestState) {
// Global currencies are merged
t.assertDeepEqual(bal2.balances.length, 1);
+
+ const payRes = await makeTestPaymentV2(t, {
+ merchant,
+ walletClient,
+ order: {
+ amount: "TESTKUDOS:10",
+ summary: "Test",
+ },
+ });
+
+ const payTx = await walletClient.call(WalletApiOperation.GetTransactionById, {
+ transactionId: payRes.transactionId,
+ });
+
+ console.log(`payment scopes: ${j2s(payTx.scopes)}`);
+
+ t.assertDeepEqual(payTx.scopes.length, 1);
}
runCurrencyScopeTest.suites = ["wallet"];
diff --git a/packages/taler-util/src/types-taler-wallet-transactions.ts b/packages/taler-util/src/types-taler-wallet-transactions.ts
@@ -634,11 +634,6 @@ export interface TransactionPayment extends TransactionCommon {
info: OrderShortInfo;
/**
- * Wallet-internal end-to-end identifier for the payment.
- */
- proposalId: string;
-
- /**
* Amount that must be paid for the contract
*/
amountRaw: AmountString;
diff --git a/packages/taler-util/src/types-taler-wallet.ts b/packages/taler-util/src/types-taler-wallet.ts
@@ -445,8 +445,6 @@ export type ScopeInfo = ScopeInfoGlobal | ScopeInfoExchange | ScopeInfoAuditor;
/**
* Shorter version of stringifyScopeInfo
- *
- * Format must be stable as it's used in the database.
*/
export function stringifyScopeInfoShort(si: ScopeInfo): string {
switch (si.type) {
diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts
@@ -110,6 +110,7 @@ import {
makeTalerErrorDetail,
parsePaytoUri,
stringifyReservePaytoUri,
+ stringifyScopeInfo,
} from "@gnu-taler/taler-util";
import {
HttpRequestLibrary,
@@ -307,11 +308,20 @@ export async function getScopeForAllExchanges(
>,
exs: string[],
): Promise<ScopeInfo[]> {
- const queries = exs.map((exchange) => {
- return getExchangeScopeInfoOrUndefined(tx, exchange);
- });
- const rs = await Promise.all(queries);
- return rs.filter((d): d is ScopeInfo => d !== undefined);
+ const scopes: ScopeInfo[] = [];
+ const scSet = new Set<string>();
+ for (const exchange of exs) {
+ const sc = await getExchangeScopeInfoOrUndefined(tx, exchange);
+ if (!sc) {
+ continue;
+ }
+ const scStr = stringifyScopeInfo(sc);
+ if (!scSet.has(scStr)) {
+ scSet.add(scStr);
+ scopes.push(sc);
+ }
+ }
+ return scopes;
}
export async function getExchangeScopeInfoOrUndefined(
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -279,7 +279,7 @@ export class PayMerchantTransactionContext implements TransactionContext {
return {
type: TransactionType.Payment,
txState,
- scopes: await getScopeForAllExchanges(
+ scopes: await getScopeForAllCoins(
tx,
!purchaseRec.payInfo.payCoinSelection
? []
@@ -303,7 +303,6 @@ export class PayMerchantTransactionContext implements TransactionContext {
tag: TransactionType.Payment,
proposalId: purchaseRec.proposalId,
}),
- proposalId: purchaseRec.proposalId,
abortReason: purchaseRec.abortReason,
info,
refundQueryActive:
diff --git a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx
@@ -39,8 +39,8 @@ import {
TransactionWithdrawal,
WithdrawalType,
} from "@gnu-taler/taler-util";
-import { HistoryView as TestedComponent } from "./History.js";
import * as tests from "@gnu-taler/web-util/testing";
+import { HistoryView as TestedComponent } from "./History.js";
export default {
title: "history",
@@ -94,7 +94,6 @@ const exampleData = {
refundPending: undefined,
totalRefundEffective: "USD:0" as AmountString,
totalRefundRaw: "USD:0" as AmountString,
- proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
status: PaymentStatus.Accepted,
refundQueryActive: false,
} as TransactionPayment,
@@ -174,7 +173,7 @@ export const SomeBalanceWithNoTransactions = tests.createExample(
type: ScopeType.Auditor,
url: "",
},
- balances: [
+ balances: [
{
available: "TESTKUDOS:10" as AmountString,
flags: [],
@@ -189,7 +188,6 @@ export const SomeBalanceWithNoTransactions = tests.createExample(
},
},
],
-
},
);
@@ -217,7 +215,6 @@ export const OneSimpleTransaction = tests.createExample(TestedComponent, {
},
},
],
-
});
export const TwoTransactionsAndZeroBalance = tests.createExample(
@@ -231,7 +228,7 @@ export const TwoTransactionsAndZeroBalance = tests.createExample(
type: ScopeType.Auditor,
url: "",
},
- balances: [
+ balances: [
{
flags: [],
available: "USD:0" as AmountString,
@@ -246,7 +243,6 @@ export const TwoTransactionsAndZeroBalance = tests.createExample(
},
},
],
-
},
);
@@ -281,7 +277,6 @@ export const OneTransactionPending = tests.createExample(TestedComponent, {
},
},
],
-
});
export const SomeTransactions = tests.createExample(TestedComponent, {
@@ -323,7 +318,6 @@ export const SomeTransactions = tests.createExample(TestedComponent, {
},
},
],
-
});
export const SomeTransactionsInDifferentStates = tests.createExample(
@@ -409,7 +403,7 @@ export const SomeTransactionsInDifferentStates = tests.createExample(
type: ScopeType.Auditor,
url: "",
},
- balances: [
+ balances: [
{
flags: [],
available: "USD:10" as AmountString,
@@ -424,7 +418,6 @@ export const SomeTransactionsInDifferentStates = tests.createExample(
},
},
],
-
},
);
@@ -447,7 +440,7 @@ export const SomeTransactionsWithTwoCurrencies = tests.createExample(
type: ScopeType.Auditor,
url: "",
},
- balances: [
+ balances: [
{
flags: [],
available: "USD:0" as AmountString,
@@ -475,7 +468,6 @@ export const SomeTransactionsWithTwoCurrencies = tests.createExample(
},
},
],
-
},
);
@@ -555,7 +547,6 @@ export const FiveOfficialCurrencies = tests.createExample(TestedComponent, {
},
},
],
-
});
export const FiveOfficialCurrenciesWithHighValue = tests.createExample(
@@ -569,7 +560,7 @@ export const FiveOfficialCurrenciesWithHighValue = tests.createExample(
type: ScopeType.Auditor,
url: "",
},
- balances: [
+ balances: [
{
flags: [],
available: "USD:881001321230000" as AmountString,
@@ -636,7 +627,6 @@ export const FiveOfficialCurrenciesWithHighValue = tests.createExample(
},
},
],
-
},
);
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
@@ -117,7 +117,6 @@ const exampleData = {
refundPending: undefined,
totalRefundEffective: "KUDOS:0" as AmountString,
totalRefundRaw: "KUDOS:0" as AmountString,
- proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
status: PaymentStatus.Accepted,
refundQueryActive: false,
} as TransactionPayment,