aboutsummaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-06-14 19:37:35 +0200
committerFlorian Dold <florian@dold.me>2021-06-14 19:37:35 +0200
commitef636c022bb6f8017ef237a5e6468f5c449665ad (patch)
tree7c7f0fa083a4c02f8d3fb0711b2bd7781cd80879 /packages
parentb4f97f4592cbab6632aff4f1ea4bedccdbf00d3a (diff)
implement force-retrying transactions
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-util/src/walletTypes.ts9
-rw-r--r--packages/taler-wallet-core/src/crypto/primitives/nacl-fast.ts12
-rw-r--r--packages/taler-wallet-core/src/operations/transactions.ts45
-rw-r--r--packages/taler-wallet-core/src/wallet.ts8
4 files changed, 69 insertions, 5 deletions
diff --git a/packages/taler-util/src/walletTypes.ts b/packages/taler-util/src/walletTypes.ts
index 10dbf75eb..6a0c57139 100644
--- a/packages/taler-util/src/walletTypes.ts
+++ b/packages/taler-util/src/walletTypes.ts
@@ -949,7 +949,16 @@ export interface DeleteTransactionRequest {
transactionId: string;
}
+export interface RetryTransactionRequest {
+ transactionId: string;
+}
+
export const codecForDeleteTransactionRequest = (): Codec<DeleteTransactionRequest> =>
buildCodecForObject<DeleteTransactionRequest>()
.property("transactionId", codecForString())
.build("DeleteTransactionRequest");
+
+export const codecForRetryTransactionRequest = (): Codec<RetryTransactionRequest> =>
+ buildCodecForObject<RetryTransactionRequest>()
+ .property("transactionId", codecForString())
+ .build("RetryTransactionRequest");
diff --git a/packages/taler-wallet-core/src/crypto/primitives/nacl-fast.ts b/packages/taler-wallet-core/src/crypto/primitives/nacl-fast.ts
index 711c83ec6..eab4a2e5c 100644
--- a/packages/taler-wallet-core/src/crypto/primitives/nacl-fast.ts
+++ b/packages/taler-wallet-core/src/crypto/primitives/nacl-fast.ts
@@ -5,11 +5,15 @@
// Implementation derived from TweetNaCl version 20140427.
// See for details: http://tweetnacl.cr.yp.to/
-import { createRequire } from "module";
+import * as mod from "module";
-// We need this require function to synchronously
-// import the "crypto" module in the CSPRNG initialization.
-const require = createRequire(import.meta.url);
+let require: any;
+
+if (typeof require !== "function" && mod.default && mod.default.createRequire) {
+ // We need this require function to synchronously
+ // import the "crypto" module in the CSPRNG initialization.
+ require = mod.default.createRequire(import.meta.url);
+}
const gf = function (init: number[] = []): Float64Array {
const r = new Float64Array(16);
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts
index 3d9f1be41..1b2c8477f 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -38,6 +38,11 @@ import {
} from "@gnu-taler/taler-util";
import { getFundingPaytoUris } from "./reserves.js";
import { getExchangeDetails } from "./exchanges.js";
+import { processWithdrawGroup } from "./withdraw.js";
+import { processPurchasePay } from "./pay.js";
+import { processDepositGroup } from "./deposits.js";
+import { processTip } from "./tip.js";
+import { processRefreshGroup } from "./refresh.js";
/**
* Create an event ID from the type and the primary key for the event.
@@ -399,6 +404,46 @@ export enum TombstoneTag {
}
/**
+ * Immediately retry the underlying operation
+ * of a transaction.
+ */
+export async function retryTransaction(
+ ws: InternalWalletState,
+ transactionId: string,
+): Promise<void> {
+ const [type, ...rest] = transactionId.split(":");
+
+ switch (type) {
+ case TransactionType.Deposit:
+ const depositGroupId = rest[0];
+ processDepositGroup(ws, depositGroupId, true);
+ break;
+ case TransactionType.Withdrawal: {
+ const withdrawalGroupId = rest[0];
+ await processWithdrawGroup(ws, withdrawalGroupId, true);
+ break;
+ }
+ case TransactionType.Payment: {
+ const proposalId = rest[0]
+ await processPurchasePay(ws, proposalId, true);
+ break;
+ }
+ case TransactionType.Tip: {
+ const walletTipId = rest[0];
+ await processTip(ws, walletTipId, true);
+ break;
+ }
+ case TransactionType.Refresh: {
+ const refreshGroupId = rest[0];
+ await processRefreshGroup(ws, refreshGroupId, true);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
* Permanently delete a transaction based on the transaction ID.
*/
export async function deleteTransaction(
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 900a2e779..33e431f37 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -26,6 +26,7 @@ import {
BackupRecovery,
codecForAny,
codecForDeleteTransactionRequest,
+ codecForRetryTransactionRequest,
DeleteTransactionRequest,
durationFromSpec,
durationMax,
@@ -103,7 +104,7 @@ import {
withdrawTestBalance,
} from "./operations/testing";
import { acceptTip, prepareTip, processTip } from "./operations/tip";
-import { deleteTransaction, getTransactions } from "./operations/transactions";
+import { deleteTransaction, getTransactions, retryTransaction } from "./operations/transactions";
import {
getExchangeWithdrawalInfo,
getWithdrawalDetailsForUri,
@@ -1194,6 +1195,11 @@ export class Wallet {
await deleteTransaction(this.ws, req.transactionId);
return {};
}
+ case "retryTransaction": {
+ const req = codecForRetryTransactionRequest().decode(payload);
+ await retryTransaction(this.ws, req.transactionId);
+ return {};
+ }
}
throw OperationFailedError.fromCode(
TalerErrorCode.WALLET_CORE_API_OPERATION_UNKNOWN,