commit df794dd2e222863d4f15831fc2a9d5ea508792be
parent 1674a056768e19fb3f66e383674ae8a14c04cdd0
Author: Florian Dold <florian@dold.me>
Date: Fri, 22 Aug 2025 21:47:17 +0200
wallet-core: draft dev experiment to fake transactions
Diffstat:
1 file changed, 76 insertions(+), 0 deletions(-)
diff --git a/packages/taler-wallet-core/src/dev-experiments.ts b/packages/taler-wallet-core/src/dev-experiments.ts
@@ -26,7 +26,10 @@
*/
import {
+ AbsoluteTime,
+ Amounts,
DenomLossEventType,
+ Duration,
Logger,
RefreshReason,
TalerPreciseTimestamp,
@@ -45,12 +48,15 @@ import {
DenomLossStatus,
RefreshGroupRecord,
RefreshOperationStatus,
+ WithdrawalGroupStatus,
+ WithdrawalRecordType,
timestampPreciseToDb,
} from "./db.js";
import { DenomLossTransactionContext } from "./exchanges.js";
import { RefreshTransactionContext } from "./refresh.js";
import { rematerializeTransactions } from "./transactions.js";
import { DevExperimentState, WalletExecutionContext } from "./wallet.js";
+import { WithdrawTransactionContext } from "./withdraw.js";
const logger = new Logger("dev-experiments.ts");
@@ -200,6 +206,76 @@ export async function applyDevExperiment(
wex.ws.devExperimentState.fakeProtoVer?.delete(baseUrl);
return;
}
+ case "add-fake-tx": {
+ const txType = parsedUri.query?.get("txType") ?? "withdrawal";
+ const withdrawalGroupId = encodeCrock(getRandomBytes(32));
+ const ctx = new WithdrawTransactionContext(wex, withdrawalGroupId);
+ switch (txType) {
+ case "withdrawal": {
+ const secretSeed = encodeCrock(getRandomBytes(32));
+ const reservePair = await wex.ws.cryptoApi.createEddsaKeypair({});
+ const exchangeBaseUrl =
+ parsedUri.query?.get("exchangeBaseUrl") ??
+ "https://exchange.demo.taler.net/";
+ const trelStr = parsedUri.query?.get("tRel") ?? undefined;
+ const amountEffectiveStr = parsedUri.query?.get("amountEffective");
+ if (!amountEffectiveStr) {
+ throw Error("missing amountEffective option");
+ }
+ const amountEffective = Amounts.parseOrThrow(amountEffectiveStr);
+ let timestamp: AbsoluteTime;
+ if (trelStr) {
+ timestamp = AbsoluteTime.subtractDuraction(
+ AbsoluteTime.now(),
+ Duration.fromPrettyString(trelStr),
+ );
+ } else {
+ timestamp = AbsoluteTime.now();
+ }
+ await wex.db.runAllStoresReadWriteTx({}, async (tx) => {
+ await tx.withdrawalGroups.add({
+ denomSelUid: encodeCrock(getRandomBytes(32)),
+ reservePriv: reservePair.priv,
+ reservePub: reservePair.pub,
+ secretSeed,
+ status: WithdrawalGroupStatus.Done,
+ timestampStart: timestampPreciseToDb(
+ AbsoluteTime.toPreciseTimestamp(timestamp),
+ ),
+ timestampFinish: timestampPreciseToDb(
+ AbsoluteTime.toPreciseTimestamp(timestamp),
+ ),
+ withdrawalGroupId,
+ wgInfo: {
+ withdrawalType: WithdrawalRecordType.BankManual,
+ exchangeCreditAccounts: [
+ {
+ paytoUri: "payto://x-taler-bank/test/test",
+ status: "ok",
+ },
+ ],
+ },
+ denomsSel: {
+ totalCoinValue: Amounts.stringify(amountEffective),
+ hasDenomWithAgeRestriction: false,
+ totalWithdrawCost: Amounts.stringify(amountEffective),
+ selectedDenoms: [],
+ },
+ exchangeBaseUrl,
+ instructedAmount: Amounts.stringify(amountEffective),
+ effectiveWithdrawalAmount: Amounts.stringify(amountEffective),
+ rawWithdrawalAmount: Amounts.stringify(amountEffective),
+ });
+ await ctx.updateTransactionMeta(tx);
+ });
+ break;
+ }
+ default: {
+ throw Error("transaction type not supported");
+ }
+ }
+ return;
+ }
case "flag-confirm-pay-no-wait": {
const setVal = parsedUri.query?.get("val");
if (setVal === "0") {