wallet-core: remove deprecated txid parsing
This commit is contained in:
parent
4627c0781c
commit
f14c7e5f2a
@ -362,42 +362,6 @@ export enum TombstoneTag {
|
||||
DeletePeerPushCredit = "delete-peer-push-credit",
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an event ID from the type and the primary key for the event.
|
||||
*
|
||||
* @deprecated use constructTransactionIdentifier instead
|
||||
*/
|
||||
export function makeTransactionId(
|
||||
type: TransactionType,
|
||||
...args: string[]
|
||||
): string {
|
||||
return `txn:${type}:${args.map((x) => encodeURIComponent(x)).join(":")}`;
|
||||
}
|
||||
|
||||
export function parseId(
|
||||
idType: "txn" | "tmb" | "any",
|
||||
txId: string,
|
||||
): {
|
||||
type: TransactionType;
|
||||
args: string[];
|
||||
} {
|
||||
const txnParts = txId.split(":");
|
||||
if (txnParts.length < 3) {
|
||||
throw Error("id should have al least 3 parts separated by ':'");
|
||||
}
|
||||
const [prefix, typeStr, ...args] = txnParts;
|
||||
const type = typeStr as TransactionType;
|
||||
|
||||
if (idType != "any" && prefix !== idType) {
|
||||
throw Error(`id should start with ${idType}`);
|
||||
}
|
||||
|
||||
if (args.length === 0) {
|
||||
throw Error("id should have one or more arguments");
|
||||
}
|
||||
|
||||
return { type, args };
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an event ID from the type and the primary key for the event.
|
||||
|
@ -118,7 +118,6 @@ import {
|
||||
TaskIdentifiers,
|
||||
} from "../util/retries.js";
|
||||
import {
|
||||
makeTransactionId,
|
||||
runLongpollAsync,
|
||||
runOperationWithErrorReporting,
|
||||
spendCoins,
|
||||
|
@ -59,7 +59,7 @@ import {
|
||||
OperationAttemptResult,
|
||||
OperationAttemptResultType,
|
||||
} from "../util/retries.js";
|
||||
import { makeCoinAvailable, makeTransactionId } from "./common.js";
|
||||
import { makeCoinAvailable } from "./common.js";
|
||||
import { updateExchangeFromUrl } from "./exchanges.js";
|
||||
import {
|
||||
getCandidateWithdrawalDenoms,
|
||||
|
@ -67,7 +67,6 @@ import {
|
||||
PeerPushPaymentIncomingStatus,
|
||||
PeerPullPaymentInitiationRecord,
|
||||
RefundGroupRecord,
|
||||
ContractTermsRecord,
|
||||
} from "../db.js";
|
||||
import { InternalWalletState } from "../internal-wallet-state.js";
|
||||
import { PendingTaskType } from "../pending-types.js";
|
||||
@ -76,8 +75,6 @@ import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
|
||||
import { constructTaskIdentifier, TaskIdentifiers } from "../util/retries.js";
|
||||
import {
|
||||
makeTombstoneId,
|
||||
makeTransactionId,
|
||||
parseId,
|
||||
resetOperationTimeout,
|
||||
runOperationWithErrorReporting,
|
||||
TombstoneTag,
|
||||
@ -164,209 +161,227 @@ export async function getTransactionById(
|
||||
ws: InternalWalletState,
|
||||
req: TransactionByIdRequest,
|
||||
): Promise<Transaction> {
|
||||
const { type, args: rest } = parseId("txn", req.transactionId);
|
||||
if (type === TransactionType.Withdrawal) {
|
||||
const withdrawalGroupId = rest[0];
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.withdrawalGroups,
|
||||
x.exchangeDetails,
|
||||
x.exchanges,
|
||||
x.operationRetries,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const withdrawalGroupRecord = await tx.withdrawalGroups.get(
|
||||
withdrawalGroupId,
|
||||
);
|
||||
const parsedTx = parseTransactionIdentifier(req.transactionId);
|
||||
|
||||
if (!withdrawalGroupRecord) throw Error("not found");
|
||||
if (!parsedTx) {
|
||||
throw Error("invalid transaction ID");
|
||||
}
|
||||
|
||||
const opId = TaskIdentifiers.forWithdrawal(withdrawalGroupRecord);
|
||||
const ort = await tx.operationRetries.get(opId);
|
||||
switch (parsedTx.tag) {
|
||||
case TransactionType.Withdrawal: {
|
||||
const withdrawalGroupId = parsedTx.withdrawalGroupId;
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.withdrawalGroups,
|
||||
x.exchangeDetails,
|
||||
x.exchanges,
|
||||
x.operationRetries,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const withdrawalGroupRecord = await tx.withdrawalGroups.get(
|
||||
withdrawalGroupId,
|
||||
);
|
||||
|
||||
if (
|
||||
withdrawalGroupRecord.wgInfo.withdrawalType ===
|
||||
WithdrawalRecordType.BankIntegrated
|
||||
) {
|
||||
return buildTransactionForBankIntegratedWithdraw(
|
||||
if (!withdrawalGroupRecord) throw Error("not found");
|
||||
|
||||
const opId = TaskIdentifiers.forWithdrawal(withdrawalGroupRecord);
|
||||
const ort = await tx.operationRetries.get(opId);
|
||||
|
||||
if (
|
||||
withdrawalGroupRecord.wgInfo.withdrawalType ===
|
||||
WithdrawalRecordType.BankIntegrated
|
||||
) {
|
||||
return buildTransactionForBankIntegratedWithdraw(
|
||||
withdrawalGroupRecord,
|
||||
ort,
|
||||
);
|
||||
}
|
||||
const exchangeDetails = await getExchangeDetails(
|
||||
tx,
|
||||
withdrawalGroupRecord.exchangeBaseUrl,
|
||||
);
|
||||
if (!exchangeDetails) throw Error("not exchange details");
|
||||
|
||||
return buildTransactionForManualWithdraw(
|
||||
withdrawalGroupRecord,
|
||||
exchangeDetails,
|
||||
ort,
|
||||
);
|
||||
}
|
||||
const exchangeDetails = await getExchangeDetails(
|
||||
tx,
|
||||
withdrawalGroupRecord.exchangeBaseUrl,
|
||||
);
|
||||
if (!exchangeDetails) throw Error("not exchange details");
|
||||
});
|
||||
}
|
||||
|
||||
return buildTransactionForManualWithdraw(
|
||||
withdrawalGroupRecord,
|
||||
exchangeDetails,
|
||||
ort,
|
||||
);
|
||||
});
|
||||
} else if (type === TransactionType.Payment) {
|
||||
const proposalId = rest[0];
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.purchases,
|
||||
x.tombstones,
|
||||
x.operationRetries,
|
||||
x.contractTerms,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const purchase = await tx.purchases.get(proposalId);
|
||||
if (!purchase) throw Error("not found");
|
||||
const download = await expectProposalDownload(ws, purchase, tx);
|
||||
const contractData = download.contractData;
|
||||
const payOpId = TaskIdentifiers.forPay(purchase);
|
||||
const payRetryRecord = await tx.operationRetries.get(payOpId);
|
||||
case TransactionType.Payment: {
|
||||
const proposalId = parsedTx.proposalId;
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.purchases,
|
||||
x.tombstones,
|
||||
x.operationRetries,
|
||||
x.contractTerms,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const purchase = await tx.purchases.get(proposalId);
|
||||
if (!purchase) throw Error("not found");
|
||||
const download = await expectProposalDownload(ws, purchase, tx);
|
||||
const contractData = download.contractData;
|
||||
const payOpId = TaskIdentifiers.forPay(purchase);
|
||||
const payRetryRecord = await tx.operationRetries.get(payOpId);
|
||||
|
||||
return buildTransactionForPurchase(
|
||||
purchase,
|
||||
contractData,
|
||||
[], // FIXME: Add refunds from refund group records here.
|
||||
payRetryRecord,
|
||||
);
|
||||
});
|
||||
} else if (type === TransactionType.Refresh) {
|
||||
const refreshGroupId = rest[0];
|
||||
throw Error(`no tx for refresh`);
|
||||
} else if (type === TransactionType.Tip) {
|
||||
const tipId = rest[0];
|
||||
return await ws.db
|
||||
.mktx((x) => [x.tips, x.operationRetries])
|
||||
.runReadWrite(async (tx) => {
|
||||
const tipRecord = await tx.tips.get(tipId);
|
||||
if (!tipRecord) throw Error("not found");
|
||||
return buildTransactionForPurchase(
|
||||
purchase,
|
||||
contractData,
|
||||
[], // FIXME: Add refunds from refund group records here.
|
||||
payRetryRecord,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const retries = await tx.operationRetries.get(
|
||||
TaskIdentifiers.forTipPickup(tipRecord),
|
||||
);
|
||||
return buildTransactionForTip(tipRecord, retries);
|
||||
});
|
||||
} else if (type === TransactionType.Deposit) {
|
||||
const depositGroupId = rest[0];
|
||||
return await ws.db
|
||||
.mktx((x) => [x.depositGroups, x.operationRetries])
|
||||
.runReadWrite(async (tx) => {
|
||||
const depositRecord = await tx.depositGroups.get(depositGroupId);
|
||||
if (!depositRecord) throw Error("not found");
|
||||
case TransactionType.Refresh: {
|
||||
// FIXME: We should return info about the refresh here!
|
||||
throw Error(`no tx for refresh`);
|
||||
}
|
||||
|
||||
const retries = await tx.operationRetries.get(
|
||||
TaskIdentifiers.forDeposit(depositRecord),
|
||||
);
|
||||
return buildTransactionForDeposit(depositRecord, retries);
|
||||
});
|
||||
} else if (type === TransactionType.Refund) {
|
||||
// FIXME!
|
||||
throw Error("not implemented");
|
||||
} else if (type === TransactionType.PeerPullDebit) {
|
||||
const peerPullPaymentIncomingId = rest[0];
|
||||
return await ws.db
|
||||
.mktx((x) => [x.peerPullPaymentIncoming])
|
||||
.runReadWrite(async (tx) => {
|
||||
const debit = await tx.peerPullPaymentIncoming.get(
|
||||
peerPullPaymentIncomingId,
|
||||
);
|
||||
if (!debit) throw Error("not found");
|
||||
return buildTransactionForPullPaymentDebit(debit);
|
||||
});
|
||||
} else if (type === TransactionType.PeerPushDebit) {
|
||||
const pursePub = rest[0];
|
||||
return await ws.db
|
||||
.mktx((x) => [x.peerPushPaymentInitiations, x.contractTerms])
|
||||
.runReadWrite(async (tx) => {
|
||||
const debit = await tx.peerPushPaymentInitiations.get(pursePub);
|
||||
if (!debit) throw Error("not found");
|
||||
const ct = await tx.contractTerms.get(debit.contractTermsHash);
|
||||
checkDbInvariant(!!ct);
|
||||
return buildTransactionForPushPaymentDebit(debit, ct.contractTermsRaw);
|
||||
});
|
||||
} else if (type === TransactionType.PeerPushCredit) {
|
||||
const peerPushPaymentIncomingId = rest[0];
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.peerPushPaymentIncoming,
|
||||
x.contractTerms,
|
||||
x.withdrawalGroups,
|
||||
x.operationRetries,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const pushInc = await tx.peerPushPaymentIncoming.get(
|
||||
peerPushPaymentIncomingId,
|
||||
);
|
||||
if (!pushInc) throw Error("not found");
|
||||
const ct = await tx.contractTerms.get(pushInc.contractTermsHash);
|
||||
checkDbInvariant(!!ct);
|
||||
case TransactionType.Tip: {
|
||||
const tipId = parsedTx.walletTipId;
|
||||
return await ws.db
|
||||
.mktx((x) => [x.tips, x.operationRetries])
|
||||
.runReadWrite(async (tx) => {
|
||||
const tipRecord = await tx.tips.get(tipId);
|
||||
if (!tipRecord) throw Error("not found");
|
||||
|
||||
let wg: WithdrawalGroupRecord | undefined = undefined;
|
||||
let wgOrt: OperationRetryRecord | undefined = undefined;
|
||||
if (pushInc.withdrawalGroupId) {
|
||||
wg = await tx.withdrawalGroups.get(pushInc.withdrawalGroupId);
|
||||
if (wg) {
|
||||
const withdrawalOpId = TaskIdentifiers.forWithdrawal(wg);
|
||||
wgOrt = await tx.operationRetries.get(withdrawalOpId);
|
||||
const retries = await tx.operationRetries.get(
|
||||
TaskIdentifiers.forTipPickup(tipRecord),
|
||||
);
|
||||
return buildTransactionForTip(tipRecord, retries);
|
||||
});
|
||||
}
|
||||
|
||||
case TransactionType.Deposit: {
|
||||
const depositGroupId = parsedTx.depositGroupId;
|
||||
return await ws.db
|
||||
.mktx((x) => [x.depositGroups, x.operationRetries])
|
||||
.runReadWrite(async (tx) => {
|
||||
const depositRecord = await tx.depositGroups.get(depositGroupId);
|
||||
if (!depositRecord) throw Error("not found");
|
||||
|
||||
const retries = await tx.operationRetries.get(
|
||||
TaskIdentifiers.forDeposit(depositRecord),
|
||||
);
|
||||
return buildTransactionForDeposit(depositRecord, retries);
|
||||
});
|
||||
}
|
||||
|
||||
case TransactionType.Refund:
|
||||
// FIXME!
|
||||
throw Error("not implemented");
|
||||
case TransactionType.PeerPullDebit: {
|
||||
return await ws.db
|
||||
.mktx((x) => [x.peerPullPaymentIncoming])
|
||||
.runReadWrite(async (tx) => {
|
||||
const debit = await tx.peerPullPaymentIncoming.get(
|
||||
parsedTx.peerPullPaymentIncomingId,
|
||||
);
|
||||
if (!debit) throw Error("not found");
|
||||
return buildTransactionForPullPaymentDebit(debit);
|
||||
});
|
||||
}
|
||||
|
||||
case TransactionType.PeerPushDebit: {
|
||||
return await ws.db
|
||||
.mktx((x) => [x.peerPushPaymentInitiations, x.contractTerms])
|
||||
.runReadWrite(async (tx) => {
|
||||
const debit = await tx.peerPushPaymentInitiations.get(
|
||||
parsedTx.pursePub,
|
||||
);
|
||||
if (!debit) throw Error("not found");
|
||||
const ct = await tx.contractTerms.get(debit.contractTermsHash);
|
||||
checkDbInvariant(!!ct);
|
||||
return buildTransactionForPushPaymentDebit(
|
||||
debit,
|
||||
ct.contractTermsRaw,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
case TransactionType.PeerPushCredit: {
|
||||
const peerPushPaymentIncomingId = parsedTx.peerPushPaymentIncomingId;
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.peerPushPaymentIncoming,
|
||||
x.contractTerms,
|
||||
x.withdrawalGroups,
|
||||
x.operationRetries,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const pushInc = await tx.peerPushPaymentIncoming.get(
|
||||
peerPushPaymentIncomingId,
|
||||
);
|
||||
if (!pushInc) throw Error("not found");
|
||||
const ct = await tx.contractTerms.get(pushInc.contractTermsHash);
|
||||
checkDbInvariant(!!ct);
|
||||
|
||||
let wg: WithdrawalGroupRecord | undefined = undefined;
|
||||
let wgOrt: OperationRetryRecord | undefined = undefined;
|
||||
if (pushInc.withdrawalGroupId) {
|
||||
wg = await tx.withdrawalGroups.get(pushInc.withdrawalGroupId);
|
||||
if (wg) {
|
||||
const withdrawalOpId = TaskIdentifiers.forWithdrawal(wg);
|
||||
wgOrt = await tx.operationRetries.get(withdrawalOpId);
|
||||
}
|
||||
}
|
||||
}
|
||||
const pushIncOpId = TaskIdentifiers.forPeerPushCredit(pushInc);
|
||||
let pushIncOrt = await tx.operationRetries.get(pushIncOpId);
|
||||
const pushIncOpId = TaskIdentifiers.forPeerPushCredit(pushInc);
|
||||
let pushIncOrt = await tx.operationRetries.get(pushIncOpId);
|
||||
|
||||
return buildTransactionForPeerPushCredit(
|
||||
pushInc,
|
||||
pushIncOrt,
|
||||
ct.contractTermsRaw,
|
||||
wg,
|
||||
wgOrt,
|
||||
);
|
||||
});
|
||||
} else if (type === TransactionType.PeerPullCredit) {
|
||||
const pursePub = rest[0];
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.peerPullPaymentInitiations,
|
||||
x.contractTerms,
|
||||
x.withdrawalGroups,
|
||||
x.operationRetries,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const pushInc = await tx.peerPullPaymentInitiations.get(pursePub);
|
||||
if (!pushInc) throw Error("not found");
|
||||
const ct = await tx.contractTerms.get(pushInc.contractTermsHash);
|
||||
checkDbInvariant(!!ct);
|
||||
return buildTransactionForPeerPushCredit(
|
||||
pushInc,
|
||||
pushIncOrt,
|
||||
ct.contractTermsRaw,
|
||||
wg,
|
||||
wgOrt,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
let wg: WithdrawalGroupRecord | undefined = undefined;
|
||||
let wgOrt: OperationRetryRecord | undefined = undefined;
|
||||
if (pushInc.withdrawalGroupId) {
|
||||
wg = await tx.withdrawalGroups.get(pushInc.withdrawalGroupId);
|
||||
if (wg) {
|
||||
const withdrawalOpId = TaskIdentifiers.forWithdrawal(wg);
|
||||
wgOrt = await tx.operationRetries.get(withdrawalOpId);
|
||||
case TransactionType.PeerPullCredit: {
|
||||
const pursePub = parsedTx.pursePub;
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.peerPullPaymentInitiations,
|
||||
x.contractTerms,
|
||||
x.withdrawalGroups,
|
||||
x.operationRetries,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const pushInc = await tx.peerPullPaymentInitiations.get(pursePub);
|
||||
if (!pushInc) throw Error("not found");
|
||||
const ct = await tx.contractTerms.get(pushInc.contractTermsHash);
|
||||
checkDbInvariant(!!ct);
|
||||
|
||||
let wg: WithdrawalGroupRecord | undefined = undefined;
|
||||
let wgOrt: OperationRetryRecord | undefined = undefined;
|
||||
if (pushInc.withdrawalGroupId) {
|
||||
wg = await tx.withdrawalGroups.get(pushInc.withdrawalGroupId);
|
||||
if (wg) {
|
||||
const withdrawalOpId = TaskIdentifiers.forWithdrawal(wg);
|
||||
wgOrt = await tx.operationRetries.get(withdrawalOpId);
|
||||
}
|
||||
}
|
||||
}
|
||||
const pushIncOpId =
|
||||
TaskIdentifiers.forPeerPullPaymentInitiation(pushInc);
|
||||
let pushIncOrt = await tx.operationRetries.get(pushIncOpId);
|
||||
const pushIncOpId =
|
||||
TaskIdentifiers.forPeerPullPaymentInitiation(pushInc);
|
||||
let pushIncOrt = await tx.operationRetries.get(pushIncOpId);
|
||||
|
||||
return buildTransactionForPeerPullCredit(
|
||||
pushInc,
|
||||
pushIncOrt,
|
||||
ct.contractTermsRaw,
|
||||
wg,
|
||||
wgOrt,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
const unknownTxType: never = type;
|
||||
throw Error(`can't retrieve a '${unknownTxType}' transaction`);
|
||||
return buildTransactionForPeerPullCredit(
|
||||
pushInc,
|
||||
pushIncOrt,
|
||||
ct.contractTermsRaw,
|
||||
wg,
|
||||
wgOrt,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Just a marker helper for unknown states until DD37 is fully implemented.
|
||||
const mkTxStateUnknown = () => ({
|
||||
major: TransactionMajorState.Unknown,
|
||||
});
|
||||
|
||||
function buildTransactionForPushPaymentDebit(
|
||||
pi: PeerPushPaymentInitiationRecord,
|
||||
contractTerms: PeerContractTerms,
|
||||
@ -1293,7 +1308,13 @@ export function constructTransactionIdentifier(
|
||||
export function parseTransactionIdentifier(
|
||||
transactionId: string,
|
||||
): ParsedTransactionIdentifier | undefined {
|
||||
const { type, args: rest } = parseId("any", transactionId);
|
||||
const txnParts = transactionId.split(":");
|
||||
|
||||
if (txnParts.length < 3) {
|
||||
throw Error("id should have al least 3 parts separated by ':'");
|
||||
}
|
||||
|
||||
const [prefix, type, ...rest] = txnParts;
|
||||
|
||||
switch (type) {
|
||||
case TransactionType.Deposit:
|
||||
@ -1489,25 +1510,92 @@ export async function deleteTransaction(
|
||||
ws: InternalWalletState,
|
||||
transactionId: string,
|
||||
): Promise<void> {
|
||||
const { type, args: rest } = parseId("txn", transactionId);
|
||||
const parsedTx = parseTransactionIdentifier(transactionId);
|
||||
|
||||
if (type === TransactionType.PeerPushCredit) {
|
||||
const peerPushPaymentIncomingId = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [
|
||||
x.withdrawalGroups,
|
||||
x.peerPushPaymentIncoming,
|
||||
x.tombstones,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const pushInc = await tx.peerPushPaymentIncoming.get(
|
||||
peerPushPaymentIncomingId,
|
||||
);
|
||||
if (!pushInc) {
|
||||
return;
|
||||
}
|
||||
if (pushInc.withdrawalGroupId) {
|
||||
const withdrawalGroupId = pushInc.withdrawalGroupId;
|
||||
if (!parsedTx) {
|
||||
throw Error("invalid transaction ID");
|
||||
}
|
||||
|
||||
switch (parsedTx.tag) {
|
||||
case TransactionType.PeerPushCredit: {
|
||||
const peerPushPaymentIncomingId = parsedTx.peerPushPaymentIncomingId;
|
||||
await ws.db
|
||||
.mktx((x) => [
|
||||
x.withdrawalGroups,
|
||||
x.peerPushPaymentIncoming,
|
||||
x.tombstones,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const pushInc = await tx.peerPushPaymentIncoming.get(
|
||||
peerPushPaymentIncomingId,
|
||||
);
|
||||
if (!pushInc) {
|
||||
return;
|
||||
}
|
||||
if (pushInc.withdrawalGroupId) {
|
||||
const withdrawalGroupId = pushInc.withdrawalGroupId;
|
||||
const withdrawalGroupRecord = await tx.withdrawalGroups.get(
|
||||
withdrawalGroupId,
|
||||
);
|
||||
if (withdrawalGroupRecord) {
|
||||
await tx.withdrawalGroups.delete(withdrawalGroupId);
|
||||
await tx.tombstones.put({
|
||||
id:
|
||||
TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
|
||||
});
|
||||
}
|
||||
}
|
||||
await tx.peerPushPaymentIncoming.delete(peerPushPaymentIncomingId);
|
||||
await tx.tombstones.put({
|
||||
id:
|
||||
TombstoneTag.DeletePeerPushCredit +
|
||||
":" +
|
||||
peerPushPaymentIncomingId,
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
case TransactionType.PeerPullCredit: {
|
||||
const pursePub = parsedTx.pursePub;
|
||||
await ws.db
|
||||
.mktx((x) => [
|
||||
x.withdrawalGroups,
|
||||
x.peerPullPaymentInitiations,
|
||||
x.tombstones,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const pullIni = await tx.peerPullPaymentInitiations.get(pursePub);
|
||||
if (!pullIni) {
|
||||
return;
|
||||
}
|
||||
if (pullIni.withdrawalGroupId) {
|
||||
const withdrawalGroupId = pullIni.withdrawalGroupId;
|
||||
const withdrawalGroupRecord = await tx.withdrawalGroups.get(
|
||||
withdrawalGroupId,
|
||||
);
|
||||
if (withdrawalGroupRecord) {
|
||||
await tx.withdrawalGroups.delete(withdrawalGroupId);
|
||||
await tx.tombstones.put({
|
||||
id:
|
||||
TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
|
||||
});
|
||||
}
|
||||
}
|
||||
await tx.peerPullPaymentInitiations.delete(pursePub);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeletePeerPullCredit + ":" + pursePub,
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case TransactionType.Withdrawal: {
|
||||
const withdrawalGroupId = parsedTx.withdrawalGroupId;
|
||||
await ws.db
|
||||
.mktx((x) => [x.withdrawalGroups, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const withdrawalGroupRecord = await tx.withdrawalGroups.get(
|
||||
withdrawalGroupId,
|
||||
);
|
||||
@ -1516,170 +1604,124 @@ export async function deleteTransaction(
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
await tx.peerPushPaymentIncoming.delete(peerPushPaymentIncomingId);
|
||||
await tx.tombstones.put({
|
||||
id:
|
||||
TombstoneTag.DeletePeerPushCredit + ":" + peerPushPaymentIncomingId,
|
||||
});
|
||||
});
|
||||
} else if (type === TransactionType.PeerPullCredit) {
|
||||
const pursePub = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [
|
||||
x.withdrawalGroups,
|
||||
x.peerPullPaymentInitiations,
|
||||
x.tombstones,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const pullIni = await tx.peerPullPaymentInitiations.get(pursePub);
|
||||
if (!pullIni) {
|
||||
return;
|
||||
}
|
||||
if (pullIni.withdrawalGroupId) {
|
||||
const withdrawalGroupId = pullIni.withdrawalGroupId;
|
||||
const withdrawalGroupRecord = await tx.withdrawalGroups.get(
|
||||
withdrawalGroupId,
|
||||
);
|
||||
if (withdrawalGroupRecord) {
|
||||
await tx.withdrawalGroups.delete(withdrawalGroupId);
|
||||
return;
|
||||
}
|
||||
|
||||
case TransactionType.Payment: {
|
||||
const proposalId = parsedTx.proposalId;
|
||||
await ws.db
|
||||
.mktx((x) => [x.purchases, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
let found = false;
|
||||
const purchase = await tx.purchases.get(proposalId);
|
||||
if (purchase) {
|
||||
found = true;
|
||||
await tx.purchases.delete(proposalId);
|
||||
}
|
||||
if (found) {
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
|
||||
id: TombstoneTag.DeletePayment + ":" + proposalId,
|
||||
});
|
||||
}
|
||||
}
|
||||
await tx.peerPullPaymentInitiations.delete(pursePub);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeletePeerPullCredit + ":" + pursePub,
|
||||
});
|
||||
});
|
||||
} else if (type === TransactionType.Withdrawal) {
|
||||
const withdrawalGroupId = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [x.withdrawalGroups, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const withdrawalGroupRecord = await tx.withdrawalGroups.get(
|
||||
withdrawalGroupId,
|
||||
);
|
||||
if (withdrawalGroupRecord) {
|
||||
await tx.withdrawalGroups.delete(withdrawalGroupId);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else if (type === TransactionType.Payment) {
|
||||
const proposalId = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [x.purchases, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
let found = false;
|
||||
const purchase = await tx.purchases.get(proposalId);
|
||||
if (purchase) {
|
||||
found = true;
|
||||
await tx.purchases.delete(proposalId);
|
||||
}
|
||||
if (found) {
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeletePayment + ":" + proposalId,
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (type === TransactionType.Refresh) {
|
||||
const refreshGroupId = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [x.refreshGroups, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const rg = await tx.refreshGroups.get(refreshGroupId);
|
||||
if (rg) {
|
||||
await tx.refreshGroups.delete(refreshGroupId);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteRefreshGroup + ":" + refreshGroupId,
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (type === TransactionType.Tip) {
|
||||
const tipId = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [x.tips, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const tipRecord = await tx.tips.get(tipId);
|
||||
if (tipRecord) {
|
||||
await tx.tips.delete(tipId);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteTip + ":" + tipId,
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (type === TransactionType.Deposit) {
|
||||
const depositGroupId = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [x.depositGroups, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const tipRecord = await tx.depositGroups.get(depositGroupId);
|
||||
if (tipRecord) {
|
||||
await tx.depositGroups.delete(depositGroupId);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteDepositGroup + ":" + depositGroupId,
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (type === TransactionType.Refund) {
|
||||
const proposalId = rest[0];
|
||||
const executionTimeStr = rest[1];
|
||||
return;
|
||||
}
|
||||
|
||||
await ws.db
|
||||
.mktx((x) => [x.purchases, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const purchase = await tx.purchases.get(proposalId);
|
||||
if (purchase) {
|
||||
// This should just influence the history view,
|
||||
// but won't delete any actual refund information.
|
||||
await tx.tombstones.put({
|
||||
id: makeTombstoneId(
|
||||
TombstoneTag.DeleteRefund,
|
||||
proposalId,
|
||||
executionTimeStr,
|
||||
),
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (type === TransactionType.PeerPullDebit) {
|
||||
const peerPullPaymentIncomingId = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [x.peerPullPaymentIncoming, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const debit = await tx.peerPullPaymentIncoming.get(
|
||||
peerPullPaymentIncomingId,
|
||||
);
|
||||
if (debit) {
|
||||
await tx.peerPullPaymentIncoming.delete(peerPullPaymentIncomingId);
|
||||
await tx.tombstones.put({
|
||||
id: makeTombstoneId(
|
||||
TombstoneTag.DeletePeerPullDebit,
|
||||
peerPullPaymentIncomingId,
|
||||
),
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (type === TransactionType.PeerPushDebit) {
|
||||
const pursePub = rest[0];
|
||||
await ws.db
|
||||
.mktx((x) => [x.peerPushPaymentInitiations, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const debit = await tx.peerPushPaymentInitiations.get(pursePub);
|
||||
if (debit) {
|
||||
await tx.peerPushPaymentInitiations.delete(pursePub);
|
||||
await tx.tombstones.put({
|
||||
id: makeTombstoneId(TombstoneTag.DeletePeerPushDebit, pursePub),
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const unknownTxType: never = type;
|
||||
throw Error(`can't delete a '${unknownTxType}' transaction`);
|
||||
case TransactionType.Refresh: {
|
||||
const refreshGroupId = parsedTx.refreshGroupId;
|
||||
await ws.db
|
||||
.mktx((x) => [x.refreshGroups, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const rg = await tx.refreshGroups.get(refreshGroupId);
|
||||
if (rg) {
|
||||
await tx.refreshGroups.delete(refreshGroupId);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteRefreshGroup + ":" + refreshGroupId,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case TransactionType.Tip: {
|
||||
const tipId = parsedTx.walletTipId;
|
||||
await ws.db
|
||||
.mktx((x) => [x.tips, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const tipRecord = await tx.tips.get(tipId);
|
||||
if (tipRecord) {
|
||||
await tx.tips.delete(tipId);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteTip + ":" + tipId,
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
case TransactionType.Deposit: {
|
||||
const depositGroupId = parsedTx.depositGroupId;
|
||||
await ws.db
|
||||
.mktx((x) => [x.depositGroups, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const tipRecord = await tx.depositGroups.get(depositGroupId);
|
||||
if (tipRecord) {
|
||||
await tx.depositGroups.delete(depositGroupId);
|
||||
await tx.tombstones.put({
|
||||
id: TombstoneTag.DeleteDepositGroup + ":" + depositGroupId,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case TransactionType.Refund: {
|
||||
// FIXME: Implement!
|
||||
return;
|
||||
}
|
||||
|
||||
case TransactionType.PeerPullDebit: {
|
||||
const peerPullPaymentIncomingId = parsedTx.peerPullPaymentIncomingId;
|
||||
await ws.db
|
||||
.mktx((x) => [x.peerPullPaymentIncoming, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const debit = await tx.peerPullPaymentIncoming.get(
|
||||
peerPullPaymentIncomingId,
|
||||
);
|
||||
if (debit) {
|
||||
await tx.peerPullPaymentIncoming.delete(peerPullPaymentIncomingId);
|
||||
await tx.tombstones.put({
|
||||
id: makeTombstoneId(
|
||||
TombstoneTag.DeletePeerPullDebit,
|
||||
peerPullPaymentIncomingId,
|
||||
),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case TransactionType.PeerPushDebit: {
|
||||
const pursePub = parsedTx.pursePub;
|
||||
await ws.db
|
||||
.mktx((x) => [x.peerPushPaymentInitiations, x.tombstones])
|
||||
.runReadWrite(async (tx) => {
|
||||
const debit = await tx.peerPushPaymentInitiations.get(pursePub);
|
||||
if (debit) {
|
||||
await tx.peerPushPaymentInitiations.delete(pursePub);
|
||||
await tx.tombstones.put({
|
||||
id: makeTombstoneId(TombstoneTag.DeletePeerPushDebit, pursePub),
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,6 @@ import {
|
||||
WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
|
||||
WALLET_EXCHANGE_PROTOCOL_VERSION,
|
||||
} from "../versions.js";
|
||||
import { makeTransactionId } from "./common.js";
|
||||
import {
|
||||
getExchangeDetails,
|
||||
getExchangePaytoUri,
|
||||
@ -1456,10 +1455,10 @@ export async function processWithdrawalGroup(
|
||||
|
||||
if (numKycRequired > 0) {
|
||||
if (kycInfo) {
|
||||
const txId = makeTransactionId(
|
||||
TransactionType.Withdrawal,
|
||||
withdrawalGroup.withdrawalGroupId,
|
||||
);
|
||||
const txId = constructTransactionIdentifier({
|
||||
tag: TransactionType.Withdrawal,
|
||||
withdrawalGroupId: withdrawalGroup.withdrawalGroupId,
|
||||
});
|
||||
await checkWithdrawalKycStatus(
|
||||
ws,
|
||||
withdrawalGroup.exchangeBaseUrl,
|
||||
@ -2050,12 +2049,13 @@ async function processReserveBankStatus(
|
||||
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
||||
r.status = WithdrawalGroupStatus.PendingQueryingStatus;
|
||||
// FIXME: Notification is deprecated with DD37.
|
||||
const transactionId = constructTransactionIdentifier({
|
||||
tag: TransactionType.Withdrawal,
|
||||
withdrawalGroupId: r.withdrawalGroupId,
|
||||
});
|
||||
ws.notify({
|
||||
type: NotificationType.WithdrawalGroupBankConfirmed,
|
||||
transactionId: makeTransactionId(
|
||||
TransactionType.Withdrawal,
|
||||
r.withdrawalGroupId,
|
||||
),
|
||||
transactionId,
|
||||
});
|
||||
} else {
|
||||
logger.info("withdrawal: transfer not yet confirmed by bank");
|
||||
|
@ -159,6 +159,7 @@ describe("Withdraw CTA states", () => {
|
||||
paytoUris: ["payto://"],
|
||||
tosAccepted: true,
|
||||
ageRestrictionOptions: [],
|
||||
numCoins: 42,
|
||||
},
|
||||
);
|
||||
|
||||
@ -222,6 +223,7 @@ describe("Withdraw CTA states", () => {
|
||||
paytoUris: ["payto://"],
|
||||
tosAccepted: false,
|
||||
ageRestrictionOptions: [],
|
||||
numCoins: 42,
|
||||
},
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user