summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-05-24 14:20:48 +0200
committerFlorian Dold <florian@dold.me>2023-05-24 14:20:48 +0200
commitf475f98f86d03e808d2c88c13eafa712c2013fe3 (patch)
tree41bf18a150d4ae8cbe9f1ec33d72634ad1bf5e9e
parentf14c7e5f2a1495613c16bcf1acf74d08fd91fb48 (diff)
downloadwallet-core-f475f98f86d03e808d2c88c13eafa712c2013fe3.tar.gz
wallet-core-f475f98f86d03e808d2c88c13eafa712c2013fe3.tar.bz2
wallet-core-f475f98f86d03e808d2c88c13eafa712c2013fe3.zip
wallet-core: fix getTransactionById for refunds
-rw-r--r--packages/taler-util/src/transactions-types.ts43
-rw-r--r--packages/taler-wallet-core/src/operations/transactions.ts71
2 files changed, 91 insertions, 23 deletions
diff --git a/packages/taler-util/src/transactions-types.ts b/packages/taler-util/src/transactions-types.ts
index aaf527b89..30178b7c7 100644
--- a/packages/taler-util/src/transactions-types.ts
+++ b/packages/taler-util/src/transactions-types.ts
@@ -203,10 +203,12 @@ export type Transaction =
| TransactionPeerPullCredit
| TransactionPeerPullDebit
| TransactionPeerPushCredit
- | TransactionPeerPushDebit;
+ | TransactionPeerPushDebit
+ | TransactionInternalWithdrawal;
export enum TransactionType {
Withdrawal = "withdrawal",
+ InternalWithdrawal = "internal-withdrawal",
Payment = "payment",
Refund = "refund",
Refresh = "refresh",
@@ -271,8 +273,9 @@ interface WithdrawalDetailsForTalerBankIntegrationApi {
reserveIsReady: boolean;
}
-// This should only be used for actual withdrawals
-// and not for tips that have their own transactions type.
+/**
+ * A withdrawal transaction (either bank-integrated or manual).
+ */
export interface TransactionWithdrawal extends TransactionCommon {
type: TransactionType.Withdrawal;
@@ -294,6 +297,40 @@ export interface TransactionWithdrawal extends TransactionCommon {
withdrawalDetails: WithdrawalDetails;
}
+/**
+ * Internal withdrawal operation, only reported on request.
+ *
+ * Some transactions (peer-*-credit) internally do a withdrawal,
+ * but only the peer-*-credit transaction is reported.
+ *
+ * The internal withdrawal transaction allows to access the details of
+ * the underlying withdrawal for testing/debugging.
+ *
+ * It is usually not reported, so that amounts of transactions properly
+ * add up, since the amountEffecive of the withdrawal is already reported
+ * in the peer-*-credit transaction.
+ */
+export interface TransactionInternalWithdrawal extends TransactionCommon {
+ type: TransactionType.InternalWithdrawal;
+
+ /**
+ * Exchange of the withdrawal.
+ */
+ exchangeBaseUrl: string;
+
+ /**
+ * Amount that got subtracted from the reserve balance.
+ */
+ amountRaw: AmountString;
+
+ /**
+ * Amount that actually was (or will be) added to the wallet's balance.
+ */
+ amountEffective: AmountString;
+
+ withdrawalDetails: WithdrawalDetails;
+}
+
export interface PeerInfoShort {
expiration: TalerProtocolTimestamp | undefined;
summary: string | undefined;
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts
index 2e42eb8d8..b5a6ba74e 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -111,6 +111,7 @@ import {
computeWithdrawalTransactionStatus,
processWithdrawalGroup,
} from "./withdraw.js";
+import { GetReadOnlyAccess, WalletStoresV1 } from "../index.js";
const logger = new Logger("taler-wallet-core:transactions.ts");
@@ -155,6 +156,7 @@ const txOrder: { [t in TransactionType]: number } = {
[TransactionType.Deposit]: 9,
[TransactionType.Refresh]: 10,
[TransactionType.Tip]: 11,
+ [TransactionType.InternalWithdrawal]: 12,
};
export async function getTransactionById(
@@ -271,9 +273,23 @@ export async function getTransactionById(
});
}
- case TransactionType.Refund:
- // FIXME!
- throw Error("not implemented");
+ case TransactionType.Refund: {
+ return await ws.db
+ .mktx((x) => [x.refundGroups, x.contractTerms, x.purchases])
+ .runReadOnly(async (tx) => {
+ const refundRecord = await tx.refundGroups.get(
+ parsedTx.refundGroupId,
+ );
+ if (!refundRecord) {
+ throw Error("not found");
+ }
+ const contractData = await lookupMaybeContractData(
+ tx,
+ refundRecord?.proposalId,
+ );
+ return buildTransactionForRefund(refundRecord, contractData);
+ });
+ }
case TransactionType.PeerPullDebit: {
return await ws.db
.mktx((x) => [x.peerPullPaymentIncoming])
@@ -829,6 +845,33 @@ function buildTransactionForTip(
};
}
+async function lookupMaybeContractData(
+ tx: GetReadOnlyAccess<{
+ purchases: typeof WalletStoresV1.purchases;
+ contractTerms: typeof WalletStoresV1.contractTerms;
+ }>,
+ proposalId: string,
+): Promise<WalletContractData | undefined> {
+ let contractData: WalletContractData | undefined = undefined;
+ const purchaseTx = await tx.purchases.get(proposalId);
+ if (purchaseTx && purchaseTx.download) {
+ const download = purchaseTx.download;
+ const contractTermsRecord = await tx.contractTerms.get(
+ download.contractTermsHash,
+ );
+ if (!contractTermsRecord) {
+ return;
+ }
+ contractData = extractContractData(
+ contractTermsRecord?.contractTermsRaw,
+ download.contractTermsHash,
+ download.contractTermsMerchantSig,
+ );
+ }
+
+ return contractData;
+}
+
async function buildTransactionForPurchase(
purchaseRecord: PurchaseRecord,
contractData: WalletContractData,
@@ -1061,22 +1104,10 @@ export async function getTransactions(
if (shouldSkipCurrency(transactionsRequest, currency)) {
return;
}
- let contractData: WalletContractData | undefined = undefined;
- const purchaseTx = await tx.purchases.get(refundGroup.proposalId);
- if (purchaseTx && purchaseTx.download) {
- const download = purchaseTx.download;
- const contractTermsRecord = await tx.contractTerms.get(
- download.contractTermsHash,
- );
- if (!contractTermsRecord) {
- return;
- }
- contractData = extractContractData(
- contractTermsRecord?.contractTermsRaw,
- download.contractTermsHash,
- download.contractTermsMerchantSig,
- );
- }
+ const contractData = await lookupMaybeContractData(
+ tx,
+ refundGroup.proposalId,
+ );
transactions.push(buildTransactionForRefund(refundGroup, contractData));
});
@@ -1704,7 +1735,7 @@ export async function deleteTransaction(
}
});
- return;
+ return;
}
case TransactionType.PeerPushDebit: {