wallet-core: report possible actions in transactions list
This commit is contained in:
parent
000359a5e7
commit
2a92ca8732
@ -125,6 +125,15 @@ export enum TransactionMinorState {
|
|||||||
AcceptRefund = "accept-refund",
|
AcceptRefund = "accept-refund",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum TransactionAction {
|
||||||
|
Delete = "delete",
|
||||||
|
Suspend = "suspend",
|
||||||
|
Resume = "resume",
|
||||||
|
Abort = "abort",
|
||||||
|
Fail = "fail",
|
||||||
|
Retry = "retry",
|
||||||
|
}
|
||||||
|
|
||||||
export interface TransactionsResponse {
|
export interface TransactionsResponse {
|
||||||
// a list of past and pending transactions sorted by pending, timestamp and transactionId.
|
// a list of past and pending transactions sorted by pending, timestamp and transactionId.
|
||||||
// In case two events are both pending and have the same timestamp,
|
// In case two events are both pending and have the same timestamp,
|
||||||
@ -149,6 +158,11 @@ export interface TransactionCommon {
|
|||||||
*/
|
*/
|
||||||
txState: TransactionState;
|
txState: TransactionState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible transitions based on the current state.
|
||||||
|
*/
|
||||||
|
txActions: string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raw amount of the transaction (exclusive of fees or other extra costs).
|
* Raw amount of the transaction (exclusive of fees or other extra costs).
|
||||||
*/
|
*/
|
||||||
|
@ -1131,7 +1131,7 @@ export enum PurchaseStatus {
|
|||||||
/**
|
/**
|
||||||
* Proposal downloaded, but the user needs to accept/reject it.
|
* Proposal downloaded, but the user needs to accept/reject it.
|
||||||
*/
|
*/
|
||||||
Proposed = 30,
|
DialogProposed = 30,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The user has rejected the proposal.
|
* The user has rejected the proposal.
|
||||||
|
@ -418,7 +418,7 @@ export async function exportBackup(
|
|||||||
break;
|
break;
|
||||||
case PurchaseStatus.PendingPayingReplay:
|
case PurchaseStatus.PendingPayingReplay:
|
||||||
case PurchaseStatus.PendingDownloadingProposal:
|
case PurchaseStatus.PendingDownloadingProposal:
|
||||||
case PurchaseStatus.Proposed:
|
case PurchaseStatus.DialogProposed:
|
||||||
case PurchaseStatus.PendingPaying:
|
case PurchaseStatus.PendingPaying:
|
||||||
propStatus = BackupProposalStatus.Proposed;
|
propStatus = BackupProposalStatus.Proposed;
|
||||||
break;
|
break;
|
||||||
|
@ -578,7 +578,7 @@ export async function importBackup(
|
|||||||
proposalStatus = PurchaseStatus.Done;
|
proposalStatus = PurchaseStatus.Done;
|
||||||
break;
|
break;
|
||||||
case BackupProposalStatus.Proposed:
|
case BackupProposalStatus.Proposed:
|
||||||
proposalStatus = PurchaseStatus.Proposed;
|
proposalStatus = PurchaseStatus.DialogProposed;
|
||||||
break;
|
break;
|
||||||
case BackupProposalStatus.PermanentlyFailed:
|
case BackupProposalStatus.PermanentlyFailed:
|
||||||
proposalStatus = PurchaseStatus.AbortedIncompletePayment;
|
proposalStatus = PurchaseStatus.AbortedIncompletePayment;
|
||||||
|
@ -59,11 +59,11 @@ import {
|
|||||||
TransactionType,
|
TransactionType,
|
||||||
URL,
|
URL,
|
||||||
WireFee,
|
WireFee,
|
||||||
|
TransactionAction,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import {
|
import {
|
||||||
DenominationRecord,
|
DenominationRecord,
|
||||||
DepositGroupRecord,
|
DepositGroupRecord,
|
||||||
OperationStatus,
|
|
||||||
DepositElementStatus,
|
DepositElementStatus,
|
||||||
} from "../db.js";
|
} from "../db.js";
|
||||||
import { TalerError } from "@gnu-taler/taler-util";
|
import { TalerError } from "@gnu-taler/taler-util";
|
||||||
@ -115,6 +115,7 @@ export function computeDepositTransactionStatus(
|
|||||||
major: TransactionMajorState.Done,
|
major: TransactionMajorState.Done,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// FIXME: We should actually use separate pending states for this!
|
||||||
case DepositOperationStatus.Pending: {
|
case DepositOperationStatus.Pending: {
|
||||||
const numTotal = dg.payCoinSelection.coinPubs.length;
|
const numTotal = dg.payCoinSelection.coinPubs.length;
|
||||||
let numDeposited = 0;
|
let numDeposited = 0;
|
||||||
@ -134,9 +135,6 @@ export function computeDepositTransactionStatus(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`num total ${numTotal}`);
|
|
||||||
logger.info(`num deposited ${numDeposited}`);
|
|
||||||
|
|
||||||
if (numKycRequired > 0) {
|
if (numKycRequired > 0) {
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Pending,
|
major: TransactionMajorState.Pending,
|
||||||
@ -181,6 +179,57 @@ export function computeDepositTransactionStatus(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function computeDepositTransactionActions(
|
||||||
|
dg: DepositGroupRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (dg.operationStatus) {
|
||||||
|
case DepositOperationStatus.Finished: {
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
}
|
||||||
|
case DepositOperationStatus.Pending: {
|
||||||
|
const numTotal = dg.payCoinSelection.coinPubs.length;
|
||||||
|
let numDeposited = 0;
|
||||||
|
let numKycRequired = 0;
|
||||||
|
let numWired = 0;
|
||||||
|
for (let i = 0; i < numTotal; i++) {
|
||||||
|
if (dg.depositedPerCoin[i]) {
|
||||||
|
numDeposited++;
|
||||||
|
}
|
||||||
|
switch (dg.transactionPerCoin[i]) {
|
||||||
|
case DepositElementStatus.KycRequired:
|
||||||
|
numKycRequired++;
|
||||||
|
break;
|
||||||
|
case DepositElementStatus.Wired:
|
||||||
|
numWired++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numKycRequired > 0) {
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numDeposited == numTotal) {
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
}
|
||||||
|
case DepositOperationStatus.Suspended:
|
||||||
|
return [TransactionAction.Resume];
|
||||||
|
case DepositOperationStatus.Aborting:
|
||||||
|
return [TransactionAction.Fail, TransactionAction.Suspend];
|
||||||
|
case DepositOperationStatus.Aborted:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case DepositOperationStatus.Failed:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case DepositOperationStatus.SuspendedAborting:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
default:
|
||||||
|
throw Error(`unexpected deposit group state (${dg.operationStatus})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function suspendDepositGroup(
|
export async function suspendDepositGroup(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
depositGroupId: string,
|
depositGroupId: string,
|
||||||
@ -309,7 +358,7 @@ export async function abortDepositGroup(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingDepositGroup(
|
export async function failDepositTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
depositGroupId: string,
|
depositGroupId: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
@ -70,6 +70,7 @@ import {
|
|||||||
TalerProtocolTimestamp,
|
TalerProtocolTimestamp,
|
||||||
TalerProtocolViolationError,
|
TalerProtocolViolationError,
|
||||||
TalerUriAction,
|
TalerUriAction,
|
||||||
|
TransactionAction,
|
||||||
TransactionMajorState,
|
TransactionMajorState,
|
||||||
TransactionMinorState,
|
TransactionMinorState,
|
||||||
TransactionState,
|
TransactionState,
|
||||||
@ -547,7 +548,7 @@ async function processDownloadProposal(
|
|||||||
await tx.purchases.put(p);
|
await tx.purchases.put(p);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.purchaseStatus = PurchaseStatus.Proposed;
|
p.purchaseStatus = PurchaseStatus.DialogProposed;
|
||||||
await tx.purchases.put(p);
|
await tx.purchases.put(p);
|
||||||
}
|
}
|
||||||
const newTxState = computePayMerchantTransactionState(p);
|
const newTxState = computePayMerchantTransactionState(p);
|
||||||
@ -994,7 +995,7 @@ export async function checkPaymentByProposalId(
|
|||||||
return tx.purchases.get(proposalId);
|
return tx.purchases.get(proposalId);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!purchase || purchase.purchaseStatus === PurchaseStatus.Proposed) {
|
if (!purchase || purchase.purchaseStatus === PurchaseStatus.DialogProposed) {
|
||||||
// If not already paid, check if we could pay for it.
|
// If not already paid, check if we could pay for it.
|
||||||
const res = await selectPayCoinsNew(ws, {
|
const res = await selectPayCoinsNew(ws, {
|
||||||
auditors: [],
|
auditors: [],
|
||||||
@ -1417,7 +1418,7 @@ export async function confirmPay(
|
|||||||
}
|
}
|
||||||
const oldTxState = computePayMerchantTransactionState(p);
|
const oldTxState = computePayMerchantTransactionState(p);
|
||||||
switch (p.purchaseStatus) {
|
switch (p.purchaseStatus) {
|
||||||
case PurchaseStatus.Proposed:
|
case PurchaseStatus.DialogProposed:
|
||||||
p.payInfo = {
|
p.payInfo = {
|
||||||
payCoinSelection: coinSelection,
|
payCoinSelection: coinSelection,
|
||||||
payCoinSelectionUid: encodeCrock(getRandomBytes(16)),
|
payCoinSelectionUid: encodeCrock(getRandomBytes(16)),
|
||||||
@ -1498,7 +1499,7 @@ export async function processPurchase(
|
|||||||
case PurchaseStatus.FailedClaim:
|
case PurchaseStatus.FailedClaim:
|
||||||
case PurchaseStatus.Done:
|
case PurchaseStatus.Done:
|
||||||
case PurchaseStatus.RepurchaseDetected:
|
case PurchaseStatus.RepurchaseDetected:
|
||||||
case PurchaseStatus.Proposed:
|
case PurchaseStatus.DialogProposed:
|
||||||
case PurchaseStatus.AbortedProposalRefused:
|
case PurchaseStatus.AbortedProposalRefused:
|
||||||
case PurchaseStatus.AbortedIncompletePayment:
|
case PurchaseStatus.AbortedIncompletePayment:
|
||||||
case PurchaseStatus.SuspendedAbortingWithRefund:
|
case PurchaseStatus.SuspendedAbortingWithRefund:
|
||||||
@ -1713,7 +1714,7 @@ export async function refuseProposal(
|
|||||||
logger.trace(`proposal ${proposalId} not found, won't refuse proposal`);
|
logger.trace(`proposal ${proposalId} not found, won't refuse proposal`);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (proposal.purchaseStatus !== PurchaseStatus.Proposed) {
|
if (proposal.purchaseStatus !== PurchaseStatus.DialogProposed) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const oldTxState = computePayMerchantTransactionState(proposal);
|
const oldTxState = computePayMerchantTransactionState(proposal);
|
||||||
@ -1791,7 +1792,7 @@ export async function abortPayMerchant(
|
|||||||
ws.workAvailable.trigger();
|
ws.workAvailable.trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingPaymentTransaction(
|
export async function failPaymentTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@ -2023,7 +2024,7 @@ export function computePayMerchantTransactionState(
|
|||||||
major: TransactionMajorState.SuspendedAborting,
|
major: TransactionMajorState.SuspendedAborting,
|
||||||
};
|
};
|
||||||
// Dialog States
|
// Dialog States
|
||||||
case PurchaseStatus.Proposed:
|
case PurchaseStatus.DialogProposed:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Dialog,
|
major: TransactionMajorState.Dialog,
|
||||||
minor: TransactionMinorState.MerchantOrderProposed,
|
minor: TransactionMinorState.MerchantOrderProposed,
|
||||||
@ -2060,6 +2061,68 @@ export function computePayMerchantTransactionState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function computePayMerchantTransactionActions(
|
||||||
|
purchaseRecord: PurchaseRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (purchaseRecord.purchaseStatus) {
|
||||||
|
// Pending States
|
||||||
|
case PurchaseStatus.PendingDownloadingProposal:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.PendingPaying:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.PendingPayingReplay:
|
||||||
|
// Special "abort" since it goes back to "done".
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.PendingQueryingAutoRefund:
|
||||||
|
// Special "abort" since it goes back to "done".
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.PendingQueryingRefund:
|
||||||
|
// Special "abort" since it goes back to "done".
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.PendingAcceptRefund:
|
||||||
|
// Special "abort" since it goes back to "done".
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
// Suspended Pending States
|
||||||
|
case PurchaseStatus.SuspendedDownloadingProposal:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.SuspendedPaying:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.SuspendedPayingReplay:
|
||||||
|
// Special "abort" since it goes back to "done".
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.SuspendedQueryingAutoRefund:
|
||||||
|
// Special "abort" since it goes back to "done".
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.SuspendedQueryingRefund:
|
||||||
|
// Special "abort" since it goes back to "done".
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PurchaseStatus.SuspendedPendingAcceptRefund:
|
||||||
|
// Special "abort" since it goes back to "done".
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
// Aborting States
|
||||||
|
case PurchaseStatus.AbortingWithRefund:
|
||||||
|
return [TransactionAction.Fail, TransactionAction.Suspend];
|
||||||
|
case PurchaseStatus.SuspendedAbortingWithRefund:
|
||||||
|
return [TransactionAction.Fail, TransactionAction.Resume];
|
||||||
|
// Dialog States
|
||||||
|
case PurchaseStatus.DialogProposed:
|
||||||
|
return [];
|
||||||
|
// Final States
|
||||||
|
case PurchaseStatus.AbortedProposalRefused:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PurchaseStatus.Done:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PurchaseStatus.RepurchaseDetected:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PurchaseStatus.AbortedIncompletePayment:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PurchaseStatus.FailedClaim:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PurchaseStatus.FailedAbort:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function processPurchaseAutoRefund(
|
async function processPurchaseAutoRefund(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
purchase: PurchaseRecord,
|
purchase: PurchaseRecord,
|
||||||
|
@ -79,6 +79,7 @@ import {
|
|||||||
TransactionMajorState,
|
TransactionMajorState,
|
||||||
TransactionMinorState,
|
TransactionMinorState,
|
||||||
TalerPreciseTimestamp,
|
TalerPreciseTimestamp,
|
||||||
|
TransactionAction,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { SpendCoinDetails } from "../crypto/cryptoImplementation.js";
|
import { SpendCoinDetails } from "../crypto/cryptoImplementation.js";
|
||||||
import {
|
import {
|
||||||
@ -2008,7 +2009,36 @@ export function computePeerPushDebitTransactionState(
|
|||||||
case PeerPushPaymentInitiationStatus.Failed:
|
case PeerPushPaymentInitiationStatus.Failed:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Failed,
|
major: TransactionMajorState.Failed,
|
||||||
}
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function computePeerPushDebitTransactionActions(
|
||||||
|
ppiRecord: PeerPushPaymentInitiationRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (ppiRecord.status) {
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingReady:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPushPaymentInitiationStatus.Aborted:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingRefresh:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedReady:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case PeerPushPaymentInitiationStatus.Done:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPushPaymentInitiationStatus.Failed:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2072,7 +2102,7 @@ export async function abortPeerPushDebitTransaction(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingPeerPushDebitTransaction(
|
export async function failPeerPushDebitTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
pursePub: string,
|
pursePub: string,
|
||||||
) {
|
) {
|
||||||
@ -2316,8 +2346,7 @@ export async function abortPeerPullDebitTransaction(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function failPeerPullDebitTransaction(
|
||||||
export async function cancelAbortingPeerPullDebitTransaction(
|
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPullPaymentIncomingId: string,
|
peerPullPaymentIncomingId: string,
|
||||||
) {
|
) {
|
||||||
@ -2501,7 +2530,6 @@ export async function suspendPeerPushCreditTransaction(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function abortPeerPushCreditTransaction(
|
export async function abortPeerPushCreditTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPushPaymentIncomingId: string,
|
peerPushPaymentIncomingId: string,
|
||||||
@ -2568,7 +2596,7 @@ export async function abortPeerPushCreditTransaction(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingPeerPushCreditTransaction(
|
export async function failPeerPushCreditTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
peerPushPaymentIncomingId: string,
|
peerPushPaymentIncomingId: string,
|
||||||
) {
|
) {
|
||||||
@ -2765,7 +2793,7 @@ export async function abortPeerPullCreditTransaction(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingPeerPullCreditTransaction(
|
export async function failPeerPullCreditTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
pursePub: string,
|
pursePub: string,
|
||||||
) {
|
) {
|
||||||
@ -2996,12 +3024,41 @@ export function computePeerPushCreditTransactionState(
|
|||||||
};
|
};
|
||||||
case PeerPushPaymentIncomingStatus.Aborted:
|
case PeerPushPaymentIncomingStatus.Aborted:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Aborted
|
major: TransactionMajorState.Aborted,
|
||||||
};
|
};
|
||||||
case PeerPushPaymentIncomingStatus.Failed:
|
case PeerPushPaymentIncomingStatus.Failed:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Failed,
|
major: TransactionMajorState.Failed,
|
||||||
}
|
};
|
||||||
|
default:
|
||||||
|
assertUnreachable(pushCreditRecord.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function computePeerPushCreditTransactionActions(
|
||||||
|
pushCreditRecord: PeerPushPaymentIncomingRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (pushCreditRecord.status) {
|
||||||
|
case PeerPushPaymentIncomingStatus.DialogProposed:
|
||||||
|
return [];
|
||||||
|
case PeerPushPaymentIncomingStatus.PendingMerge:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPushPaymentIncomingStatus.Done:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPushPaymentIncomingStatus.PendingMergeKycRequired:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPushPaymentIncomingStatus.PendingWithdrawing:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
case PeerPushPaymentIncomingStatus.SuspendedMerge:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PeerPushPaymentIncomingStatus.SuspendedMergeKycRequired:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PeerPushPaymentIncomingStatus.SuspendedWithdrawing:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
case PeerPushPaymentIncomingStatus.Aborted:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPushPaymentIncomingStatus.Failed:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
default:
|
default:
|
||||||
assertUnreachable(pushCreditRecord.status);
|
assertUnreachable(pushCreditRecord.status);
|
||||||
}
|
}
|
||||||
@ -3076,6 +3133,39 @@ export function computePeerPullCreditTransactionState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function computePeerPullCreditTransactionActions(
|
||||||
|
pullCreditRecord: PeerPullPaymentInitiationRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (pullCreditRecord.status) {
|
||||||
|
case PeerPullPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPullPaymentInitiationStatus.PendingMergeKycRequired:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPullPaymentInitiationStatus.PendingReady:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPullPaymentInitiationStatus.DonePurseDeposited:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPullPaymentInitiationStatus.PendingWithdrawing:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPullPaymentInitiationStatus.SuspendedCreatePurse:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PeerPullPaymentInitiationStatus.SuspendedReady:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Resume];
|
||||||
|
case PeerPullPaymentInitiationStatus.SuspendedWithdrawing:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
case PeerPullPaymentInitiationStatus.SuspendedMergeKycRequired:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
case PeerPullPaymentInitiationStatus.Aborted:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPullPaymentInitiationStatus.AbortingDeletePurse:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
case PeerPullPaymentInitiationStatus.Failed:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPullPaymentInitiationStatus.SuspendedAbortingDeletePurse:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function computePeerPullDebitTransactionState(
|
export function computePeerPullDebitTransactionState(
|
||||||
pullDebitRecord: PeerPullPaymentIncomingRecord,
|
pullDebitRecord: PeerPullPaymentIncomingRecord,
|
||||||
): TransactionState {
|
): TransactionState {
|
||||||
@ -3119,3 +3209,26 @@ export function computePeerPullDebitTransactionState(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function computePeerPullDebitTransactionActions(
|
||||||
|
pullDebitRecord: PeerPullPaymentIncomingRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (pullDebitRecord.status) {
|
||||||
|
case PeerPullDebitRecordStatus.DialogProposed:
|
||||||
|
return [];
|
||||||
|
case PeerPullDebitRecordStatus.PendingDeposit:
|
||||||
|
return [TransactionAction.Abort, TransactionAction.Suspend];
|
||||||
|
case PeerPullDebitRecordStatus.DonePaid:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPullDebitRecordStatus.SuspendedDeposit:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case PeerPullDebitRecordStatus.Aborted:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPullDebitRecordStatus.AbortingRefresh:
|
||||||
|
return [TransactionAction.Fail, TransactionAction.Suspend];
|
||||||
|
case PeerPullDebitRecordStatus.Failed:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case PeerPullDebitRecordStatus.SuspendedAbortingRefresh:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -50,6 +50,7 @@ import {
|
|||||||
TalerErrorDetail,
|
TalerErrorDetail,
|
||||||
TalerPreciseTimestamp,
|
TalerPreciseTimestamp,
|
||||||
TalerProtocolTimestamp,
|
TalerProtocolTimestamp,
|
||||||
|
TransactionAction,
|
||||||
TransactionMajorState,
|
TransactionMajorState,
|
||||||
TransactionState,
|
TransactionState,
|
||||||
TransactionType,
|
TransactionType,
|
||||||
@ -96,7 +97,10 @@ import {
|
|||||||
PendingTaskType,
|
PendingTaskType,
|
||||||
WalletConfig,
|
WalletConfig,
|
||||||
} from "../index.js";
|
} from "../index.js";
|
||||||
import { constructTransactionIdentifier, notifyTransition } from "./transactions.js";
|
import {
|
||||||
|
constructTransactionIdentifier,
|
||||||
|
notifyTransition,
|
||||||
|
} from "./transactions.js";
|
||||||
|
|
||||||
const logger = new Logger("refresh.ts");
|
const logger = new Logger("refresh.ts");
|
||||||
|
|
||||||
@ -1076,8 +1080,12 @@ export async function createRefreshGroup(
|
|||||||
* Timestamp after which the wallet would do the next check for an auto-refresh.
|
* Timestamp after which the wallet would do the next check for an auto-refresh.
|
||||||
*/
|
*/
|
||||||
function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime {
|
function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime {
|
||||||
const expireWithdraw = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw);
|
const expireWithdraw = AbsoluteTime.fromProtocolTimestamp(
|
||||||
const expireDeposit = AbsoluteTime.fromProtocolTimestamp(d.stampExpireDeposit);
|
d.stampExpireWithdraw,
|
||||||
|
);
|
||||||
|
const expireDeposit = AbsoluteTime.fromProtocolTimestamp(
|
||||||
|
d.stampExpireDeposit,
|
||||||
|
);
|
||||||
const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit);
|
const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit);
|
||||||
const deltaDiv = durationMul(delta, 0.75);
|
const deltaDiv = durationMul(delta, 0.75);
|
||||||
return AbsoluteTime.addDuration(expireWithdraw, deltaDiv);
|
return AbsoluteTime.addDuration(expireWithdraw, deltaDiv);
|
||||||
@ -1087,8 +1095,12 @@ function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime {
|
|||||||
* Timestamp after which the wallet would do an auto-refresh.
|
* Timestamp after which the wallet would do an auto-refresh.
|
||||||
*/
|
*/
|
||||||
function getAutoRefreshExecuteThreshold(d: DenominationRecord): AbsoluteTime {
|
function getAutoRefreshExecuteThreshold(d: DenominationRecord): AbsoluteTime {
|
||||||
const expireWithdraw = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw);
|
const expireWithdraw = AbsoluteTime.fromProtocolTimestamp(
|
||||||
const expireDeposit = AbsoluteTime.fromProtocolTimestamp(d.stampExpireDeposit);
|
d.stampExpireWithdraw,
|
||||||
|
);
|
||||||
|
const expireDeposit = AbsoluteTime.fromProtocolTimestamp(
|
||||||
|
d.stampExpireDeposit,
|
||||||
|
);
|
||||||
const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit);
|
const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit);
|
||||||
const deltaDiv = durationMul(delta, 0.5);
|
const deltaDiv = durationMul(delta, 0.5);
|
||||||
return AbsoluteTime.addDuration(expireWithdraw, deltaDiv);
|
return AbsoluteTime.addDuration(expireWithdraw, deltaDiv);
|
||||||
@ -1175,7 +1187,8 @@ export async function autoRefresh(
|
|||||||
logger.info(
|
logger.info(
|
||||||
`next refresh check at ${AbsoluteTime.toIsoString(minCheckThreshold)}`,
|
`next refresh check at ${AbsoluteTime.toIsoString(minCheckThreshold)}`,
|
||||||
);
|
);
|
||||||
exchange.nextRefreshCheck = AbsoluteTime.toPreciseTimestamp(minCheckThreshold);
|
exchange.nextRefreshCheck =
|
||||||
|
AbsoluteTime.toPreciseTimestamp(minCheckThreshold);
|
||||||
await tx.exchanges.put(exchange);
|
await tx.exchanges.put(exchange);
|
||||||
});
|
});
|
||||||
return OperationAttemptResult.finishedEmpty();
|
return OperationAttemptResult.finishedEmpty();
|
||||||
@ -1204,6 +1217,21 @@ export function computeRefreshTransactionState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function computeRefreshTransactionActions(
|
||||||
|
rg: RefreshGroupRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (rg.operationStatus) {
|
||||||
|
case RefreshOperationStatus.Finished:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case RefreshOperationStatus.Failed:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case RefreshOperationStatus.Pending:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
case RefreshOperationStatus.Suspended:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function suspendRefreshGroup(
|
export async function suspendRefreshGroup(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
refreshGroupId: string,
|
refreshGroupId: string,
|
||||||
@ -1292,7 +1320,7 @@ export async function resumeRefreshGroup(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingRefreshGroup(
|
export async function failRefreshGroup(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
refreshGroupId: string,
|
refreshGroupId: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@ -1321,7 +1349,7 @@ export async function abortRefreshGroup(
|
|||||||
let newStatus: RefreshOperationStatus | undefined;
|
let newStatus: RefreshOperationStatus | undefined;
|
||||||
switch (dg.operationStatus) {
|
switch (dg.operationStatus) {
|
||||||
case RefreshOperationStatus.Finished:
|
case RefreshOperationStatus.Finished:
|
||||||
break;;
|
break;
|
||||||
case RefreshOperationStatus.Pending:
|
case RefreshOperationStatus.Pending:
|
||||||
case RefreshOperationStatus.Suspended:
|
case RefreshOperationStatus.Suspended:
|
||||||
newStatus = RefreshOperationStatus.Failed;
|
newStatus = RefreshOperationStatus.Failed;
|
||||||
|
@ -36,6 +36,7 @@ import {
|
|||||||
TalerPreciseTimestamp,
|
TalerPreciseTimestamp,
|
||||||
TalerProtocolTimestamp,
|
TalerProtocolTimestamp,
|
||||||
TipPlanchetDetail,
|
TipPlanchetDetail,
|
||||||
|
TransactionAction,
|
||||||
TransactionMajorState,
|
TransactionMajorState,
|
||||||
TransactionMinorState,
|
TransactionMinorState,
|
||||||
TransactionState,
|
TransactionState,
|
||||||
@ -111,6 +112,24 @@ export function computeTipTransactionStatus(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function computeTipTransactionActions(
|
||||||
|
tipRecord: TipRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (tipRecord.status) {
|
||||||
|
case TipRecordStatus.Done:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case TipRecordStatus.Aborted:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case TipRecordStatus.PendingPickup:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
case TipRecordStatus.SuspendidPickup:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
default:
|
||||||
|
assertUnreachable(tipRecord.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function prepareTip(
|
export async function prepareTip(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
talerTipUri: string,
|
talerTipUri: string,
|
||||||
@ -526,7 +545,7 @@ export async function resumeTipTransaction(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingTipTransaction(
|
export async function failTipTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
walletTipId: string,
|
walletTipId: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
@ -73,32 +73,34 @@ import { constructTaskIdentifier, TaskIdentifiers } from "../util/retries.js";
|
|||||||
import { resetOperationTimeout, TombstoneTag } from "./common.js";
|
import { resetOperationTimeout, TombstoneTag } from "./common.js";
|
||||||
import {
|
import {
|
||||||
abortDepositGroup,
|
abortDepositGroup,
|
||||||
cancelAbortingDepositGroup,
|
failDepositTransaction,
|
||||||
computeDepositTransactionStatus,
|
computeDepositTransactionStatus,
|
||||||
deleteDepositGroup,
|
deleteDepositGroup,
|
||||||
resumeDepositGroup,
|
resumeDepositGroup,
|
||||||
suspendDepositGroup,
|
suspendDepositGroup,
|
||||||
|
computeDepositTransactionActions,
|
||||||
} from "./deposits.js";
|
} from "./deposits.js";
|
||||||
import { getExchangeDetails } from "./exchanges.js";
|
import { getExchangeDetails } from "./exchanges.js";
|
||||||
import {
|
import {
|
||||||
abortPayMerchant,
|
abortPayMerchant,
|
||||||
cancelAbortingPaymentTransaction,
|
failPaymentTransaction,
|
||||||
computePayMerchantTransactionState,
|
computePayMerchantTransactionState,
|
||||||
computeRefundTransactionState,
|
computeRefundTransactionState,
|
||||||
expectProposalDownload,
|
expectProposalDownload,
|
||||||
extractContractData,
|
extractContractData,
|
||||||
resumePayMerchant,
|
resumePayMerchant,
|
||||||
suspendPayMerchant,
|
suspendPayMerchant,
|
||||||
|
computePayMerchantTransactionActions,
|
||||||
} from "./pay-merchant.js";
|
} from "./pay-merchant.js";
|
||||||
import {
|
import {
|
||||||
abortPeerPullCreditTransaction,
|
abortPeerPullCreditTransaction,
|
||||||
abortPeerPullDebitTransaction,
|
abortPeerPullDebitTransaction,
|
||||||
abortPeerPushCreditTransaction,
|
abortPeerPushCreditTransaction,
|
||||||
abortPeerPushDebitTransaction,
|
abortPeerPushDebitTransaction,
|
||||||
cancelAbortingPeerPullCreditTransaction,
|
failPeerPullCreditTransaction,
|
||||||
cancelAbortingPeerPullDebitTransaction,
|
failPeerPullDebitTransaction,
|
||||||
cancelAbortingPeerPushCreditTransaction,
|
failPeerPushCreditTransaction,
|
||||||
cancelAbortingPeerPushDebitTransaction,
|
failPeerPushDebitTransaction,
|
||||||
computePeerPullCreditTransactionState,
|
computePeerPullCreditTransactionState,
|
||||||
computePeerPullDebitTransactionState,
|
computePeerPullDebitTransactionState,
|
||||||
computePeerPushCreditTransactionState,
|
computePeerPushCreditTransactionState,
|
||||||
@ -111,28 +113,35 @@ import {
|
|||||||
suspendPeerPullDebitTransaction,
|
suspendPeerPullDebitTransaction,
|
||||||
suspendPeerPushCreditTransaction,
|
suspendPeerPushCreditTransaction,
|
||||||
suspendPeerPushDebitTransaction,
|
suspendPeerPushDebitTransaction,
|
||||||
|
computePeerPushDebitTransactionActions,
|
||||||
|
computePeerPullDebitTransactionActions,
|
||||||
|
computePeerPullCreditTransactionActions,
|
||||||
|
computePeerPushCreditTransactionActions,
|
||||||
} from "./pay-peer.js";
|
} from "./pay-peer.js";
|
||||||
import {
|
import {
|
||||||
abortRefreshGroup,
|
abortRefreshGroup,
|
||||||
cancelAbortingRefreshGroup,
|
failRefreshGroup,
|
||||||
computeRefreshTransactionState,
|
computeRefreshTransactionState,
|
||||||
resumeRefreshGroup,
|
resumeRefreshGroup,
|
||||||
suspendRefreshGroup,
|
suspendRefreshGroup,
|
||||||
|
computeRefreshTransactionActions,
|
||||||
} from "./refresh.js";
|
} from "./refresh.js";
|
||||||
import {
|
import {
|
||||||
abortTipTransaction,
|
abortTipTransaction,
|
||||||
cancelAbortingTipTransaction,
|
failTipTransaction,
|
||||||
computeTipTransactionStatus,
|
computeTipTransactionStatus,
|
||||||
resumeTipTransaction,
|
resumeTipTransaction,
|
||||||
suspendTipTransaction,
|
suspendTipTransaction,
|
||||||
|
computeTipTransactionActions,
|
||||||
} from "./tip.js";
|
} from "./tip.js";
|
||||||
import {
|
import {
|
||||||
abortWithdrawalTransaction,
|
abortWithdrawalTransaction,
|
||||||
augmentPaytoUrisForWithdrawal,
|
augmentPaytoUrisForWithdrawal,
|
||||||
cancelAbortingWithdrawalTransaction,
|
failWithdrawalTransaction,
|
||||||
computeWithdrawalTransactionStatus,
|
computeWithdrawalTransactionStatus,
|
||||||
resumeWithdrawalTransaction,
|
resumeWithdrawalTransaction,
|
||||||
suspendWithdrawalTransaction,
|
suspendWithdrawalTransaction,
|
||||||
|
computeWithdrawalTransactionActions,
|
||||||
} from "./withdraw.js";
|
} from "./withdraw.js";
|
||||||
|
|
||||||
const logger = new Logger("taler-wallet-core:transactions.ts");
|
const logger = new Logger("taler-wallet-core:transactions.ts");
|
||||||
@ -429,6 +438,7 @@ function buildTransactionForPushPaymentDebit(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPushDebit,
|
type: TransactionType.PeerPushDebit,
|
||||||
txState: computePeerPushDebitTransactionState(pi),
|
txState: computePeerPushDebitTransactionState(pi),
|
||||||
|
txActions: computePeerPushDebitTransactionActions(pi),
|
||||||
amountEffective: pi.totalCost,
|
amountEffective: pi.totalCost,
|
||||||
amountRaw: pi.amount,
|
amountRaw: pi.amount,
|
||||||
exchangeBaseUrl: pi.exchangeBaseUrl,
|
exchangeBaseUrl: pi.exchangeBaseUrl,
|
||||||
@ -456,6 +466,7 @@ function buildTransactionForPullPaymentDebit(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPullDebit,
|
type: TransactionType.PeerPullDebit,
|
||||||
txState: computePeerPullDebitTransactionState(pi),
|
txState: computePeerPullDebitTransactionState(pi),
|
||||||
|
txActions: computePeerPullDebitTransactionActions(pi),
|
||||||
amountEffective: pi.coinSel?.totalCost
|
amountEffective: pi.coinSel?.totalCost
|
||||||
? pi.coinSel?.totalCost
|
? pi.coinSel?.totalCost
|
||||||
: Amounts.stringify(pi.contractTerms.amount),
|
: Amounts.stringify(pi.contractTerms.amount),
|
||||||
@ -503,6 +514,7 @@ function buildTransactionForPeerPullCredit(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPullCredit,
|
type: TransactionType.PeerPullCredit,
|
||||||
txState: computePeerPullCreditTransactionState(pullCredit),
|
txState: computePeerPullCreditTransactionState(pullCredit),
|
||||||
|
txActions: computePeerPullCreditTransactionActions(pullCredit),
|
||||||
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
|
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
|
||||||
amountRaw: Amounts.stringify(wsr.instructedAmount),
|
amountRaw: Amounts.stringify(wsr.instructedAmount),
|
||||||
exchangeBaseUrl: wsr.exchangeBaseUrl,
|
exchangeBaseUrl: wsr.exchangeBaseUrl,
|
||||||
@ -533,6 +545,7 @@ function buildTransactionForPeerPullCredit(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPullCredit,
|
type: TransactionType.PeerPullCredit,
|
||||||
txState: computePeerPullCreditTransactionState(pullCredit),
|
txState: computePeerPullCreditTransactionState(pullCredit),
|
||||||
|
txActions: computePeerPullCreditTransactionActions(pullCredit),
|
||||||
amountEffective: Amounts.stringify(pullCredit.estimatedAmountEffective),
|
amountEffective: Amounts.stringify(pullCredit.estimatedAmountEffective),
|
||||||
amountRaw: Amounts.stringify(peerContractTerms.amount),
|
amountRaw: Amounts.stringify(peerContractTerms.amount),
|
||||||
exchangeBaseUrl: pullCredit.exchangeBaseUrl,
|
exchangeBaseUrl: pullCredit.exchangeBaseUrl,
|
||||||
@ -569,6 +582,7 @@ function buildTransactionForPeerPushCredit(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPushCredit,
|
type: TransactionType.PeerPushCredit,
|
||||||
txState: computePeerPushCreditTransactionState(pushInc),
|
txState: computePeerPushCreditTransactionState(pushInc),
|
||||||
|
txActions: computePeerPushCreditTransactionActions(pushInc),
|
||||||
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
|
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
|
||||||
amountRaw: Amounts.stringify(wsr.instructedAmount),
|
amountRaw: Amounts.stringify(wsr.instructedAmount),
|
||||||
exchangeBaseUrl: wsr.exchangeBaseUrl,
|
exchangeBaseUrl: wsr.exchangeBaseUrl,
|
||||||
@ -588,6 +602,7 @@ function buildTransactionForPeerPushCredit(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPushCredit,
|
type: TransactionType.PeerPushCredit,
|
||||||
txState: computePeerPushCreditTransactionState(pushInc),
|
txState: computePeerPushCreditTransactionState(pushInc),
|
||||||
|
txActions: computePeerPushCreditTransactionActions(pushInc),
|
||||||
// FIXME: This is wrong, needs to consider fees!
|
// FIXME: This is wrong, needs to consider fees!
|
||||||
amountEffective: Amounts.stringify(peerContractTerms.amount),
|
amountEffective: Amounts.stringify(peerContractTerms.amount),
|
||||||
amountRaw: Amounts.stringify(peerContractTerms.amount),
|
amountRaw: Amounts.stringify(peerContractTerms.amount),
|
||||||
@ -615,6 +630,7 @@ function buildTransactionForBankIntegratedWithdraw(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.Withdrawal,
|
type: TransactionType.Withdrawal,
|
||||||
txState: computeWithdrawalTransactionStatus(wgRecord),
|
txState: computeWithdrawalTransactionStatus(wgRecord),
|
||||||
|
txActions: computeWithdrawalTransactionActions(wgRecord),
|
||||||
amountEffective: Amounts.stringify(wgRecord.denomsSel.totalCoinValue),
|
amountEffective: Amounts.stringify(wgRecord.denomsSel.totalCoinValue),
|
||||||
amountRaw: Amounts.stringify(wgRecord.instructedAmount),
|
amountRaw: Amounts.stringify(wgRecord.instructedAmount),
|
||||||
withdrawalDetails: {
|
withdrawalDetails: {
|
||||||
@ -656,6 +672,7 @@ function buildTransactionForManualWithdraw(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.Withdrawal,
|
type: TransactionType.Withdrawal,
|
||||||
txState: computeWithdrawalTransactionStatus(withdrawalGroup),
|
txState: computeWithdrawalTransactionStatus(withdrawalGroup),
|
||||||
|
txActions: computeWithdrawalTransactionActions(withdrawalGroup),
|
||||||
amountEffective: Amounts.stringify(
|
amountEffective: Amounts.stringify(
|
||||||
withdrawalGroup.denomsSel.totalCoinValue,
|
withdrawalGroup.denomsSel.totalCoinValue,
|
||||||
),
|
),
|
||||||
@ -706,6 +723,7 @@ function buildTransactionForRefund(
|
|||||||
refundGroupId: refundRecord.refundGroupId,
|
refundGroupId: refundRecord.refundGroupId,
|
||||||
}),
|
}),
|
||||||
txState: computeRefundTransactionState(refundRecord),
|
txState: computeRefundTransactionState(refundRecord),
|
||||||
|
txActions: [],
|
||||||
paymentInfo,
|
paymentInfo,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -725,6 +743,7 @@ function buildTransactionForRefresh(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.Refresh,
|
type: TransactionType.Refresh,
|
||||||
txState: computeRefreshTransactionState(refreshGroupRecord),
|
txState: computeRefreshTransactionState(refreshGroupRecord),
|
||||||
|
txActions: computeRefreshTransactionActions(refreshGroupRecord),
|
||||||
refreshReason: refreshGroupRecord.reason,
|
refreshReason: refreshGroupRecord.reason,
|
||||||
amountEffective: Amounts.stringify(
|
amountEffective: Amounts.stringify(
|
||||||
Amounts.zeroOfCurrency(refreshGroupRecord.currency),
|
Amounts.zeroOfCurrency(refreshGroupRecord.currency),
|
||||||
@ -759,6 +778,7 @@ function buildTransactionForDeposit(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.Deposit,
|
type: TransactionType.Deposit,
|
||||||
txState: computeDepositTransactionStatus(dg),
|
txState: computeDepositTransactionStatus(dg),
|
||||||
|
txActions: computeDepositTransactionActions(dg),
|
||||||
amountRaw: Amounts.stringify(dg.effectiveDepositAmount),
|
amountRaw: Amounts.stringify(dg.effectiveDepositAmount),
|
||||||
amountEffective: Amounts.stringify(dg.totalPayCost),
|
amountEffective: Amounts.stringify(dg.totalPayCost),
|
||||||
timestamp: dg.timestampCreated,
|
timestamp: dg.timestampCreated,
|
||||||
@ -791,6 +811,7 @@ function buildTransactionForTip(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.Tip,
|
type: TransactionType.Tip,
|
||||||
txState: computeTipTransactionStatus(tipRecord),
|
txState: computeTipTransactionStatus(tipRecord),
|
||||||
|
txActions: computeTipTransactionActions(tipRecord),
|
||||||
amountEffective: Amounts.stringify(tipRecord.tipAmountEffective),
|
amountEffective: Amounts.stringify(tipRecord.tipAmountEffective),
|
||||||
amountRaw: Amounts.stringify(tipRecord.tipAmountRaw),
|
amountRaw: Amounts.stringify(tipRecord.tipAmountRaw),
|
||||||
timestamp: tipRecord.acceptedTimestamp,
|
timestamp: tipRecord.acceptedTimestamp,
|
||||||
@ -860,6 +881,7 @@ async function buildTransactionForPurchase(
|
|||||||
return {
|
return {
|
||||||
type: TransactionType.Payment,
|
type: TransactionType.Payment,
|
||||||
txState: computePayMerchantTransactionState(purchaseRecord),
|
txState: computePayMerchantTransactionState(purchaseRecord),
|
||||||
|
txActions: computePayMerchantTransactionActions(purchaseRecord),
|
||||||
amountRaw: Amounts.stringify(contractData.amount),
|
amountRaw: Amounts.stringify(contractData.amount),
|
||||||
amountEffective: Amounts.stringify(purchaseRecord.payInfo.totalPayCost),
|
amountEffective: Amounts.stringify(purchaseRecord.payInfo.totalPayCost),
|
||||||
totalRefundRaw: Amounts.stringify(zero), // FIXME!
|
totalRefundRaw: Amounts.stringify(zero), // FIXME!
|
||||||
@ -1493,7 +1515,7 @@ export async function suspendTransaction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingTransaction(
|
export async function failTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
transactionId: string,
|
transactionId: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@ -1503,34 +1525,34 @@ export async function cancelAbortingTransaction(
|
|||||||
}
|
}
|
||||||
switch (tx.tag) {
|
switch (tx.tag) {
|
||||||
case TransactionType.Deposit:
|
case TransactionType.Deposit:
|
||||||
await cancelAbortingDepositGroup(ws, tx.depositGroupId);
|
await failDepositTransaction(ws, tx.depositGroupId);
|
||||||
return;
|
return;
|
||||||
case TransactionType.InternalWithdrawal:
|
case TransactionType.InternalWithdrawal:
|
||||||
case TransactionType.Withdrawal:
|
case TransactionType.Withdrawal:
|
||||||
await cancelAbortingWithdrawalTransaction(ws, tx.withdrawalGroupId);
|
await failWithdrawalTransaction(ws, tx.withdrawalGroupId);
|
||||||
return;
|
return;
|
||||||
case TransactionType.Payment:
|
case TransactionType.Payment:
|
||||||
await cancelAbortingPaymentTransaction(ws, tx.proposalId);
|
await failPaymentTransaction(ws, tx.proposalId);
|
||||||
return;
|
return;
|
||||||
case TransactionType.Refund:
|
case TransactionType.Refund:
|
||||||
throw Error("can't do cancel-aborting on refund transaction");
|
throw Error("can't do cancel-aborting on refund transaction");
|
||||||
case TransactionType.Tip:
|
case TransactionType.Tip:
|
||||||
await cancelAbortingTipTransaction(ws, tx.walletTipId);
|
await failTipTransaction(ws, tx.walletTipId);
|
||||||
return;
|
return;
|
||||||
case TransactionType.Refresh:
|
case TransactionType.Refresh:
|
||||||
await cancelAbortingRefreshGroup(ws, tx.refreshGroupId);
|
await failRefreshGroup(ws, tx.refreshGroupId);
|
||||||
return;
|
return;
|
||||||
case TransactionType.PeerPullCredit:
|
case TransactionType.PeerPullCredit:
|
||||||
await cancelAbortingPeerPullCreditTransaction(ws, tx.pursePub);
|
await failPeerPullCreditTransaction(ws, tx.pursePub);
|
||||||
return;
|
return;
|
||||||
case TransactionType.PeerPullDebit:
|
case TransactionType.PeerPullDebit:
|
||||||
await cancelAbortingPeerPullDebitTransaction(ws, tx.peerPullPaymentIncomingId);
|
await failPeerPullDebitTransaction(ws, tx.peerPullPaymentIncomingId);
|
||||||
return;
|
return;
|
||||||
case TransactionType.PeerPushCredit:
|
case TransactionType.PeerPushCredit:
|
||||||
await cancelAbortingPeerPushCreditTransaction(ws, tx.peerPushPaymentIncomingId);
|
await failPeerPushCreditTransaction(ws, tx.peerPushPaymentIncomingId);
|
||||||
return;
|
return;
|
||||||
case TransactionType.PeerPushDebit:
|
case TransactionType.PeerPushDebit:
|
||||||
await cancelAbortingPeerPushDebitTransaction(ws, tx.pursePub);
|
await failPeerPushDebitTransaction(ws, tx.pursePub);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
assertUnreachable(tx);
|
assertUnreachable(tx);
|
||||||
|
@ -67,6 +67,7 @@ import {
|
|||||||
TransactionMajorState,
|
TransactionMajorState,
|
||||||
TransactionMinorState,
|
TransactionMinorState,
|
||||||
TalerPreciseTimestamp,
|
TalerPreciseTimestamp,
|
||||||
|
TransactionAction,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { EddsaKeypair } from "../crypto/cryptoImplementation.js";
|
import { EddsaKeypair } from "../crypto/cryptoImplementation.js";
|
||||||
import {
|
import {
|
||||||
@ -338,7 +339,7 @@ export async function abortWithdrawalTransaction(
|
|||||||
notifyTransition(ws, transactionId, transitionInfo);
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelAbortingWithdrawalTransaction(
|
export async function failWithdrawalTransaction(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
withdrawalGroupId: string,
|
withdrawalGroupId: string,
|
||||||
) {
|
) {
|
||||||
@ -483,6 +484,49 @@ export function computeWithdrawalTransactionStatus(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function computeWithdrawalTransactionActions(
|
||||||
|
wgRecord: WithdrawalGroupRecord,
|
||||||
|
): TransactionAction[] {
|
||||||
|
switch (wgRecord.status) {
|
||||||
|
case WithdrawalGroupStatus.FailedBankAborted:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case WithdrawalGroupStatus.Finished:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.PendingReady:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.PendingQueryingStatus:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.AbortingBank:
|
||||||
|
return [TransactionAction.Suspend, TransactionAction.Fail];
|
||||||
|
case WithdrawalGroupStatus.SuspendedAbortingBank:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Fail];
|
||||||
|
case WithdrawalGroupStatus.SuspendedQueryingStatus:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.SuspendedRegisteringBank:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort]
|
||||||
|
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.SuspendedReady:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.PendingAml:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.PendingKyc:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.SuspendedAml:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort];
|
||||||
|
case WithdrawalGroupStatus.SuspendedKyc:
|
||||||
|
return [TransactionAction.Resume, TransactionAction.Abort]
|
||||||
|
case WithdrawalGroupStatus.FailedAbortingBank:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
case WithdrawalGroupStatus.AbortedExchange:
|
||||||
|
return [TransactionAction.Delete];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get information about a withdrawal from
|
* Get information about a withdrawal from
|
||||||
* a taler://withdraw URI by asking the bank.
|
* a taler://withdraw URI by asking the bank.
|
||||||
|
@ -232,7 +232,7 @@ import {
|
|||||||
import { acceptTip, prepareTip, processTip } from "./operations/tip.js";
|
import { acceptTip, prepareTip, processTip } from "./operations/tip.js";
|
||||||
import {
|
import {
|
||||||
abortTransaction,
|
abortTransaction,
|
||||||
cancelAbortingTransaction,
|
failTransaction,
|
||||||
deleteTransaction,
|
deleteTransaction,
|
||||||
getTransactionById,
|
getTransactionById,
|
||||||
getTransactions,
|
getTransactions,
|
||||||
@ -1233,7 +1233,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
|
|||||||
}
|
}
|
||||||
case WalletApiOperation.CancelAbortingTransaction: {
|
case WalletApiOperation.CancelAbortingTransaction: {
|
||||||
const req = codecForCancelAbortingTransactionRequest().decode(payload);
|
const req = codecForCancelAbortingTransactionRequest().decode(payload);
|
||||||
await cancelAbortingTransaction(ws, req.transactionId);
|
await failTransaction(ws, req.transactionId);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
case WalletApiOperation.ResumeTransaction: {
|
case WalletApiOperation.ResumeTransaction: {
|
||||||
|
Loading…
Reference in New Issue
Block a user