gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: wallet-core: put contract ter


From: gnunet
Subject: [taler-wallet-core] branch master updated: wallet-core: put contract terms into separate object store
Date: Sun, 09 Oct 2022 02:23:09 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 19f3e6321 wallet-core: put contract terms into separate object store
19f3e6321 is described below

commit 19f3e6321d68adbaf9e8ca2d03efac6706d3fdea
Author: Florian Dold <florian@dold.me>
AuthorDate: Sun Oct 9 02:23:06 2022 +0200

    wallet-core: put contract terms into separate object store
---
 packages/taler-util/src/backupTypes.ts             |   2 +
 packages/taler-wallet-core/src/db.ts               |  47 ++++++----
 .../src/operations/backup/export.ts                |  17 +++-
 .../src/operations/backup/import.ts                |  47 +++-------
 .../src/operations/pay-merchant.ts                 | 102 ++++++++++++++-------
 .../src/operations/transactions.ts                 |  78 +++++++++++-----
 6 files changed, 183 insertions(+), 110 deletions(-)

diff --git a/packages/taler-util/src/backupTypes.ts 
b/packages/taler-util/src/backupTypes.ts
index 777086599..620f476ad 100644
--- a/packages/taler-util/src/backupTypes.ts
+++ b/packages/taler-util/src/backupTypes.ts
@@ -909,6 +909,8 @@ export interface BackupPurchase {
 
   /**
    * Signature on the contract terms.
+   * 
+   * FIXME: Better name needed.
    */
   merchant_sig?: string;
 
diff --git a/packages/taler-wallet-core/src/db.ts 
b/packages/taler-wallet-core/src/db.ts
index b019be67a..ec11f4d47 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -1085,18 +1085,16 @@ export enum PurchaseStatus {
   Paid = OperationStatusRange.DORMANT_START + 5,
 }
 
+/**
+ * Partial information about the downloaded proposal.
+ * Only contains data that is relevant for indexing on the
+ * "purchases" object stores.
+ */
 export interface ProposalDownload {
-  /**
-   * The contract that was offered by the merchant.
-   */
-  contractTermsRaw: any;
-
-  /**
-   * Extracted / parsed data from the contract terms.
-   *
-   * FIXME: Do we need to store *all* that data in duplicate?
-   */
-  contractData: WalletContractData;
+  contractTermsHash: string;
+  fulfillmentUrl?: string;
+  currency: string;
+  contractTermsMerchantSig: string;
 }
 
 export interface PurchasePayInfo {
@@ -1723,6 +1721,7 @@ export interface PeerPullPaymentInitiationRecord {
    * Contract terms for the other party.
    *
    * FIXME: Nail down type!
+   * FIXME: Put in contractTerms store
    */
   contractTerms: any;
 }
@@ -1819,6 +1818,18 @@ export interface CoinAvailabilityRecord {
   freshCoinCount: number;
 }
 
+export interface ContractTermsRecord {
+  /**
+   * Contract terms hash.
+   */
+  h: string;
+
+  /**
+   * Contract terms JSON.
+   */
+  contractTermsRaw: any;
+}
+
 /**
  * Schema definition for the IndexedDB
  * wallet database.
@@ -1937,13 +1948,8 @@ export const WalletStoresV1 = {
       byStatus: describeIndex("byStatus", "purchaseStatus"),
       byFulfillmentUrl: describeIndex(
         "byFulfillmentUrl",
-        "download.contractData.fulfillmentUrl",
+        "download.fulfillmentUrl",
       ),
-      // FIXME: Deduplicate!
-      byMerchantUrlAndOrderId: describeIndex("byMerchantUrlAndOrderId", [
-        "download.contractData.merchantBaseUrl",
-        "download.contractData.orderId",
-      ]),
       byUrlAndOrderId: describeIndex("byUrlAndOrderId", [
         "merchantBaseUrl",
         "orderId",
@@ -2088,6 +2094,13 @@ export const WalletStoresV1 = {
     }),
     {},
   ),
+  contractTerms: describeStore(
+    "contractTerms",
+    describeContents<ContractTermsRecord>({
+      keyPath: "h",
+    }),
+    {},
+  ),
 };
 
 /**
diff --git a/packages/taler-wallet-core/src/operations/backup/export.ts 
b/packages/taler-wallet-core/src/operations/backup/export.ts
index d16b344f6..2e2a1c4b4 100644
--- a/packages/taler-wallet-core/src/operations/backup/export.ts
+++ b/packages/taler-wallet-core/src/operations/backup/export.ts
@@ -88,6 +88,7 @@ export async function exportBackup(
       x.exchanges,
       x.exchangeDetails,
       x.coins,
+      x.contractTerms,
       x.denominations,
       x.purchases,
       x.refreshGroups,
@@ -353,7 +354,7 @@ export async function exportBackup(
 
       const purchaseProposalIdSet = new Set<string>();
 
-      await tx.purchases.iter().forEach((purch) => {
+      await tx.purchases.iter().forEachAsync(async (purch) => {
         const refunds: BackupRefundItem[] = [];
         purchaseProposalIdSet.add(purch.proposalId);
         for (const refundKey of Object.keys(purch.refunds)) {
@@ -418,8 +419,18 @@ export async function exportBackup(
           };
         }
 
+        let contractTermsRaw = undefined;
+        if (purch.download) {
+          const contractTermsRecord = await tx.contractTerms.get(
+            purch.download.contractTermsHash,
+          );
+          if (contractTermsRecord) {
+            contractTermsRaw = contractTermsRecord.contractTermsRaw;
+          }
+        }
+
         backupPurchases.push({
-          contract_terms_raw: purch.download?.contractTermsRaw,
+          contract_terms_raw: contractTermsRaw,
           auto_refund_deadline: purch.autoRefundDeadline,
           merchant_pay_sig: purch.merchantPaySig,
           pay_info: backupPayInfo,
@@ -428,7 +439,7 @@ export async function exportBackup(
           timestamp_accepted: purch.timestampAccept,
           timestamp_first_successful_pay: purch.timestampFirstSuccessfulPay,
           nonce_priv: purch.noncePriv,
-          merchant_sig: purch.download?.contractData.merchantSig,
+          merchant_sig: purch.download?.contractTermsMerchantSig,
           claim_token: purch.claimToken,
           merchant_base_url: purch.merchantBaseUrl,
           order_id: purch.orderId,
diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts 
b/packages/taler-wallet-core/src/operations/backup/import.ts
index bb5fe56e2..3ee3680fe 100644
--- a/packages/taler-wallet-core/src/operations/backup/import.ts
+++ b/packages/taler-wallet-core/src/operations/backup/import.ts
@@ -64,6 +64,7 @@ import { checkLogicInvariant } from 
"../../util/invariants.js";
 import { GetReadOnlyAccess, GetReadWriteAccess } from "../../util/query.js";
 import { makeCoinAvailable, makeEventId, TombstoneTag } from "../common.js";
 import { getExchangeDetails } from "../exchanges.js";
+import { extractContractData } from "../pay-merchant.js";
 import { provideBackupState } from "./state.js";
 
 const logger = new Logger("operations/backup/import.ts");
@@ -630,49 +631,25 @@ export async function importBackup(
             maxWireFee = Amounts.getZero(amount.currency);
           }
           const download: ProposalDownload = {
-            contractData: {
-              amount,
-              contractTermsHash: contractTermsHash,
-              fulfillmentUrl: parsedContractTerms.fulfillment_url ?? "",
-              merchantBaseUrl: parsedContractTerms.merchant_base_url,
-              merchantPub: parsedContractTerms.merchant_pub,
-              merchantSig: backupPurchase.merchant_sig!,
-              orderId: parsedContractTerms.order_id,
-              summary: parsedContractTerms.summary,
-              autoRefund: parsedContractTerms.auto_refund,
-              maxWireFee,
-              payDeadline: parsedContractTerms.pay_deadline,
-              refundDeadline: parsedContractTerms.refund_deadline,
-              wireFeeAmortization:
-                parsedContractTerms.wire_fee_amortization || 1,
-              allowedAuditors: parsedContractTerms.auditors.map((x) => ({
-                auditorBaseUrl: x.url,
-                auditorPub: x.auditor_pub,
-              })),
-              allowedExchanges: parsedContractTerms.exchanges.map((x) => ({
-                exchangeBaseUrl: x.url,
-                exchangePub: x.master_pub,
-              })),
-              timestamp: parsedContractTerms.timestamp,
-              wireMethod: parsedContractTerms.wire_method,
-              wireInfoHash: parsedContractTerms.h_wire,
-              maxDepositFee: Amounts.parseOrThrow(parsedContractTerms.max_fee),
-              merchant: parsedContractTerms.merchant,
-              products: parsedContractTerms.products,
-              summaryI18n: parsedContractTerms.summary_i18n,
-              deliveryDate: parsedContractTerms.delivery_date,
-              deliveryLocation: parsedContractTerms.delivery_location,
-            },
-            contractTermsRaw: backupPurchase.contract_terms_raw,
+            contractTermsHash,
+            contractTermsMerchantSig: backupPurchase.merchant_sig!,
+            currency: amount.currency,
+            fulfillmentUrl: backupPurchase.contract_terms_raw.fulfillment_url,
           };
 
+          const contractData = extractContractData(
+            backupPurchase.contract_terms_raw,
+            contractTermsHash,
+            download.contractTermsMerchantSig,
+          );
+
           let payInfo: PurchasePayInfo | undefined = undefined;
           if (backupPurchase.pay_info) {
             payInfo = {
               coinDepositPermissions: undefined,
               payCoinSelection: await recoverPayCoinSelection(
                 tx,
-                download.contractData,
+                contractData,
                 backupPurchase.pay_info,
               ),
               payCoinSelectionUid: backupPurchase.pay_info.pay_coins_uid,
diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts 
b/packages/taler-wallet-core/src/operations/pay-merchant.ts
index d590177c2..e805c0ea1 100644
--- a/packages/taler-wallet-core/src/operations/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts
@@ -115,6 +115,7 @@ import {
   throwUnexpectedRequestError,
 } from "../util/http.js";
 import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
+import { GetReadOnlyAccess } from "../util/query.js";
 import {
   OperationAttemptResult,
   OperationAttemptResultType,
@@ -256,12 +257,34 @@ function getPayRequestTimeout(purchase: PurchaseRecord): 
Duration {
  * (Async since in the future this will query the DB.)
  */
 export async function expectProposalDownload(
+  ws: InternalWalletState,
   p: PurchaseRecord,
-): Promise<ProposalDownload> {
+): Promise<{
+  contractData: WalletContractData;
+  contractTermsRaw: any;
+}> {
   if (!p.download) {
     throw Error("expected proposal to be downloaded");
   }
-  return p.download;
+  const download = p.download;
+  return await ws.db
+    .mktx((x) => [x.contractTerms])
+    .runReadOnly(async (tx) => {
+      const contractTerms = await tx.contractTerms.get(
+        download.contractTermsHash,
+      );
+      if (!contractTerms) {
+        throw Error("contract terms not found");
+      }
+      return {
+        contractData: extractContractData(
+          contractTerms.contractTermsRaw,
+          download.contractTermsHash,
+          download.contractTermsMerchantSig,
+        ),
+        contractTermsRaw: contractTerms.contractTermsRaw,
+      };
+    });
 }
 
 export function extractContractData(
@@ -494,7 +517,7 @@ export async function processDownloadProposal(
   logger.trace(`extracted contract data: ${j2s(contractData)}`);
 
   await ws.db
-    .mktx((x) => [x.purchases])
+    .mktx((x) => [x.purchases, x.contractTerms])
     .runReadWrite(async (tx) => {
       const p = await tx.purchases.get(proposalId);
       if (!p) {
@@ -504,9 +527,15 @@ export async function processDownloadProposal(
         return;
       }
       p.download = {
-        contractData,
-        contractTermsRaw: proposalResp.contract_terms,
+        contractTermsHash,
+        contractTermsMerchantSig: contractData.merchantSig,
+        currency: contractData.amount.currency,
+        fulfillmentUrl: contractData.fulfillmentUrl,
       };
+      await tx.contractTerms.put({
+        h: contractTermsHash,
+        contractTermsRaw: proposalResp.contract_terms,
+      });
       if (
         fulfillmentUrl &&
         (fulfillmentUrl.startsWith("http://";) ||
@@ -636,7 +665,7 @@ async function storeFirstPaySuccess(
 ): Promise<void> {
   const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
   await ws.db
-    .mktx((x) => [x.purchases])
+    .mktx((x) => [x.purchases, x.contractTerms])
     .runReadWrite(async (tx) => {
       const purchase = await tx.purchases.get(proposalId);
 
@@ -655,7 +684,18 @@ async function storeFirstPaySuccess(
       purchase.timestampFirstSuccessfulPay = now;
       purchase.lastSessionId = sessionId;
       purchase.merchantPaySig = paySig;
-      const protoAr = purchase.download!.contractData.autoRefund;
+      const dl = purchase.download;
+      checkDbInvariant(!!dl);
+      const contractTermsRecord = await tx.contractTerms.get(
+        dl.contractTermsHash,
+      );
+      checkDbInvariant(!!contractTermsRecord);
+      const contractData = extractContractData(
+        contractTermsRecord.contractTermsRaw,
+        dl.contractTermsHash,
+        dl.contractTermsMerchantSig,
+      );
+      const protoAr = contractData.autoRefund;
       if (protoAr) {
         const ar = Duration.fromTalerProtocolDuration(protoAr);
         logger.info("auto_refund present");
@@ -739,7 +779,7 @@ async function handleInsufficientFunds(
     throw new TalerProtocolViolationError();
   }
 
-  const { contractData } = proposal.download!;
+  const { contractData } = await expectProposalDownload(ws, proposal);
 
   const prevPayCoins: PreviousPayCoins = [];
 
@@ -1254,11 +1294,7 @@ export async function checkPaymentByProposalId(
       throw Error("existing proposal is in wrong state");
     }
   }
-  const d = proposal.download;
-  if (!d) {
-    logger.error("bad proposal", proposal);
-    throw Error("proposal is in invalid state");
-  }
+  const d = await expectProposalDownload(ws, proposal);
   const contractData = d.contractData;
   const merchantSig = d.contractData.merchantSig;
   if (!merchantSig) {
@@ -1338,7 +1374,7 @@ export async function checkPaymentByProposalId(
       // FIXME: This does not surface the original error
       throw Error("submitting pay failed");
     }
-    const download = await expectProposalDownload(purchase);
+    const download = await expectProposalDownload(ws, purchase);
     return {
       status: PreparePayResultType.AlreadyConfirmed,
       contractTerms: download.contractTermsRaw,
@@ -1349,7 +1385,7 @@ export async function checkPaymentByProposalId(
       proposalId,
     };
   } else if (!purchase.timestampFirstSuccessfulPay) {
-    const download = await expectProposalDownload(purchase);
+    const download = await expectProposalDownload(ws, purchase);
     return {
       status: PreparePayResultType.AlreadyConfirmed,
       contractTerms: download.contractTermsRaw,
@@ -1364,7 +1400,7 @@ export async function checkPaymentByProposalId(
       purchase.purchaseStatus === PurchaseStatus.Paid ||
       purchase.purchaseStatus === PurchaseStatus.QueryingRefund ||
       purchase.purchaseStatus === PurchaseStatus.QueryingAutoRefund;
-    const download = await expectProposalDownload(purchase);
+    const download = await expectProposalDownload(ws, purchase);
     return {
       status: PreparePayResultType.AlreadyConfirmed,
       contractTerms: download.contractTermsRaw,
@@ -1392,11 +1428,9 @@ export async function getContractTermsDetails(
     throw Error(`proposal with id ${proposalId} not found`);
   }
 
-  if (!proposal.download || !proposal.download.contractData) {
-    throw Error("proposal is in invalid state");
-  }
+  const d = await expectProposalDownload(ws, proposal);
 
-  return proposal.download.contractData;
+  return d.contractData;
 }
 
 /**
@@ -1516,12 +1550,13 @@ export async function runPayForConfirmPay(
         .runReadOnly(async (tx) => {
           return tx.purchases.get(proposalId);
         });
-      if (!purchase?.download) {
+      if (!purchase) {
         throw Error("purchase record not available anymore");
       }
+      const d = await expectProposalDownload(ws, purchase);
       return {
         type: ConfirmPayResultType.Done,
-        contractTerms: purchase.download.contractTermsRaw,
+        contractTerms: d.contractTermsRaw,
         transactionId: makeEventId(TransactionType.Payment, proposalId),
       };
     }
@@ -1599,7 +1634,7 @@ export async function confirmPay(
     throw Error(`proposal with id ${proposalId} not found`);
   }
 
-  const d = proposal.download;
+  const d = await expectProposalDownload(ws, proposal);
   if (!d) {
     throw Error("proposal is in invalid state");
   }
@@ -1810,7 +1845,7 @@ export async function processPurchasePay(
   const payInfo = purchase.payInfo;
   checkDbInvariant(!!payInfo, "payInfo");
 
-  const download = await expectProposalDownload(purchase);
+  const download = await expectProposalDownload(ws, purchase);
   if (!purchase.merchantPaySig) {
     const payUrl = new URL(
       `orders/${download.contractData.orderId}/pay`,
@@ -2007,7 +2042,7 @@ export async function prepareRefund(
   const purchase = await ws.db
     .mktx((x) => [x.purchases])
     .runReadOnly(async (tx) => {
-      return tx.purchases.indexes.byMerchantUrlAndOrderId.get([
+      return tx.purchases.indexes.byUrlAndOrderId.get([
         parseResult.merchantBaseUrl,
         parseResult.orderId,
       ]);
@@ -2020,10 +2055,10 @@ export async function prepareRefund(
   }
 
   const awaiting = await queryAndSaveAwaitingRefund(ws, purchase);
-  const summary = await calculateRefundSummary(purchase);
+  const summary = await calculateRefundSummary(ws, purchase);
   const proposalId = purchase.proposalId;
 
-  const { contractData: c } = await expectProposalDownload(purchase);
+  const { contractData: c } = await expectProposalDownload(ws, purchase);
 
   return {
     proposalId,
@@ -2380,9 +2415,10 @@ async function acceptRefunds(
 }
 
 async function calculateRefundSummary(
+  ws: InternalWalletState,
   p: PurchaseRecord,
 ): Promise<RefundSummary> {
-  const download = await expectProposalDownload(p);
+  const download = await expectProposalDownload(ws, p);
   let amountRefundGranted = Amounts.getZero(
     download.contractData.amount.currency,
   );
@@ -2456,7 +2492,7 @@ export async function applyRefund(
   const purchase = await ws.db
     .mktx((x) => [x.purchases])
     .runReadOnly(async (tx) => {
-      return tx.purchases.indexes.byMerchantUrlAndOrderId.get([
+      return tx.purchases.indexes.byUrlAndOrderId.get([
         parseResult.merchantBaseUrl,
         parseResult.orderId,
       ]);
@@ -2513,8 +2549,8 @@ export async function applyRefundFromPurchaseId(
     throw Error("purchase no longer exists");
   }
 
-  const summary = await calculateRefundSummary(purchase);
-  const download = await expectProposalDownload(purchase);
+  const summary = await calculateRefundSummary(ws, purchase);
+  const download = await expectProposalDownload(ws, purchase);
 
   return {
     contractTermsHash: download.contractData.contractTermsHash,
@@ -2542,7 +2578,7 @@ async function queryAndSaveAwaitingRefund(
   purchase: PurchaseRecord,
   waitForAutoRefund?: boolean,
 ): Promise<AmountJson> {
-  const download = await expectProposalDownload(purchase);
+  const download = await expectProposalDownload(ws, purchase);
   const requestUrl = new URL(
     `orders/${download.contractData.orderId}`,
     download.contractData.merchantBaseUrl,
@@ -2621,7 +2657,7 @@ export async function processPurchaseQueryRefund(
     return OperationAttemptResult.finishedEmpty();
   }
 
-  const download = await expectProposalDownload(purchase);
+  const download = await expectProposalDownload(ws, purchase);
 
   if (purchase.timestampFirstSuccessfulPay) {
     if (
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts 
b/packages/taler-wallet-core/src/operations/transactions.ts
index d8069436a..6955d7b17 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -48,6 +48,7 @@ import {
   WalletRefundItem,
   WithdrawalGroupRecord,
   WithdrawalRecordType,
+  WalletContractData,
 } from "../db.js";
 import { InternalWalletState } from "../internal-wallet-state.js";
 import { checkDbInvariant } from "../util/invariants.js";
@@ -55,7 +56,11 @@ import { RetryTags } from "../util/retries.js";
 import { makeEventId, TombstoneTag } from "./common.js";
 import { processDepositGroup } from "./deposits.js";
 import { getExchangeDetails } from "./exchanges.js";
-import { expectProposalDownload, processPurchasePay } from "./pay-merchant.js";
+import {
+  expectProposalDownload,
+  extractContractData,
+  processPurchasePay,
+} from "./pay-merchant.js";
 import { processRefreshGroup } from "./refresh.js";
 import { processTip } from "./tip.js";
 import {
@@ -199,7 +204,7 @@ export async function getTransactionById(
           }),
         );
 
-        const download = await expectProposalDownload(purchase);
+        const download = await expectProposalDownload(ws, purchase);
 
         const cleanRefunds = filteredRefunds.filter(
           (x): x is WalletRefundItem => !!x,
@@ -214,7 +219,12 @@ export async function getTransactionById(
         const payOpId = RetryTags.forPay(purchase);
         const payRetryRecord = await tx.operationRetries.get(payOpId);
 
-        return buildTransactionForPurchase(purchase, refunds, payRetryRecord);
+        return buildTransactionForPurchase(
+          purchase,
+          contractData,
+          refunds,
+          payRetryRecord,
+        );
       });
   } else if (type === TransactionType.Refresh) {
     const refreshGroupId = rest[0];
@@ -268,14 +278,19 @@ export async function getTransactionById(
           ),
         );
         if (t) throw Error("deleted");
-        const download = await expectProposalDownload(purchase);
+        const download = await expectProposalDownload(ws, purchase);
         const contractData = download.contractData;
         const refunds = mergeRefundByExecutionTime(
           [theRefund],
           Amounts.getZero(contractData.amount.currency),
         );
 
-        return buildTransactionForRefund(purchase, refunds[0], undefined);
+        return buildTransactionForRefund(
+          purchase,
+          contractData,
+          refunds[0],
+          undefined,
+        );
       });
   } else if (type === TransactionType.PeerPullDebit) {
     const peerPullPaymentIncomingId = rest[0];
@@ -572,12 +587,10 @@ function mergeRefundByExecutionTime(
 
 async function buildTransactionForRefund(
   purchaseRecord: PurchaseRecord,
+  contractData: WalletContractData,
   refundInfo: MergedRefundInfo,
   ort?: OperationRetryRecord,
 ): Promise<Transaction> {
-  const download = await expectProposalDownload(purchaseRecord);
-  const contractData = download.contractData;
-
   const info: OrderShortInfo = {
     merchant: contractData.merchant,
     orderId: contractData.orderId,
@@ -617,11 +630,10 @@ async function buildTransactionForRefund(
 
 async function buildTransactionForPurchase(
   purchaseRecord: PurchaseRecord,
+  contractData: WalletContractData,
   refundsInfo: MergedRefundInfo[],
   ort?: OperationRetryRecord,
 ): Promise<Transaction> {
-  const download = await expectProposalDownload(purchaseRecord);
-  const contractData = download.contractData;
   const zero = Amounts.getZero(contractData.amount.currency);
 
   const info: OrderShortInfo = {
@@ -689,7 +701,8 @@ async function buildTransactionForPurchase(
     proposalId: purchaseRecord.proposalId,
     info,
     frozen:
-      purchaseRecord.purchaseStatus === PurchaseStatus.PaymentAbortFinished ?? 
false,
+      purchaseRecord.purchaseStatus === PurchaseStatus.PaymentAbortFinished ??
+      false,
     ...(ort?.lastError ? { error: ort.lastError } : {}),
   };
 }
@@ -715,6 +728,7 @@ export async function getTransactions(
       x.peerPushPaymentInitiations,
       x.planchets,
       x.purchases,
+      x.contractTerms,
       x.recoupGroups,
       x.tips,
       x.tombstones,
@@ -814,19 +828,29 @@ export async function getTransactions(
         if (!purchase.payInfo) {
           return;
         }
-        if (
-          shouldSkipCurrency(
-            transactionsRequest,
-            download.contractData.amount.currency,
-          )
-        ) {
+        if (shouldSkipCurrency(transactionsRequest, download.currency)) {
           return;
         }
-        const contractData = download.contractData;
-        if (shouldSkipSearch(transactionsRequest, [contractData.summary])) {
+        const contractTermsRecord = await tx.contractTerms.get(
+          download.contractTermsHash,
+        );
+        if (!contractTermsRecord) {
+          return;
+        }
+        if (
+          shouldSkipSearch(transactionsRequest, [
+            contractTermsRecord?.contractTermsRaw?.summary || "",
+          ])
+        ) {
           return;
         }
 
+        const contractData = extractContractData(
+          contractTermsRecord?.contractTermsRaw,
+          download.contractTermsHash,
+          download.contractTermsMerchantSig,
+        );
+
         const filteredRefunds = await Promise.all(
           Object.values(purchase.refunds).map(async (r) => {
             const t = await tx.tombstones.get(
@@ -847,19 +871,29 @@ export async function getTransactions(
 
         const refunds = mergeRefundByExecutionTime(
           cleanRefunds,
-          Amounts.getZero(contractData.amount.currency),
+          Amounts.getZero(download.currency),
         );
 
         refunds.forEach(async (refundInfo) => {
           transactions.push(
-            await buildTransactionForRefund(purchase, refundInfo, undefined),
+            await buildTransactionForRefund(
+              purchase,
+              contractData,
+              refundInfo,
+              undefined,
+            ),
           );
         });
 
         const payOpId = RetryTags.forPay(purchase);
         const payRetryRecord = await tx.operationRetries.get(payOpId);
         transactions.push(
-          await buildTransactionForPurchase(purchase, refunds, payRetryRecord),
+          await buildTransactionForPurchase(
+            purchase,
+            contractData,
+            refunds,
+            payRetryRecord,
+          ),
         );
       });
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]