taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

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:
Mpackages/taler-harness/src/harness/environments.ts | 7++++++-
Mpackages/taler-harness/src/integrationtests/test-currency-scope.ts | 27++++++++++++++++++++++-----
Mpackages/taler-util/src/types-taler-wallet-transactions.ts | 5-----
Mpackages/taler-util/src/types-taler-wallet.ts | 2--
Mpackages/taler-wallet-core/src/exchanges.ts | 20+++++++++++++++-----
Mpackages/taler-wallet-core/src/pay-merchant.ts | 3+--
Mpackages/taler-wallet-webextension/src/wallet/History.stories.tsx | 22++++++----------------
Mpackages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx | 1-
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,