DD37 wip
This commit is contained in:
parent
1b0bec0363
commit
60805f3ff8
@ -89,7 +89,6 @@ export enum TransactionMajorState {
|
|||||||
Aborting = "aborting",
|
Aborting = "aborting",
|
||||||
Aborted = "aborted",
|
Aborted = "aborted",
|
||||||
Suspended = "suspended",
|
Suspended = "suspended",
|
||||||
SuspendedDeletable = "suspended-deletable",
|
|
||||||
Dialog = "dialog",
|
Dialog = "dialog",
|
||||||
SuspendedAborting = "suspended-aborting",
|
SuspendedAborting = "suspended-aborting",
|
||||||
Failed = "failed",
|
Failed = "failed",
|
||||||
@ -105,6 +104,7 @@ export enum TransactionMinorState {
|
|||||||
Deposit = "deposit",
|
Deposit = "deposit",
|
||||||
KycRequired = "kyc",
|
KycRequired = "kyc",
|
||||||
AmlRequired = "aml",
|
AmlRequired = "aml",
|
||||||
|
MergeKycRequired = "merge-kyc",
|
||||||
Track = "track",
|
Track = "track",
|
||||||
Pay = "pay",
|
Pay = "pay",
|
||||||
RebindSession = "rebind-session",
|
RebindSession = "rebind-session",
|
||||||
@ -113,8 +113,13 @@ export enum TransactionMinorState {
|
|||||||
AutoRefund = "auto-refund",
|
AutoRefund = "auto-refund",
|
||||||
User = "user",
|
User = "user",
|
||||||
Bank = "bank",
|
Bank = "bank",
|
||||||
|
Exchange = "exchange",
|
||||||
ClaimProposal = "claim-proposal",
|
ClaimProposal = "claim-proposal",
|
||||||
CheckRefunds = "check-refunds",
|
CheckRefunds = "check-refunds",
|
||||||
|
CreatePurse = "create-purse",
|
||||||
|
DeletePurse = "delete-purse",
|
||||||
|
Ready = "ready",
|
||||||
|
Merge = "merge",
|
||||||
Repurchase = "repurchase",
|
Repurchase = "repurchase",
|
||||||
BankRegisterReserve = "bank-register-reserve",
|
BankRegisterReserve = "bank-register-reserve",
|
||||||
BankConfirmTransfer = "bank-confirm-transfer",
|
BankConfirmTransfer = "bank-confirm-transfer",
|
||||||
@ -122,6 +127,9 @@ export enum TransactionMinorState {
|
|||||||
ExchangeWaitReserve = "exchange-wait-reserve",
|
ExchangeWaitReserve = "exchange-wait-reserve",
|
||||||
AbortingBank = "aborting-bank",
|
AbortingBank = "aborting-bank",
|
||||||
Refused = "refused",
|
Refused = "refused",
|
||||||
|
Withdraw = "withdraw",
|
||||||
|
MerchantOrderProposed = "merchant-order-proposed",
|
||||||
|
Proposed = "proposed",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransactionsResponse {
|
export interface TransactionsResponse {
|
||||||
|
@ -444,7 +444,7 @@ transactionsCli
|
|||||||
});
|
});
|
||||||
|
|
||||||
transactionsCli
|
transactionsCli
|
||||||
.subcommand("cancelAbortingTransaction", "suspend", {
|
.subcommand("cancelAbortingTransaction", "cancel-aborting", {
|
||||||
help: "Cancel the attempt of properly aborting a transaction.",
|
help: "Cancel the attempt of properly aborting a transaction.",
|
||||||
})
|
})
|
||||||
.requiredArgument("transactionId", clk.STRING, {
|
.requiredArgument("transactionId", clk.STRING, {
|
||||||
|
@ -130,10 +130,10 @@ export enum OperationStatusRange {
|
|||||||
// Operations that need to be actively processed.
|
// Operations that need to be actively processed.
|
||||||
ACTIVE_START = 10,
|
ACTIVE_START = 10,
|
||||||
ACTIVE_END = 29,
|
ACTIVE_END = 29,
|
||||||
// Operations that need user input, but nothing can be done
|
// Operations that are suspended and might
|
||||||
// automatically.
|
// expire, but nothing else can be done.
|
||||||
USER_ATTENTION_START = 30,
|
SUSPENDED_START = 30,
|
||||||
USER_ATTENTION_END = 49,
|
SUSPENDED_END = 49,
|
||||||
// Operations that don't need any attention or processing.
|
// Operations that don't need any attention or processing.
|
||||||
DORMANT_START = 50,
|
DORMANT_START = 50,
|
||||||
DORMANT_END = 69,
|
DORMANT_END = 69,
|
||||||
@ -146,24 +146,24 @@ export enum WithdrawalGroupStatus {
|
|||||||
/**
|
/**
|
||||||
* Reserve must be registered with the bank.
|
* Reserve must be registered with the bank.
|
||||||
*/
|
*/
|
||||||
RegisteringBank = 10,
|
PendingRegisteringBank = 10,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We've registered reserve's information with the bank
|
* We've registered reserve's information with the bank
|
||||||
* and are now waiting for the user to confirm the withdraw
|
* and are now waiting for the user to confirm the withdraw
|
||||||
* with the bank (typically 2nd factor auth).
|
* with the bank (typically 2nd factor auth).
|
||||||
*/
|
*/
|
||||||
WaitConfirmBank = 11,
|
PendingWaitConfirmBank = 11,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Querying reserve status with the exchange.
|
* Querying reserve status with the exchange.
|
||||||
*/
|
*/
|
||||||
QueryingStatus = 12,
|
PendingQueryingStatus = 12,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ready for withdrawal.
|
* Ready for withdrawal.
|
||||||
*/
|
*/
|
||||||
Ready = 13,
|
PendingReady = 13,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are telling the bank that we don't want to complete
|
* We are telling the bank that we don't want to complete
|
||||||
@ -174,12 +174,20 @@ export enum WithdrawalGroupStatus {
|
|||||||
/**
|
/**
|
||||||
* Exchange wants KYC info from the user.
|
* Exchange wants KYC info from the user.
|
||||||
*/
|
*/
|
||||||
Kyc = 16,
|
PendingKyc = 16,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchange is doing AML checks.
|
* Exchange is doing AML checks.
|
||||||
*/
|
*/
|
||||||
Aml = 17,
|
PendingAml = 17,
|
||||||
|
|
||||||
|
SuspendedRegisteringBank = 30,
|
||||||
|
SuspendedWaitConfirmBank = 31,
|
||||||
|
SuspendedQueryingStatus = 32,
|
||||||
|
SuspendedReady = 33,
|
||||||
|
SuspendedAbortingBank = 34,
|
||||||
|
SuspendedKyc = 35,
|
||||||
|
SuspendedAml = 36,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The corresponding withdraw record has been created.
|
* The corresponding withdraw record has been created.
|
||||||
@ -191,16 +199,16 @@ export enum WithdrawalGroupStatus {
|
|||||||
/**
|
/**
|
||||||
* The bank aborted the withdrawal.
|
* The bank aborted the withdrawal.
|
||||||
*/
|
*/
|
||||||
BankAborted = 51,
|
FailedBankAborted = 51,
|
||||||
|
|
||||||
SuspendedRegisteringBank = 52,
|
|
||||||
SuspendedWaitConfirmBank = 53,
|
|
||||||
SuspendedQueryingStatus = 54,
|
|
||||||
SuspendedReady = 55,
|
|
||||||
SuspendedAbortingBank = 56,
|
|
||||||
SuspendedKyc = 57,
|
|
||||||
SuspendedAml = 58,
|
|
||||||
FailedAbortingBank = 59,
|
FailedAbortingBank = 59,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aborted in a state where we were supposed to
|
||||||
|
* talk to the exchange. Money might have been
|
||||||
|
* wired or not.
|
||||||
|
*/
|
||||||
|
AbortedExchange = 60
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1790,8 +1798,18 @@ export enum PeerPushPaymentInitiationStatus {
|
|||||||
/**
|
/**
|
||||||
* Initiated, but no purse created yet.
|
* Initiated, but no purse created yet.
|
||||||
*/
|
*/
|
||||||
Initiated = 10 /* ACTIVE_START */,
|
PendingCreatePurse = 10 /* ACTIVE_START */,
|
||||||
PurseCreated = 50 /* DORMANT_START */,
|
PendingReady = 11,
|
||||||
|
AbortingDeletePurse = 12,
|
||||||
|
AbortingRefresh = 13,
|
||||||
|
|
||||||
|
SuspendedCreatePurse = 30,
|
||||||
|
SuspendedReady = 31,
|
||||||
|
SuspendedAbortingDeletePurse = 32,
|
||||||
|
SuspendedAbortingRefresh = 33,
|
||||||
|
|
||||||
|
Done = 50 /* DORMANT_START */,
|
||||||
|
Aborted = 51,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PeerPushPaymentCoinSelection {
|
export interface PeerPushPaymentCoinSelection {
|
||||||
@ -1856,14 +1874,18 @@ export interface PeerPushPaymentInitiationRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum PeerPullPaymentInitiationStatus {
|
export enum PeerPullPaymentInitiationStatus {
|
||||||
Initial = 10 /* ACTIVE_START */,
|
PendingCreatePurse = 10 /* ACTIVE_START */,
|
||||||
/**
|
/**
|
||||||
* Purse created, waiting for the other party to accept the
|
* Purse created, waiting for the other party to accept the
|
||||||
* invoice and deposit money into it.
|
* invoice and deposit money into it.
|
||||||
*/
|
*/
|
||||||
PurseCreated = 11 /* ACTIVE_START + 1 */,
|
PendingReady = 11 /* ACTIVE_START + 1 */,
|
||||||
KycRequired = 12 /* ACTIVE_START + 2 */,
|
PendingMergeKycRequired = 12 /* ACTIVE_START + 2 */,
|
||||||
PurseDeposited = 50 /* DORMANT_START */,
|
PendingWithdrawing = 13,
|
||||||
|
SuspendedCreatePurse = 30,
|
||||||
|
SuspendedReady = 31,
|
||||||
|
SuspendedWithdrawing = 32,
|
||||||
|
DonePurseDeposited = 50 /* DORMANT_START */,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PeerPullPaymentInitiationRecord {
|
export interface PeerPullPaymentInitiationRecord {
|
||||||
@ -1921,12 +1943,13 @@ export interface PeerPullPaymentInitiationRecord {
|
|||||||
export enum PeerPushPaymentIncomingStatus {
|
export enum PeerPushPaymentIncomingStatus {
|
||||||
Proposed = 30 /* USER_ATTENTION_START */,
|
Proposed = 30 /* USER_ATTENTION_START */,
|
||||||
Accepted = 10 /* ACTIVE_START */,
|
Accepted = 10 /* ACTIVE_START */,
|
||||||
KycRequired = 11 /* ACTIVE_START + 1 */,
|
MergeKycRequired = 11 /* ACTIVE_START + 1 */,
|
||||||
/**
|
/**
|
||||||
* Merge was successful and withdrawal group has been created, now
|
* Merge was successful and withdrawal group has been created, now
|
||||||
* everything is in the hand of the withdrawal group.
|
* everything is in the hand of the withdrawal group.
|
||||||
*/
|
*/
|
||||||
WithdrawalCreated = 50 /* DORMANT_START */,
|
Withdrawing = 12,
|
||||||
|
Done = 50 /* DORMANT_START */,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,7 +177,7 @@ export interface InternalWalletState {
|
|||||||
*
|
*
|
||||||
* Used to allow processing of new work faster.
|
* Used to allow processing of new work faster.
|
||||||
*/
|
*/
|
||||||
latch: AsyncCondition;
|
workAvailable: AsyncCondition;
|
||||||
|
|
||||||
listeners: NotificationListener[];
|
listeners: NotificationListener[];
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ export async function importBackup(
|
|||||||
reservePub,
|
reservePub,
|
||||||
status: backupWg.timestamp_finish
|
status: backupWg.timestamp_finish
|
||||||
? WithdrawalGroupStatus.Finished
|
? WithdrawalGroupStatus.Finished
|
||||||
: WithdrawalGroupStatus.QueryingStatus, // FIXME!
|
: WithdrawalGroupStatus.PendingQueryingStatus, // FIXME!
|
||||||
timestampStart: backupWg.timestamp_created,
|
timestampStart: backupWg.timestamp_created,
|
||||||
wgInfo,
|
wgInfo,
|
||||||
restrictAge: backupWg.restrict_age,
|
restrictAge: backupWg.restrict_age,
|
||||||
|
@ -492,7 +492,7 @@ export function runLongpollAsync(
|
|||||||
if (!res.ready) {
|
if (!res.ready) {
|
||||||
await storeOperationPending(ws, retryTag);
|
await storeOperationPending(ws, retryTag);
|
||||||
}
|
}
|
||||||
ws.latch.trigger();
|
ws.workAvailable.trigger();
|
||||||
};
|
};
|
||||||
asyncFn();
|
asyncFn();
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ export async function resumeDepositGroup(
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
ws.latch.trigger();
|
ws.workAvailable.trigger();
|
||||||
if (res) {
|
if (res) {
|
||||||
ws.notify({
|
ws.notify({
|
||||||
type: NotificationType.TransactionStateTransition,
|
type: NotificationType.TransactionStateTransition,
|
||||||
@ -301,7 +301,7 @@ export async function abortDepositGroup(
|
|||||||
});
|
});
|
||||||
stopLongpolling(ws, retryTag);
|
stopLongpolling(ws, retryTag);
|
||||||
// Need to process the operation again.
|
// Need to process the operation again.
|
||||||
ws.latch.trigger();
|
ws.workAvailable.trigger();
|
||||||
if (res) {
|
if (res) {
|
||||||
ws.notify({
|
ws.notify({
|
||||||
type: NotificationType.TransactionStateTransition,
|
type: NotificationType.TransactionStateTransition,
|
||||||
|
@ -2410,7 +2410,7 @@ export async function processPurchaseQueryRefund(
|
|||||||
return OperationAttemptResult.finishedEmpty();
|
return OperationAttemptResult.finishedEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function abortPay(
|
export async function abortPayMerchant(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
cancelImmediately?: boolean,
|
cancelImmediately?: boolean,
|
||||||
@ -2499,6 +2499,7 @@ export function computePayMerchantTransactionState(
|
|||||||
case PurchaseStatus.Proposed:
|
case PurchaseStatus.Proposed:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Dialog,
|
major: TransactionMajorState.Dialog,
|
||||||
|
minor: TransactionMinorState.MerchantOrderProposed,
|
||||||
};
|
};
|
||||||
case PurchaseStatus.ProposalDownloadFailed:
|
case PurchaseStatus.ProposalDownloadFailed:
|
||||||
return {
|
return {
|
||||||
|
@ -75,20 +75,21 @@ import {
|
|||||||
NotificationType,
|
NotificationType,
|
||||||
HttpStatusCode,
|
HttpStatusCode,
|
||||||
codecForWalletKycUuid,
|
codecForWalletKycUuid,
|
||||||
WalletKycUuid,
|
TransactionState,
|
||||||
|
TransactionMajorState,
|
||||||
|
TransactionMinorState,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { SpendCoinDetails } from "../crypto/cryptoImplementation.js";
|
import { SpendCoinDetails } from "../crypto/cryptoImplementation.js";
|
||||||
import {
|
import {
|
||||||
DenominationRecord,
|
DenominationRecord,
|
||||||
KycPendingInfo,
|
PeerPullPaymentIncomingRecord,
|
||||||
KycUserType,
|
|
||||||
OperationStatus,
|
|
||||||
PeerPullPaymentIncomingStatus,
|
PeerPullPaymentIncomingStatus,
|
||||||
PeerPullPaymentInitiationRecord,
|
PeerPullPaymentInitiationRecord,
|
||||||
PeerPullPaymentInitiationStatus,
|
PeerPullPaymentInitiationStatus,
|
||||||
PeerPushPaymentCoinSelection,
|
PeerPushPaymentCoinSelection,
|
||||||
PeerPushPaymentIncomingRecord,
|
PeerPushPaymentIncomingRecord,
|
||||||
PeerPushPaymentIncomingStatus,
|
PeerPushPaymentIncomingStatus,
|
||||||
|
PeerPushPaymentInitiationRecord,
|
||||||
PeerPushPaymentInitiationStatus,
|
PeerPushPaymentInitiationStatus,
|
||||||
ReserveRecord,
|
ReserveRecord,
|
||||||
WithdrawalGroupStatus,
|
WithdrawalGroupStatus,
|
||||||
@ -98,7 +99,6 @@ import { TalerError } from "@gnu-taler/taler-util";
|
|||||||
import { InternalWalletState } from "../internal-wallet-state.js";
|
import { InternalWalletState } from "../internal-wallet-state.js";
|
||||||
import {
|
import {
|
||||||
LongpollResult,
|
LongpollResult,
|
||||||
makeTransactionId,
|
|
||||||
resetOperationTimeout,
|
resetOperationTimeout,
|
||||||
runLongpollAsync,
|
runLongpollAsync,
|
||||||
runOperationWithErrorReporting,
|
runOperationWithErrorReporting,
|
||||||
@ -128,8 +128,10 @@ import {
|
|||||||
import { PendingTaskType } from "../pending-types.js";
|
import { PendingTaskType } from "../pending-types.js";
|
||||||
import {
|
import {
|
||||||
constructTransactionIdentifier,
|
constructTransactionIdentifier,
|
||||||
|
notifyTransition,
|
||||||
stopLongpolling,
|
stopLongpolling,
|
||||||
} from "./transactions.js";
|
} from "./transactions.js";
|
||||||
|
import { assertUnreachable } from "../util/assertUnreachable.js";
|
||||||
|
|
||||||
const logger = new Logger("operations/peer-to-peer.ts");
|
const logger = new Logger("operations/peer-to-peer.ts");
|
||||||
|
|
||||||
@ -451,19 +453,11 @@ export async function checkPeerPushDebit(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processPeerPushInitiation(
|
async function processPeerPushDebitCreateReserve(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
pursePub: string,
|
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
||||||
): Promise<OperationAttemptResult> {
|
): Promise<OperationAttemptResult> {
|
||||||
const peerPushInitiation = await ws.db
|
const pursePub = peerPushInitiation.pursePub;
|
||||||
.mktx((x) => [x.peerPushPaymentInitiations])
|
|
||||||
.runReadOnly(async (tx) => {
|
|
||||||
return tx.peerPushPaymentInitiations.get(pursePub);
|
|
||||||
});
|
|
||||||
if (!peerPushInitiation) {
|
|
||||||
throw Error("peer push payment not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
const purseExpiration = peerPushInitiation.purseExpiration;
|
const purseExpiration = peerPushInitiation.purseExpiration;
|
||||||
const hContractTerms = peerPushInitiation.contractTermsHash;
|
const hContractTerms = peerPushInitiation.contractTermsHash;
|
||||||
|
|
||||||
@ -501,7 +495,9 @@ export async function processPeerPushInitiation(
|
|||||||
peerPushInitiation.exchangeBaseUrl,
|
peerPushInitiation.exchangeBaseUrl,
|
||||||
);
|
);
|
||||||
|
|
||||||
const httpResp = await ws.http.postJson(createPurseUrl.href, {
|
const httpResp = await ws.http.fetch(createPurseUrl.href, {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
amount: peerPushInitiation.amount,
|
amount: peerPushInitiation.amount,
|
||||||
merge_pub: peerPushInitiation.mergePub,
|
merge_pub: peerPushInitiation.mergePub,
|
||||||
purse_sig: purseSigResp.sig,
|
purse_sig: purseSigResp.sig,
|
||||||
@ -510,13 +506,14 @@ export async function processPeerPushInitiation(
|
|||||||
deposits: depositSigsResp.deposits,
|
deposits: depositSigsResp.deposits,
|
||||||
min_age: 0,
|
min_age: 0,
|
||||||
econtract: econtractResp.econtract,
|
econtract: econtractResp.econtract,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const resp = await httpResp.json();
|
const resp = await httpResp.json();
|
||||||
|
|
||||||
logger.info(`resp: ${j2s(resp)}`);
|
logger.info(`resp: ${j2s(resp)}`);
|
||||||
|
|
||||||
if (httpResp.status !== 200) {
|
if (httpResp.status !== HttpStatusCode.Ok) {
|
||||||
throw Error("got error response from exchange");
|
throw Error("got error response from exchange");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,7 +524,7 @@ export async function processPeerPushInitiation(
|
|||||||
if (!ppi) {
|
if (!ppi) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ppi.status = PeerPushPaymentInitiationStatus.PurseCreated;
|
ppi.status = PeerPushPaymentInitiationStatus.Done;
|
||||||
await tx.peerPushPaymentInitiations.put(ppi);
|
await tx.peerPushPaymentInitiations.put(ppi);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -537,6 +534,122 @@ export async function processPeerPushInitiation(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function transitionPeerPushDebitFromReadyToDone(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
pursePub: string,
|
||||||
|
): Promise<void> {
|
||||||
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
const transitionInfo = await ws.db
|
||||||
|
.mktx((x) => [x.peerPushPaymentInitiations])
|
||||||
|
.runReadWrite(async (tx) => {
|
||||||
|
const ppiRec = await tx.peerPushPaymentInitiations.get(pursePub);
|
||||||
|
if (!ppiRec) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (ppiRec.status !== PeerPushPaymentInitiationStatus.PendingReady) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const oldTxState = computePeerPushDebitTransactionState(ppiRec);
|
||||||
|
ppiRec.status = PeerPushPaymentInitiationStatus.Done;
|
||||||
|
const newTxState = computePeerPushDebitTransactionState(ppiRec);
|
||||||
|
return {
|
||||||
|
oldTxState,
|
||||||
|
newTxState,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the "pending(ready)" state of a peer-push-debit transaction.
|
||||||
|
*/
|
||||||
|
async function processPeerPushDebitReady(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
peerPushInitiation: PeerPushPaymentInitiationRecord,
|
||||||
|
): Promise<OperationAttemptResult> {
|
||||||
|
const pursePub = peerPushInitiation.pursePub;
|
||||||
|
const retryTag = constructTaskIdentifier({
|
||||||
|
tag: PendingTaskType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
runLongpollAsync(ws, retryTag, async (ct) => {
|
||||||
|
const mergeUrl = new URL(`purses/${pursePub}/merge`);
|
||||||
|
mergeUrl.searchParams.set("timeout_ms", "30000");
|
||||||
|
const resp = await ws.http.fetch(mergeUrl.href, {
|
||||||
|
// timeout: getReserveRequestTimeout(withdrawalGroup),
|
||||||
|
cancellationToken: ct,
|
||||||
|
});
|
||||||
|
if (resp.status === HttpStatusCode.Ok) {
|
||||||
|
const purseStatus = await readSuccessResponseJsonOrThrow(
|
||||||
|
resp,
|
||||||
|
codecForExchangePurseStatus(),
|
||||||
|
);
|
||||||
|
if (purseStatus.deposit_timestamp) {
|
||||||
|
await transitionPeerPushDebitFromReadyToDone(
|
||||||
|
ws,
|
||||||
|
peerPushInitiation.pursePub,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
ready: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (resp.status === HttpStatusCode.Gone) {
|
||||||
|
// FIXME: transition the reserve into the expired state
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
ready: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
logger.trace(
|
||||||
|
"returning early from withdrawal for long-polling in background",
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
type: OperationAttemptResultType.Longpoll,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function processPeerPushDebit(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
pursePub: string,
|
||||||
|
): Promise<OperationAttemptResult> {
|
||||||
|
const peerPushInitiation = await ws.db
|
||||||
|
.mktx((x) => [x.peerPushPaymentInitiations])
|
||||||
|
.runReadOnly(async (tx) => {
|
||||||
|
return tx.peerPushPaymentInitiations.get(pursePub);
|
||||||
|
});
|
||||||
|
if (!peerPushInitiation) {
|
||||||
|
throw Error("peer push payment not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
const retryTag = constructTaskIdentifier({
|
||||||
|
tag: PendingTaskType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
|
||||||
|
// We're already running!
|
||||||
|
if (ws.activeLongpoll[retryTag]) {
|
||||||
|
logger.info("peer-push-debit task already in long-polling, returning!");
|
||||||
|
return {
|
||||||
|
type: OperationAttemptResultType.Longpoll,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (peerPushInitiation.status) {
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
return processPeerPushDebitCreateReserve(ws, peerPushInitiation);
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingReady:
|
||||||
|
return processPeerPushDebitReady(ws, peerPushInitiation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: OperationAttemptResultType.Finished,
|
||||||
|
result: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate sending a peer-to-peer push payment.
|
* Initiate sending a peer-to-peer push payment.
|
||||||
*/
|
*/
|
||||||
@ -612,7 +725,7 @@ export async function initiatePeerPushPayment(
|
|||||||
pursePriv: pursePair.priv,
|
pursePriv: pursePair.priv,
|
||||||
pursePub: pursePair.pub,
|
pursePub: pursePair.pub,
|
||||||
timestampCreated: TalerProtocolTimestamp.now(),
|
timestampCreated: TalerProtocolTimestamp.now(),
|
||||||
status: PeerPushPaymentInitiationStatus.Initiated,
|
status: PeerPushPaymentInitiationStatus.PendingCreatePurse,
|
||||||
contractTerms: contractTerms,
|
contractTerms: contractTerms,
|
||||||
coinSel: {
|
coinSel: {
|
||||||
coinPubs: sel.coins.map((x) => x.coinPub),
|
coinPubs: sel.coins.map((x) => x.coinPub),
|
||||||
@ -628,12 +741,12 @@ export async function initiatePeerPushPayment(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const taskId = constructTaskIdentifier({
|
const taskId = constructTaskIdentifier({
|
||||||
tag: PendingTaskType.PeerPushInitiation,
|
tag: PendingTaskType.PeerPushDebit,
|
||||||
pursePub: pursePair.pub,
|
pursePub: pursePair.pub,
|
||||||
});
|
});
|
||||||
|
|
||||||
await runOperationWithErrorReporting(ws, taskId, async () => {
|
await runOperationWithErrorReporting(ws, taskId, async () => {
|
||||||
return await processPeerPushInitiation(ws, pursePair.pub);
|
return await processPeerPushDebit(ws, pursePair.pub);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -645,22 +758,24 @@ export async function initiatePeerPushPayment(
|
|||||||
exchangeBaseUrl: coinSelRes.result.exchangeBaseUrl,
|
exchangeBaseUrl: coinSelRes.result.exchangeBaseUrl,
|
||||||
contractPriv: contractKeyPair.priv,
|
contractPriv: contractKeyPair.priv,
|
||||||
}),
|
}),
|
||||||
transactionId: makeTransactionId(
|
transactionId: constructTransactionIdentifier({
|
||||||
TransactionType.PeerPushDebit,
|
tag: TransactionType.PeerPushDebit,
|
||||||
pursePair.pub,
|
pursePub: pursePair.pub,
|
||||||
),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExchangePurseStatus {
|
interface ExchangePurseStatus {
|
||||||
balance: AmountString;
|
balance: AmountString;
|
||||||
deposit_timestamp?: TalerProtocolTimestamp;
|
deposit_timestamp?: TalerProtocolTimestamp;
|
||||||
|
merge_timestamp?: TalerProtocolTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const codecForExchangePurseStatus = (): Codec<ExchangePurseStatus> =>
|
export const codecForExchangePurseStatus = (): Codec<ExchangePurseStatus> =>
|
||||||
buildCodecForObject<ExchangePurseStatus>()
|
buildCodecForObject<ExchangePurseStatus>()
|
||||||
.property("balance", codecForAmountString())
|
.property("balance", codecForAmountString())
|
||||||
.property("deposit_timestamp", codecOptional(codecForTimestamp))
|
.property("deposit_timestamp", codecOptional(codecForTimestamp))
|
||||||
|
.property("merge_timestamp", codecOptional(codecForTimestamp))
|
||||||
.build("ExchangePurseStatus");
|
.build("ExchangePurseStatus");
|
||||||
|
|
||||||
export async function preparePeerPushCredit(
|
export async function preparePeerPushCredit(
|
||||||
@ -879,13 +994,13 @@ export async function processPeerPushCredit(
|
|||||||
const amount = Amounts.parseOrThrow(contractTerms.amount);
|
const amount = Amounts.parseOrThrow(contractTerms.amount);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
peerInc.status === PeerPushPaymentIncomingStatus.KycRequired &&
|
peerInc.status === PeerPushPaymentIncomingStatus.MergeKycRequired &&
|
||||||
peerInc.kycInfo
|
peerInc.kycInfo
|
||||||
) {
|
) {
|
||||||
const txId = makeTransactionId(
|
const txId = constructTransactionIdentifier({
|
||||||
TransactionType.PeerPushCredit,
|
tag: TransactionType.PeerPushCredit,
|
||||||
peerInc.peerPushPaymentIncomingId,
|
peerPushPaymentIncomingId: peerInc.peerPushPaymentIncomingId,
|
||||||
);
|
});
|
||||||
await checkWithdrawalKycStatus(
|
await checkWithdrawalKycStatus(
|
||||||
ws,
|
ws,
|
||||||
peerInc.exchangeBaseUrl,
|
peerInc.exchangeBaseUrl,
|
||||||
@ -951,7 +1066,7 @@ export async function processPeerPushCredit(
|
|||||||
paytoHash: kycPending.h_payto,
|
paytoHash: kycPending.h_payto,
|
||||||
requirementRow: kycPending.requirement_row,
|
requirementRow: kycPending.requirement_row,
|
||||||
};
|
};
|
||||||
peerInc.status = PeerPushPaymentIncomingStatus.KycRequired;
|
peerInc.status = PeerPushPaymentIncomingStatus.MergeKycRequired;
|
||||||
await tx.peerPushPaymentIncoming.put(peerInc);
|
await tx.peerPushPaymentIncoming.put(peerInc);
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
@ -975,7 +1090,7 @@ export async function processPeerPushCredit(
|
|||||||
},
|
},
|
||||||
forcedWithdrawalGroupId: peerInc.withdrawalGroupId,
|
forcedWithdrawalGroupId: peerInc.withdrawalGroupId,
|
||||||
exchangeBaseUrl: peerInc.exchangeBaseUrl,
|
exchangeBaseUrl: peerInc.exchangeBaseUrl,
|
||||||
reserveStatus: WithdrawalGroupStatus.QueryingStatus,
|
reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus,
|
||||||
reserveKeyPair: {
|
reserveKeyPair: {
|
||||||
priv: mergeReserveInfo.reservePriv,
|
priv: mergeReserveInfo.reservePriv,
|
||||||
pub: mergeReserveInfo.reservePub,
|
pub: mergeReserveInfo.reservePub,
|
||||||
@ -993,9 +1108,9 @@ export async function processPeerPushCredit(
|
|||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
peerInc.status === PeerPushPaymentIncomingStatus.Accepted ||
|
peerInc.status === PeerPushPaymentIncomingStatus.Accepted ||
|
||||||
peerInc.status === PeerPushPaymentIncomingStatus.KycRequired
|
peerInc.status === PeerPushPaymentIncomingStatus.MergeKycRequired
|
||||||
) {
|
) {
|
||||||
peerInc.status = PeerPushPaymentIncomingStatus.WithdrawalCreated;
|
peerInc.status = PeerPushPaymentIncomingStatus.Done;
|
||||||
}
|
}
|
||||||
await tx.peerPushPaymentIncoming.put(peerInc);
|
await tx.peerPushPaymentIncoming.put(peerInc);
|
||||||
});
|
});
|
||||||
@ -1011,7 +1126,7 @@ export async function confirmPeerPushCredit(
|
|||||||
req: ConfirmPeerPushCreditRequest,
|
req: ConfirmPeerPushCreditRequest,
|
||||||
): Promise<AcceptPeerPushPaymentResponse> {
|
): Promise<AcceptPeerPushPaymentResponse> {
|
||||||
let peerInc: PeerPushPaymentIncomingRecord | undefined;
|
let peerInc: PeerPushPaymentIncomingRecord | undefined;
|
||||||
let contractTerms: PeerContractTerms | undefined;
|
|
||||||
await ws.db
|
await ws.db
|
||||||
.mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming])
|
.mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming])
|
||||||
.runReadWrite(async (tx) => {
|
.runReadWrite(async (tx) => {
|
||||||
@ -1021,10 +1136,6 @@ export async function confirmPeerPushCredit(
|
|||||||
if (!peerInc) {
|
if (!peerInc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ctRec = await tx.contractTerms.get(peerInc.contractTermsHash);
|
|
||||||
if (ctRec) {
|
|
||||||
contractTerms = ctRec.contractTermsRaw;
|
|
||||||
}
|
|
||||||
if (peerInc.status === PeerPushPaymentIncomingStatus.Proposed) {
|
if (peerInc.status === PeerPushPaymentIncomingStatus.Proposed) {
|
||||||
peerInc.status = PeerPushPaymentIncomingStatus.Accepted;
|
peerInc.status = PeerPushPaymentIncomingStatus.Accepted;
|
||||||
}
|
}
|
||||||
@ -1037,21 +1148,15 @@ export async function confirmPeerPushCredit(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDbInvariant(!!contractTerms);
|
ws.workAvailable.trigger();
|
||||||
|
|
||||||
await updateExchangeFromUrl(ws, peerInc.exchangeBaseUrl);
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPushCredit,
|
||||||
const retryTag = TaskIdentifiers.forPeerPushCredit(peerInc);
|
peerPushPaymentIncomingId: req.peerPushPaymentIncomingId,
|
||||||
|
});
|
||||||
await runOperationWithErrorReporting(ws, retryTag, () =>
|
|
||||||
processPeerPushCredit(ws, req.peerPushPaymentIncomingId),
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
transactionId: makeTransactionId(
|
transactionId,
|
||||||
TransactionType.PeerPushCredit,
|
|
||||||
req.peerPushPaymentIncomingId,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1209,11 +1314,13 @@ export async function confirmPeerPullDebit(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPullDebit,
|
||||||
|
peerPullPaymentIncomingId: req.peerPullPaymentIncomingId,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
transactionId: makeTransactionId(
|
transactionId,
|
||||||
TransactionType.PeerPullDebit,
|
|
||||||
req.peerPullPaymentIncomingId,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,7 +1502,7 @@ export async function queryPurseForPeerPullCredit(
|
|||||||
},
|
},
|
||||||
forcedWithdrawalGroupId: pullIni.withdrawalGroupId,
|
forcedWithdrawalGroupId: pullIni.withdrawalGroupId,
|
||||||
exchangeBaseUrl: pullIni.exchangeBaseUrl,
|
exchangeBaseUrl: pullIni.exchangeBaseUrl,
|
||||||
reserveStatus: WithdrawalGroupStatus.QueryingStatus,
|
reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus,
|
||||||
reserveKeyPair: {
|
reserveKeyPair: {
|
||||||
priv: reserve.reservePriv,
|
priv: reserve.reservePriv,
|
||||||
pub: reserve.reservePub,
|
pub: reserve.reservePub,
|
||||||
@ -1410,8 +1517,8 @@ export async function queryPurseForPeerPullCredit(
|
|||||||
logger.warn("peerPullPaymentInitiation not found anymore");
|
logger.warn("peerPullPaymentInitiation not found anymore");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (finPi.status === PeerPullPaymentInitiationStatus.PurseCreated) {
|
if (finPi.status === PeerPullPaymentInitiationStatus.PendingReady) {
|
||||||
finPi.status = PeerPullPaymentInitiationStatus.PurseDeposited;
|
finPi.status = PeerPullPaymentInitiationStatus.DonePurseDeposited;
|
||||||
}
|
}
|
||||||
await tx.peerPullPaymentInitiations.put(finPi);
|
await tx.peerPullPaymentInitiations.put(finPi);
|
||||||
});
|
});
|
||||||
@ -1434,7 +1541,7 @@ export async function processPeerPullCredit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const retryTag = constructTaskIdentifier({
|
const retryTag = constructTaskIdentifier({
|
||||||
tag: PendingTaskType.PeerPullInitiation,
|
tag: PendingTaskType.PeerPullCredit,
|
||||||
pursePub,
|
pursePub,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1449,7 +1556,7 @@ export async function processPeerPullCredit(
|
|||||||
logger.trace(`processing ${retryTag}, status=${pullIni.status}`);
|
logger.trace(`processing ${retryTag}, status=${pullIni.status}`);
|
||||||
|
|
||||||
switch (pullIni.status) {
|
switch (pullIni.status) {
|
||||||
case PeerPullPaymentInitiationStatus.PurseDeposited: {
|
case PeerPullPaymentInitiationStatus.DonePurseDeposited: {
|
||||||
// We implement this case so that the "retry" action on a peer-pull-credit transaction
|
// We implement this case so that the "retry" action on a peer-pull-credit transaction
|
||||||
// also retries the withdrawal task.
|
// also retries the withdrawal task.
|
||||||
|
|
||||||
@ -1475,7 +1582,7 @@ export async function processPeerPullCredit(
|
|||||||
result: undefined,
|
result: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case PeerPullPaymentInitiationStatus.PurseCreated:
|
case PeerPullPaymentInitiationStatus.PendingReady:
|
||||||
runLongpollAsync(ws, retryTag, async (cancellationToken) =>
|
runLongpollAsync(ws, retryTag, async (cancellationToken) =>
|
||||||
queryPurseForPeerPullCredit(ws, pullIni, cancellationToken),
|
queryPurseForPeerPullCredit(ws, pullIni, cancellationToken),
|
||||||
);
|
);
|
||||||
@ -1485,23 +1592,23 @@ export async function processPeerPullCredit(
|
|||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Longpoll,
|
type: OperationAttemptResultType.Longpoll,
|
||||||
};
|
};
|
||||||
case PeerPullPaymentInitiationStatus.KycRequired: {
|
case PeerPullPaymentInitiationStatus.PendingMergeKycRequired: {
|
||||||
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPullCredit,
|
||||||
|
pursePub: pullIni.pursePub,
|
||||||
|
});
|
||||||
if (pullIni.kycInfo) {
|
if (pullIni.kycInfo) {
|
||||||
const txId = makeTransactionId(
|
|
||||||
TransactionType.PeerPullCredit,
|
|
||||||
pullIni.pursePub,
|
|
||||||
);
|
|
||||||
await checkWithdrawalKycStatus(
|
await checkWithdrawalKycStatus(
|
||||||
ws,
|
ws,
|
||||||
pullIni.exchangeBaseUrl,
|
pullIni.exchangeBaseUrl,
|
||||||
txId,
|
transactionId,
|
||||||
pullIni.kycInfo,
|
pullIni.kycInfo,
|
||||||
"individual",
|
"individual",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PeerPullPaymentInitiationStatus.Initial:
|
case PeerPullPaymentInitiationStatus.PendingCreatePurse:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw Error(`unknown PeerPullPaymentInitiationStatus ${pullIni.status}`);
|
throw Error(`unknown PeerPullPaymentInitiationStatus ${pullIni.status}`);
|
||||||
@ -1590,7 +1697,8 @@ export async function processPeerPullCredit(
|
|||||||
paytoHash: kycPending.h_payto,
|
paytoHash: kycPending.h_payto,
|
||||||
requirementRow: kycPending.requirement_row,
|
requirementRow: kycPending.requirement_row,
|
||||||
};
|
};
|
||||||
peerIni.status = PeerPullPaymentInitiationStatus.KycRequired;
|
peerIni.status =
|
||||||
|
PeerPullPaymentInitiationStatus.PendingMergeKycRequired;
|
||||||
await tx.peerPullPaymentInitiations.put(peerIni);
|
await tx.peerPullPaymentInitiations.put(peerIni);
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
@ -1610,7 +1718,7 @@ export async function processPeerPullCredit(
|
|||||||
if (!pi2) {
|
if (!pi2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pi2.status = PeerPullPaymentInitiationStatus.PurseCreated;
|
pi2.status = PeerPullPaymentInitiationStatus.PendingReady;
|
||||||
await tx.peerPullPaymentInitiations.put(pi2);
|
await tx.peerPullPaymentInitiations.put(pi2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1776,7 +1884,7 @@ export async function initiatePeerPullPayment(
|
|||||||
pursePub: pursePair.pub,
|
pursePub: pursePair.pub,
|
||||||
mergePriv: mergePair.priv,
|
mergePriv: mergePair.priv,
|
||||||
mergePub: mergePair.pub,
|
mergePub: mergePair.pub,
|
||||||
status: PeerPullPaymentInitiationStatus.Initial,
|
status: PeerPullPaymentInitiationStatus.PendingCreatePurse,
|
||||||
contractTerms: contractTerms,
|
contractTerms: contractTerms,
|
||||||
mergeTimestamp,
|
mergeTimestamp,
|
||||||
mergeReserveRowId: mergeReserveRowId,
|
mergeReserveRowId: mergeReserveRowId,
|
||||||
@ -1796,7 +1904,7 @@ export async function initiatePeerPullPayment(
|
|||||||
// check this asynchronously from the transaction status?
|
// check this asynchronously from the transaction status?
|
||||||
|
|
||||||
const taskId = constructTaskIdentifier({
|
const taskId = constructTaskIdentifier({
|
||||||
tag: PendingTaskType.PeerPullInitiation,
|
tag: PendingTaskType.PeerPullCredit,
|
||||||
pursePub: pursePair.pub,
|
pursePub: pursePair.pub,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1804,14 +1912,408 @@ export async function initiatePeerPullPayment(
|
|||||||
return processPeerPullCredit(ws, pursePair.pub);
|
return processPeerPullCredit(ws, pursePair.pub);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPullCredit,
|
||||||
|
pursePub: pursePair.pub,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
talerUri: constructPayPullUri({
|
talerUri: constructPayPullUri({
|
||||||
exchangeBaseUrl: exchangeBaseUrl,
|
exchangeBaseUrl: exchangeBaseUrl,
|
||||||
contractPriv: contractKeyPair.priv,
|
contractPriv: contractKeyPair.priv,
|
||||||
}),
|
}),
|
||||||
transactionId: makeTransactionId(
|
transactionId,
|
||||||
TransactionType.PeerPullCredit,
|
|
||||||
pursePair.pub,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function computePeerPushDebitTransactionState(
|
||||||
|
ppiRecord: PeerPushPaymentInitiationRecord,
|
||||||
|
): TransactionState {
|
||||||
|
switch (ppiRecord.status) {
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.CreatePurse,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingReady:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.Ready,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.Aborted:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Aborted,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Aborting,
|
||||||
|
minor: TransactionMinorState.DeletePurse,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingRefresh:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Aborting,
|
||||||
|
minor: TransactionMinorState.Refresh,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.SuspendedAborting,
|
||||||
|
minor: TransactionMinorState.DeletePurse,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.SuspendedAborting,
|
||||||
|
minor: TransactionMinorState.Refresh,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Suspended,
|
||||||
|
minor: TransactionMinorState.CreatePurse,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedReady:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Suspended,
|
||||||
|
minor: TransactionMinorState.Ready,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentInitiationStatus.Done:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Done,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function abortPeerPushDebitTransaction(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
pursePub: string,
|
||||||
|
) {
|
||||||
|
const taskId = constructTaskIdentifier({
|
||||||
|
tag: PendingTaskType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
stopLongpolling(ws, taskId);
|
||||||
|
const transitionInfo = await ws.db
|
||||||
|
.mktx((x) => [x.peerPushPaymentInitiations])
|
||||||
|
.runReadWrite(async (tx) => {
|
||||||
|
const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub);
|
||||||
|
if (!pushDebitRec) {
|
||||||
|
logger.warn(`peer push debit ${pursePub} not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined;
|
||||||
|
switch (pushDebitRec.status) {
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingReady:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedReady:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
// Network request might already be in-flight!
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingRefresh:
|
||||||
|
case PeerPushPaymentInitiationStatus.Done:
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.Aborted:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assertUnreachable(pushDebitRec.status);
|
||||||
|
}
|
||||||
|
if (newStatus != null) {
|
||||||
|
const oldTxState = computePeerPushDebitTransactionState(pushDebitRec);
|
||||||
|
pushDebitRec.status = newStatus;
|
||||||
|
const newTxState = computePeerPushDebitTransactionState(pushDebitRec);
|
||||||
|
await tx.peerPushPaymentInitiations.put(pushDebitRec);
|
||||||
|
return {
|
||||||
|
oldTxState,
|
||||||
|
newTxState,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cancelAbortingPeerPushDebitTransaction(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
pursePub: string,
|
||||||
|
) {
|
||||||
|
const taskId = constructTaskIdentifier({
|
||||||
|
tag: PendingTaskType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
stopLongpolling(ws, taskId);
|
||||||
|
const transitionInfo = await ws.db
|
||||||
|
.mktx((x) => [x.peerPushPaymentInitiations])
|
||||||
|
.runReadWrite(async (tx) => {
|
||||||
|
const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub);
|
||||||
|
if (!pushDebitRec) {
|
||||||
|
logger.warn(`peer push debit ${pursePub} not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined;
|
||||||
|
switch (pushDebitRec.status) {
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingRefresh:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
|
||||||
|
// FIXME: We also need to abort the refresh group!
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.Aborted;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.Aborted;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingReady:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedReady:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.Done:
|
||||||
|
case PeerPushPaymentInitiationStatus.Aborted:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assertUnreachable(pushDebitRec.status);
|
||||||
|
}
|
||||||
|
if (newStatus != null) {
|
||||||
|
const oldTxState = computePeerPushDebitTransactionState(pushDebitRec);
|
||||||
|
pushDebitRec.status = newStatus;
|
||||||
|
const newTxState = computePeerPushDebitTransactionState(pushDebitRec);
|
||||||
|
await tx.peerPushPaymentInitiations.put(pushDebitRec);
|
||||||
|
return {
|
||||||
|
oldTxState,
|
||||||
|
newTxState,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function suspendPeerPushDebitTransaction(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
pursePub: string,
|
||||||
|
) {
|
||||||
|
const taskId = constructTaskIdentifier({
|
||||||
|
tag: PendingTaskType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
stopLongpolling(ws, taskId);
|
||||||
|
const transitionInfo = await ws.db
|
||||||
|
.mktx((x) => [x.peerPushPaymentInitiations])
|
||||||
|
.runReadWrite(async (tx) => {
|
||||||
|
const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub);
|
||||||
|
if (!pushDebitRec) {
|
||||||
|
logger.warn(`peer push debit ${pursePub} not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined;
|
||||||
|
switch (pushDebitRec.status) {
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.SuspendedCreatePurse;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingRefresh:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
|
||||||
|
newStatus =
|
||||||
|
PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingReady:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.SuspendedReady;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedReady:
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.Done:
|
||||||
|
case PeerPushPaymentInitiationStatus.Aborted:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assertUnreachable(pushDebitRec.status);
|
||||||
|
}
|
||||||
|
if (newStatus != null) {
|
||||||
|
const oldTxState = computePeerPushDebitTransactionState(pushDebitRec);
|
||||||
|
pushDebitRec.status = newStatus;
|
||||||
|
const newTxState = computePeerPushDebitTransactionState(pushDebitRec);
|
||||||
|
await tx.peerPushPaymentInitiations.put(pushDebitRec);
|
||||||
|
return {
|
||||||
|
oldTxState,
|
||||||
|
newTxState,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function resumePeerPushDebitTransaction(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
pursePub: string,
|
||||||
|
) {
|
||||||
|
const taskId = constructTaskIdentifier({
|
||||||
|
tag: PendingTaskType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
const transactionId = constructTransactionIdentifier({
|
||||||
|
tag: TransactionType.PeerPushDebit,
|
||||||
|
pursePub,
|
||||||
|
});
|
||||||
|
stopLongpolling(ws, taskId);
|
||||||
|
const transitionInfo = await ws.db
|
||||||
|
.mktx((x) => [x.peerPushPaymentInitiations])
|
||||||
|
.runReadWrite(async (tx) => {
|
||||||
|
const pushDebitRec = await tx.peerPushPaymentInitiations.get(pursePub);
|
||||||
|
if (!pushDebitRec) {
|
||||||
|
logger.warn(`peer push debit ${pursePub} not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let newStatus: PeerPushPaymentInitiationStatus | undefined = undefined;
|
||||||
|
switch (pushDebitRec.status) {
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingDeletePurse:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.AbortingDeletePurse;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedAbortingRefresh:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.AbortingRefresh;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedReady:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.PendingReady;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.SuspendedCreatePurse:
|
||||||
|
newStatus = PeerPushPaymentInitiationStatus.PendingCreatePurse;
|
||||||
|
break;
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingRefresh:
|
||||||
|
case PeerPushPaymentInitiationStatus.AbortingDeletePurse:
|
||||||
|
case PeerPushPaymentInitiationStatus.PendingReady:
|
||||||
|
case PeerPushPaymentInitiationStatus.Done:
|
||||||
|
case PeerPushPaymentInitiationStatus.Aborted:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assertUnreachable(pushDebitRec.status);
|
||||||
|
}
|
||||||
|
if (newStatus != null) {
|
||||||
|
const oldTxState = computePeerPushDebitTransactionState(pushDebitRec);
|
||||||
|
pushDebitRec.status = newStatus;
|
||||||
|
const newTxState = computePeerPushDebitTransactionState(pushDebitRec);
|
||||||
|
await tx.peerPushPaymentInitiations.put(pushDebitRec);
|
||||||
|
return {
|
||||||
|
oldTxState,
|
||||||
|
newTxState,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
notifyTransition(ws, transactionId, transitionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function computePeerPushCreditTransactionState(
|
||||||
|
pushCreditRecord: PeerPushPaymentIncomingRecord,
|
||||||
|
): TransactionState {
|
||||||
|
switch (pushCreditRecord.status) {
|
||||||
|
case PeerPushPaymentIncomingStatus.Proposed:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Dialog,
|
||||||
|
minor: TransactionMinorState.Proposed,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentIncomingStatus.Accepted:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.Merge,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentIncomingStatus.Done:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Done,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentIncomingStatus.MergeKycRequired:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.KycRequired,
|
||||||
|
};
|
||||||
|
case PeerPushPaymentIncomingStatus.Withdrawing:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.Withdraw,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function computePeerPullCreditTransactionState(
|
||||||
|
pullCreditRecord: PeerPullPaymentInitiationRecord,
|
||||||
|
): TransactionState {
|
||||||
|
switch (pullCreditRecord.status) {
|
||||||
|
case PeerPullPaymentInitiationStatus.PendingCreatePurse:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.CreatePurse,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentInitiationStatus.PendingMergeKycRequired:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.MergeKycRequired,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentInitiationStatus.PendingReady:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.Ready,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentInitiationStatus.DonePurseDeposited:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Done,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentInitiationStatus.PendingWithdrawing:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.Withdraw,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentInitiationStatus.SuspendedCreatePurse:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Suspended,
|
||||||
|
minor: TransactionMinorState.CreatePurse,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentInitiationStatus.SuspendedReady:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Suspended,
|
||||||
|
minor: TransactionMinorState.Ready,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentInitiationStatus.SuspendedWithdrawing:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.Withdraw,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function computePeerPullDebitTransactionState(
|
||||||
|
pullDebitRecord: PeerPullPaymentIncomingRecord,
|
||||||
|
): TransactionState {
|
||||||
|
switch (pullDebitRecord.status) {
|
||||||
|
case PeerPullPaymentIncomingStatus.Proposed:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Dialog,
|
||||||
|
minor: TransactionMinorState.Proposed,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentIncomingStatus.Accepted:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Pending,
|
||||||
|
minor: TransactionMinorState.Deposit,
|
||||||
|
};
|
||||||
|
case PeerPullPaymentIncomingStatus.Paid:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Done,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -364,14 +364,14 @@ async function gatherPeerPullInitiationPending(
|
|||||||
resp: PendingOperationsResponse,
|
resp: PendingOperationsResponse,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await tx.peerPullPaymentInitiations.iter().forEachAsync(async (pi) => {
|
await tx.peerPullPaymentInitiations.iter().forEachAsync(async (pi) => {
|
||||||
if (pi.status === PeerPullPaymentInitiationStatus.PurseDeposited) {
|
if (pi.status === PeerPullPaymentInitiationStatus.DonePurseDeposited) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const opId = TaskIdentifiers.forPeerPullPaymentInitiation(pi);
|
const opId = TaskIdentifiers.forPeerPullPaymentInitiation(pi);
|
||||||
const retryRecord = await tx.operationRetries.get(opId);
|
const retryRecord = await tx.operationRetries.get(opId);
|
||||||
const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now();
|
const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now();
|
||||||
resp.pendingOperations.push({
|
resp.pendingOperations.push({
|
||||||
type: PendingTaskType.PeerPullInitiation,
|
type: PendingTaskType.PeerPullCredit,
|
||||||
...getPendingCommon(ws, opId, timestampDue),
|
...getPendingCommon(ws, opId, timestampDue),
|
||||||
givesLifeness: true,
|
givesLifeness: true,
|
||||||
retryInfo: retryRecord?.retryInfo,
|
retryInfo: retryRecord?.retryInfo,
|
||||||
@ -421,14 +421,14 @@ async function gatherPeerPushInitiationPending(
|
|||||||
resp: PendingOperationsResponse,
|
resp: PendingOperationsResponse,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await tx.peerPushPaymentInitiations.iter().forEachAsync(async (pi) => {
|
await tx.peerPushPaymentInitiations.iter().forEachAsync(async (pi) => {
|
||||||
if (pi.status === PeerPushPaymentInitiationStatus.PurseCreated) {
|
if (pi.status === PeerPushPaymentInitiationStatus.Done) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const opId = TaskIdentifiers.forPeerPushPaymentInitiation(pi);
|
const opId = TaskIdentifiers.forPeerPushPaymentInitiation(pi);
|
||||||
const retryRecord = await tx.operationRetries.get(opId);
|
const retryRecord = await tx.operationRetries.get(opId);
|
||||||
const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now();
|
const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now();
|
||||||
resp.pendingOperations.push({
|
resp.pendingOperations.push({
|
||||||
type: PendingTaskType.PeerPushInitiation,
|
type: PendingTaskType.PeerPushDebit,
|
||||||
...getPendingCommon(ws, opId, timestampDue),
|
...getPendingCommon(ws, opId, timestampDue),
|
||||||
givesLifeness: true,
|
givesLifeness: true,
|
||||||
retryInfo: retryRecord?.retryInfo,
|
retryInfo: retryRecord?.retryInfo,
|
||||||
@ -450,7 +450,7 @@ async function gatherPeerPushCreditPending(
|
|||||||
switch (pi.status) {
|
switch (pi.status) {
|
||||||
case PeerPushPaymentIncomingStatus.Proposed:
|
case PeerPushPaymentIncomingStatus.Proposed:
|
||||||
return;
|
return;
|
||||||
case PeerPushPaymentIncomingStatus.WithdrawalCreated:
|
case PeerPushPaymentIncomingStatus.Done:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const opId = TaskIdentifiers.forPeerPushCredit(pi);
|
const opId = TaskIdentifiers.forPeerPushCredit(pi);
|
||||||
|
@ -400,7 +400,7 @@ export async function processRecoupGroupHandler(
|
|||||||
await internalCreateWithdrawalGroup(ws, {
|
await internalCreateWithdrawalGroup(ws, {
|
||||||
amount: Amounts.parseOrThrow(result.balance),
|
amount: Amounts.parseOrThrow(result.balance),
|
||||||
exchangeBaseUrl: recoupGroup.exchangeBaseUrl,
|
exchangeBaseUrl: recoupGroup.exchangeBaseUrl,
|
||||||
reserveStatus: WithdrawalGroupStatus.QueryingStatus,
|
reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus,
|
||||||
reserveKeyPair: {
|
reserveKeyPair: {
|
||||||
pub: reservePub,
|
pub: reservePub,
|
||||||
priv: reservePrivMap[reservePub],
|
priv: reservePrivMap[reservePub],
|
||||||
|
@ -1125,7 +1125,7 @@ export async function autoRefresh(
|
|||||||
return OperationAttemptResult.finishedEmpty();
|
return OperationAttemptResult.finishedEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function computeRefreshTransactionStatus(
|
export function computeRefreshTransactionState(
|
||||||
rg: RefreshGroupRecord,
|
rg: RefreshGroupRecord,
|
||||||
): TransactionState {
|
): TransactionState {
|
||||||
switch (rg.operationStatus) {
|
switch (rg.operationStatus) {
|
||||||
@ -1170,7 +1170,7 @@ export async function suspendRefreshGroup(
|
|||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const oldState = computeRefreshTransactionStatus(dg);
|
const oldState = computeRefreshTransactionState(dg);
|
||||||
switch (dg.operationStatus) {
|
switch (dg.operationStatus) {
|
||||||
case RefreshOperationStatus.Finished:
|
case RefreshOperationStatus.Finished:
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -1179,7 +1179,7 @@ export async function suspendRefreshGroup(
|
|||||||
await tx.refreshGroups.put(dg);
|
await tx.refreshGroups.put(dg);
|
||||||
return {
|
return {
|
||||||
oldTxState: oldState,
|
oldTxState: oldState,
|
||||||
newTxState: computeRefreshTransactionStatus(dg),
|
newTxState: computeRefreshTransactionState(dg),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case RefreshOperationStatus.Suspended:
|
case RefreshOperationStatus.Suspended:
|
||||||
@ -1215,7 +1215,7 @@ export async function resumeRefreshGroup(
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const oldState = computeRefreshTransactionStatus(dg);
|
const oldState = computeRefreshTransactionState(dg);
|
||||||
switch (dg.operationStatus) {
|
switch (dg.operationStatus) {
|
||||||
case RefreshOperationStatus.Finished:
|
case RefreshOperationStatus.Finished:
|
||||||
return;
|
return;
|
||||||
@ -1227,12 +1227,12 @@ export async function resumeRefreshGroup(
|
|||||||
await tx.refreshGroups.put(dg);
|
await tx.refreshGroups.put(dg);
|
||||||
return {
|
return {
|
||||||
oldTxState: oldState,
|
oldTxState: oldState,
|
||||||
newTxState: computeRefreshTransactionStatus(dg),
|
newTxState: computeRefreshTransactionState(dg),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
ws.latch.trigger();
|
ws.workAvailable.trigger();
|
||||||
if (res) {
|
if (res) {
|
||||||
ws.notify({
|
ws.notify({
|
||||||
type: NotificationType.TransactionStateTransition,
|
type: NotificationType.TransactionStateTransition,
|
||||||
|
@ -87,14 +87,14 @@ import {
|
|||||||
} from "./deposits.js";
|
} from "./deposits.js";
|
||||||
import { getExchangeDetails } from "./exchanges.js";
|
import { getExchangeDetails } from "./exchanges.js";
|
||||||
import {
|
import {
|
||||||
abortPay,
|
abortPayMerchant,
|
||||||
computePayMerchantTransactionState,
|
computePayMerchantTransactionState,
|
||||||
expectProposalDownload,
|
expectProposalDownload,
|
||||||
extractContractData,
|
extractContractData,
|
||||||
processPurchasePay,
|
processPurchasePay,
|
||||||
} from "./pay-merchant.js";
|
} from "./pay-merchant.js";
|
||||||
import { processPeerPullCredit } from "./pay-peer.js";
|
import { computePeerPullCreditTransactionState, computePeerPullDebitTransactionState, computePeerPushCreditTransactionState, computePeerPushDebitTransactionState, processPeerPullCredit } from "./pay-peer.js";
|
||||||
import { processRefreshGroup } from "./refresh.js";
|
import { computeRefreshTransactionState, processRefreshGroup } from "./refresh.js";
|
||||||
import { computeTipTransactionStatus, processTip } from "./tip.js";
|
import { computeTipTransactionStatus, processTip } from "./tip.js";
|
||||||
import {
|
import {
|
||||||
abortWithdrawalTransaction,
|
abortWithdrawalTransaction,
|
||||||
@ -445,7 +445,7 @@ function buildTransactionForPushPaymentDebit(
|
|||||||
): Transaction {
|
): Transaction {
|
||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPushDebit,
|
type: TransactionType.PeerPushDebit,
|
||||||
txState: mkTxStateUnknown(),
|
txState: computePeerPushDebitTransactionState(pi),
|
||||||
amountEffective: pi.totalCost,
|
amountEffective: pi.totalCost,
|
||||||
amountRaw: pi.amount,
|
amountRaw: pi.amount,
|
||||||
exchangeBaseUrl: pi.exchangeBaseUrl,
|
exchangeBaseUrl: pi.exchangeBaseUrl,
|
||||||
@ -455,10 +455,10 @@ function buildTransactionForPushPaymentDebit(
|
|||||||
},
|
},
|
||||||
frozen: false,
|
frozen: false,
|
||||||
extendedStatus:
|
extendedStatus:
|
||||||
pi.status != PeerPushPaymentInitiationStatus.PurseCreated
|
pi.status != PeerPushPaymentInitiationStatus.Done
|
||||||
? ExtendedStatus.Pending
|
? ExtendedStatus.Pending
|
||||||
: ExtendedStatus.Done,
|
: ExtendedStatus.Done,
|
||||||
pending: pi.status != PeerPushPaymentInitiationStatus.PurseCreated,
|
pending: pi.status != PeerPushPaymentInitiationStatus.Done,
|
||||||
timestamp: pi.timestampCreated,
|
timestamp: pi.timestampCreated,
|
||||||
talerUri: constructPayPushUri({
|
talerUri: constructPayPushUri({
|
||||||
exchangeBaseUrl: pi.exchangeBaseUrl,
|
exchangeBaseUrl: pi.exchangeBaseUrl,
|
||||||
@ -478,7 +478,7 @@ function buildTransactionForPullPaymentDebit(
|
|||||||
): Transaction {
|
): Transaction {
|
||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPullDebit,
|
type: TransactionType.PeerPullDebit,
|
||||||
txState: mkTxStateUnknown(),
|
txState: computePeerPullDebitTransactionState(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),
|
||||||
@ -528,7 +528,7 @@ function buildTransactionForPeerPullCredit(
|
|||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPullCredit,
|
type: TransactionType.PeerPullCredit,
|
||||||
txState: mkTxStateUnknown(),
|
txState: computePeerPullCreditTransactionState(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,
|
||||||
@ -563,7 +563,7 @@ function buildTransactionForPeerPullCredit(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPullCredit,
|
type: TransactionType.PeerPullCredit,
|
||||||
txState: mkTxStateUnknown(),
|
txState: computePeerPullCreditTransactionState(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,
|
||||||
@ -602,7 +602,7 @@ function buildTransactionForPeerPushCredit(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPushCredit,
|
type: TransactionType.PeerPushCredit,
|
||||||
txState: mkTxStateUnknown(),
|
txState: computePeerPushCreditTransactionState(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,
|
||||||
@ -626,7 +626,7 @@ function buildTransactionForPeerPushCredit(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
type: TransactionType.PeerPushCredit,
|
type: TransactionType.PeerPushCredit,
|
||||||
txState: mkTxStateUnknown(),
|
txState: computePeerPushCreditTransactionState(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),
|
||||||
@ -666,7 +666,7 @@ function buildTransactionForBankIntegratedWithdraw(
|
|||||||
bankConfirmationUrl: wgRecord.wgInfo.bankInfo.confirmUrl,
|
bankConfirmationUrl: wgRecord.wgInfo.bankInfo.confirmUrl,
|
||||||
reserveIsReady:
|
reserveIsReady:
|
||||||
wgRecord.status === WithdrawalGroupStatus.Finished ||
|
wgRecord.status === WithdrawalGroupStatus.Finished ||
|
||||||
wgRecord.status === WithdrawalGroupStatus.Ready,
|
wgRecord.status === WithdrawalGroupStatus.PendingReady,
|
||||||
},
|
},
|
||||||
exchangeBaseUrl: wgRecord.exchangeBaseUrl,
|
exchangeBaseUrl: wgRecord.exchangeBaseUrl,
|
||||||
extendedStatus: wgRecord.timestampFinish
|
extendedStatus: wgRecord.timestampFinish
|
||||||
@ -713,7 +713,7 @@ function buildTransactionForManualWithdraw(
|
|||||||
exchangePaytoUris,
|
exchangePaytoUris,
|
||||||
reserveIsReady:
|
reserveIsReady:
|
||||||
withdrawalGroup.status === WithdrawalGroupStatus.Finished ||
|
withdrawalGroup.status === WithdrawalGroupStatus.Finished ||
|
||||||
withdrawalGroup.status === WithdrawalGroupStatus.Ready,
|
withdrawalGroup.status === WithdrawalGroupStatus.PendingReady,
|
||||||
},
|
},
|
||||||
exchangeBaseUrl: withdrawalGroup.exchangeBaseUrl,
|
exchangeBaseUrl: withdrawalGroup.exchangeBaseUrl,
|
||||||
extendedStatus: withdrawalGroup.timestampFinish
|
extendedStatus: withdrawalGroup.timestampFinish
|
||||||
@ -753,7 +753,7 @@ function buildTransactionForRefresh(
|
|||||||
).amount;
|
).amount;
|
||||||
return {
|
return {
|
||||||
type: TransactionType.Refresh,
|
type: TransactionType.Refresh,
|
||||||
txState: mkTxStateUnknown(),
|
txState: computeRefreshTransactionState(refreshGroupRecord),
|
||||||
refreshReason: refreshGroupRecord.reason,
|
refreshReason: refreshGroupRecord.reason,
|
||||||
amountEffective: Amounts.stringify(
|
amountEffective: Amounts.stringify(
|
||||||
Amounts.zeroOfCurrency(refreshGroupRecord.currency),
|
Amounts.zeroOfCurrency(refreshGroupRecord.currency),
|
||||||
@ -1538,7 +1538,7 @@ export async function retryTransaction(
|
|||||||
switch (parsedTx.tag) {
|
switch (parsedTx.tag) {
|
||||||
case TransactionType.PeerPullCredit: {
|
case TransactionType.PeerPullCredit: {
|
||||||
const taskId = constructTaskIdentifier({
|
const taskId = constructTaskIdentifier({
|
||||||
tag: PendingTaskType.PeerPullInitiation,
|
tag: PendingTaskType.PeerPullCredit,
|
||||||
pursePub: parsedTx.pursePub,
|
pursePub: parsedTx.pursePub,
|
||||||
});
|
});
|
||||||
await resetOperationTimeout(ws, taskId);
|
await resetOperationTimeout(ws, taskId);
|
||||||
@ -1866,7 +1866,7 @@ export async function abortTransaction(
|
|||||||
|
|
||||||
switch (txId.tag) {
|
switch (txId.tag) {
|
||||||
case TransactionType.Payment: {
|
case TransactionType.Payment: {
|
||||||
await abortPay(ws, txId.proposalId);
|
await abortPayMerchant(ws, txId.proposalId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TransactionType.Withdrawal: {
|
case TransactionType.Withdrawal: {
|
||||||
|
@ -135,6 +135,7 @@ import {
|
|||||||
notifyTransition,
|
notifyTransition,
|
||||||
stopLongpolling,
|
stopLongpolling,
|
||||||
} from "./transactions.js";
|
} from "./transactions.js";
|
||||||
|
import { assertUnreachable } from "../util/assertUnreachable.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger for this file.
|
* Logger for this file.
|
||||||
@ -160,25 +161,25 @@ export async function suspendWithdrawalTransaction(
|
|||||||
}
|
}
|
||||||
let newStatus: WithdrawalGroupStatus | undefined = undefined;
|
let newStatus: WithdrawalGroupStatus | undefined = undefined;
|
||||||
switch (wg.status) {
|
switch (wg.status) {
|
||||||
case WithdrawalGroupStatus.Ready:
|
case WithdrawalGroupStatus.PendingReady:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedReady;
|
newStatus = WithdrawalGroupStatus.SuspendedReady;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.AbortingBank:
|
case WithdrawalGroupStatus.AbortingBank:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedAbortingBank;
|
newStatus = WithdrawalGroupStatus.SuspendedAbortingBank;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedWaitConfirmBank;
|
newStatus = WithdrawalGroupStatus.SuspendedWaitConfirmBank;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedRegisteringBank;
|
newStatus = WithdrawalGroupStatus.SuspendedRegisteringBank;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.QueryingStatus:
|
case WithdrawalGroupStatus.PendingQueryingStatus:
|
||||||
newStatus = WithdrawalGroupStatus.QueryingStatus;
|
newStatus = WithdrawalGroupStatus.SuspendedQueryingStatus;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.Kyc:
|
case WithdrawalGroupStatus.PendingKyc:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedKyc;
|
newStatus = WithdrawalGroupStatus.SuspendedKyc;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.Aml:
|
case WithdrawalGroupStatus.PendingAml:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedAml;
|
newStatus = WithdrawalGroupStatus.SuspendedAml;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -221,25 +222,25 @@ export async function resumeWithdrawalTransaction(
|
|||||||
let newStatus: WithdrawalGroupStatus | undefined = undefined;
|
let newStatus: WithdrawalGroupStatus | undefined = undefined;
|
||||||
switch (wg.status) {
|
switch (wg.status) {
|
||||||
case WithdrawalGroupStatus.SuspendedReady:
|
case WithdrawalGroupStatus.SuspendedReady:
|
||||||
newStatus = WithdrawalGroupStatus.Ready;
|
newStatus = WithdrawalGroupStatus.PendingReady;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.SuspendedAbortingBank:
|
case WithdrawalGroupStatus.SuspendedAbortingBank:
|
||||||
newStatus = WithdrawalGroupStatus.AbortingBank;
|
newStatus = WithdrawalGroupStatus.AbortingBank;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
|
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
|
||||||
newStatus = WithdrawalGroupStatus.WaitConfirmBank;
|
newStatus = WithdrawalGroupStatus.PendingWaitConfirmBank;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.SuspendedQueryingStatus:
|
case WithdrawalGroupStatus.SuspendedQueryingStatus:
|
||||||
newStatus = WithdrawalGroupStatus.QueryingStatus;
|
newStatus = WithdrawalGroupStatus.PendingQueryingStatus;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.SuspendedRegisteringBank:
|
case WithdrawalGroupStatus.SuspendedRegisteringBank:
|
||||||
newStatus = WithdrawalGroupStatus.RegisteringBank;
|
newStatus = WithdrawalGroupStatus.PendingRegisteringBank;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.SuspendedAml:
|
case WithdrawalGroupStatus.SuspendedAml:
|
||||||
newStatus = WithdrawalGroupStatus.Aml;
|
newStatus = WithdrawalGroupStatus.PendingAml;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.SuspendedKyc:
|
case WithdrawalGroupStatus.SuspendedKyc:
|
||||||
newStatus = WithdrawalGroupStatus.Kyc;
|
newStatus = WithdrawalGroupStatus.PendingKyc;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.warn(
|
logger.warn(
|
||||||
@ -289,21 +290,21 @@ export async function abortWithdrawalTransaction(
|
|||||||
}
|
}
|
||||||
let newStatus: WithdrawalGroupStatus | undefined = undefined;
|
let newStatus: WithdrawalGroupStatus | undefined = undefined;
|
||||||
switch (wg.status) {
|
switch (wg.status) {
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
case WithdrawalGroupStatus.AbortingBank:
|
case WithdrawalGroupStatus.AbortingBank:
|
||||||
newStatus = WithdrawalGroupStatus.AbortingBank;
|
newStatus = WithdrawalGroupStatus.AbortingBank;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.Aml:
|
case WithdrawalGroupStatus.PendingAml:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedAml;
|
newStatus = WithdrawalGroupStatus.SuspendedAml;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.Kyc:
|
case WithdrawalGroupStatus.PendingKyc:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedKyc;
|
newStatus = WithdrawalGroupStatus.SuspendedKyc;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.QueryingStatus:
|
case WithdrawalGroupStatus.PendingQueryingStatus:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedQueryingStatus;
|
newStatus = WithdrawalGroupStatus.SuspendedQueryingStatus;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.Ready:
|
case WithdrawalGroupStatus.PendingReady:
|
||||||
newStatus = WithdrawalGroupStatus.SuspendedReady;
|
newStatus = WithdrawalGroupStatus.SuspendedReady;
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.SuspendedAbortingBank:
|
case WithdrawalGroupStatus.SuspendedAbortingBank:
|
||||||
@ -316,9 +317,13 @@ export async function abortWithdrawalTransaction(
|
|||||||
case WithdrawalGroupStatus.SuspendedRegisteringBank:
|
case WithdrawalGroupStatus.SuspendedRegisteringBank:
|
||||||
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
|
case WithdrawalGroupStatus.SuspendedWaitConfirmBank:
|
||||||
case WithdrawalGroupStatus.Finished:
|
case WithdrawalGroupStatus.Finished:
|
||||||
case WithdrawalGroupStatus.BankAborted:
|
case WithdrawalGroupStatus.FailedBankAborted:
|
||||||
|
case WithdrawalGroupStatus.AbortedExchange:
|
||||||
|
case WithdrawalGroupStatus.FailedAbortingBank:
|
||||||
// Not allowed
|
// Not allowed
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
assertUnreachable(wg.status);
|
||||||
}
|
}
|
||||||
if (newStatus != null) {
|
if (newStatus != null) {
|
||||||
const oldTxState = computeWithdrawalTransactionStatus(wg);
|
const oldTxState = computeWithdrawalTransactionStatus(wg);
|
||||||
@ -385,7 +390,7 @@ export function computeWithdrawalTransactionStatus(
|
|||||||
wgRecord: WithdrawalGroupRecord,
|
wgRecord: WithdrawalGroupRecord,
|
||||||
): TransactionState {
|
): TransactionState {
|
||||||
switch (wgRecord.status) {
|
switch (wgRecord.status) {
|
||||||
case WithdrawalGroupStatus.BankAborted:
|
case WithdrawalGroupStatus.FailedBankAborted:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Aborted,
|
major: TransactionMajorState.Aborted,
|
||||||
};
|
};
|
||||||
@ -393,22 +398,22 @@ export function computeWithdrawalTransactionStatus(
|
|||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Done,
|
major: TransactionMajorState.Done,
|
||||||
};
|
};
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Pending,
|
major: TransactionMajorState.Pending,
|
||||||
minor: TransactionMinorState.BankRegisterReserve,
|
minor: TransactionMinorState.BankRegisterReserve,
|
||||||
};
|
};
|
||||||
case WithdrawalGroupStatus.Ready:
|
case WithdrawalGroupStatus.PendingReady:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Pending,
|
major: TransactionMajorState.Pending,
|
||||||
minor: TransactionMinorState.WithdrawCoins,
|
minor: TransactionMinorState.WithdrawCoins,
|
||||||
};
|
};
|
||||||
case WithdrawalGroupStatus.QueryingStatus:
|
case WithdrawalGroupStatus.PendingQueryingStatus:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Pending,
|
major: TransactionMajorState.Pending,
|
||||||
minor: TransactionMinorState.ExchangeWaitReserve,
|
minor: TransactionMinorState.ExchangeWaitReserve,
|
||||||
};
|
};
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Pending,
|
major: TransactionMajorState.Pending,
|
||||||
minor: TransactionMinorState.BankConfirmTransfer,
|
minor: TransactionMinorState.BankConfirmTransfer,
|
||||||
@ -444,13 +449,13 @@ export function computeWithdrawalTransactionStatus(
|
|||||||
minor: TransactionMinorState.WithdrawCoins,
|
minor: TransactionMinorState.WithdrawCoins,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case WithdrawalGroupStatus.Aml: {
|
case WithdrawalGroupStatus.PendingAml: {
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Pending,
|
major: TransactionMajorState.Pending,
|
||||||
minor: TransactionMinorState.AmlRequired,
|
minor: TransactionMinorState.AmlRequired,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case WithdrawalGroupStatus.Kyc: {
|
case WithdrawalGroupStatus.PendingKyc: {
|
||||||
return {
|
return {
|
||||||
major: TransactionMajorState.Pending,
|
major: TransactionMajorState.Pending,
|
||||||
minor: TransactionMinorState.KycRequired,
|
minor: TransactionMinorState.KycRequired,
|
||||||
@ -473,6 +478,11 @@ export function computeWithdrawalTransactionStatus(
|
|||||||
major: TransactionMajorState.Failed,
|
major: TransactionMajorState.Failed,
|
||||||
minor: TransactionMinorState.AbortingBank,
|
minor: TransactionMinorState.AbortingBank,
|
||||||
};
|
};
|
||||||
|
case WithdrawalGroupStatus.AbortedExchange:
|
||||||
|
return {
|
||||||
|
major: TransactionMajorState.Aborted,
|
||||||
|
minor: TransactionMinorState.Exchange,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,7 +1132,7 @@ async function queryReserve(
|
|||||||
withdrawalGroupId,
|
withdrawalGroupId,
|
||||||
});
|
});
|
||||||
checkDbInvariant(!!withdrawalGroup);
|
checkDbInvariant(!!withdrawalGroup);
|
||||||
if (withdrawalGroup.status !== WithdrawalGroupStatus.QueryingStatus) {
|
if (withdrawalGroup.status !== WithdrawalGroupStatus.PendingQueryingStatus) {
|
||||||
return { ready: true };
|
return { ready: true };
|
||||||
}
|
}
|
||||||
const reservePub = withdrawalGroup.reservePub;
|
const reservePub = withdrawalGroup.reservePub;
|
||||||
@ -1135,7 +1145,7 @@ async function queryReserve(
|
|||||||
|
|
||||||
logger.info(`querying reserve status via ${reserveUrl.href}`);
|
logger.info(`querying reserve status via ${reserveUrl.href}`);
|
||||||
|
|
||||||
const resp = await ws.http.get(reserveUrl.href, {
|
const resp = await ws.http.fetch(reserveUrl.href, {
|
||||||
timeout: getReserveRequestTimeout(withdrawalGroup),
|
timeout: getReserveRequestTimeout(withdrawalGroup),
|
||||||
cancellationToken,
|
cancellationToken,
|
||||||
});
|
});
|
||||||
@ -1177,7 +1187,7 @@ async function queryReserve(
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const txStateOld = computeWithdrawalTransactionStatus(wg);
|
const txStateOld = computeWithdrawalTransactionStatus(wg);
|
||||||
wg.status = WithdrawalGroupStatus.Ready;
|
wg.status = WithdrawalGroupStatus.PendingReady;
|
||||||
const txStateNew = computeWithdrawalTransactionStatus(wg);
|
const txStateNew = computeWithdrawalTransactionStatus(wg);
|
||||||
wg.reserveBalanceAmount = Amounts.stringify(result.response.balance);
|
wg.reserveBalanceAmount = Amounts.stringify(result.response.balance);
|
||||||
await tx.withdrawalGroups.put(wg);
|
await tx.withdrawalGroups.put(wg);
|
||||||
@ -1250,12 +1260,12 @@ export async function processWithdrawalGroup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (withdrawalGroup.status) {
|
switch (withdrawalGroup.status) {
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
await processReserveBankStatus(ws, withdrawalGroupId);
|
await processReserveBankStatus(ws, withdrawalGroupId);
|
||||||
return await processWithdrawalGroup(ws, withdrawalGroupId, {
|
return await processWithdrawalGroup(ws, withdrawalGroupId, {
|
||||||
forceNow: true,
|
forceNow: true,
|
||||||
});
|
});
|
||||||
case WithdrawalGroupStatus.QueryingStatus: {
|
case WithdrawalGroupStatus.PendingQueryingStatus: {
|
||||||
runLongpollAsync(ws, retryTag, (ct) => {
|
runLongpollAsync(ws, retryTag, (ct) => {
|
||||||
return queryReserve(ws, withdrawalGroupId, ct);
|
return queryReserve(ws, withdrawalGroupId, ct);
|
||||||
});
|
});
|
||||||
@ -1266,7 +1276,7 @@ export async function processWithdrawalGroup(
|
|||||||
type: OperationAttemptResultType.Longpoll,
|
type: OperationAttemptResultType.Longpoll,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank: {
|
case WithdrawalGroupStatus.PendingWaitConfirmBank: {
|
||||||
const res = await processReserveBankStatus(ws, withdrawalGroupId);
|
const res = await processReserveBankStatus(ws, withdrawalGroupId);
|
||||||
switch (res.status) {
|
switch (res.status) {
|
||||||
case BankStatusResultCode.Aborted:
|
case BankStatusResultCode.Aborted:
|
||||||
@ -1284,7 +1294,7 @@ export async function processWithdrawalGroup(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WithdrawalGroupStatus.BankAborted: {
|
case WithdrawalGroupStatus.FailedBankAborted: {
|
||||||
// FIXME
|
// FIXME
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Pending,
|
type: OperationAttemptResultType.Pending,
|
||||||
@ -1294,7 +1304,7 @@ export async function processWithdrawalGroup(
|
|||||||
case WithdrawalGroupStatus.Finished:
|
case WithdrawalGroupStatus.Finished:
|
||||||
// We can try to withdraw, nothing needs to be done with the reserve.
|
// We can try to withdraw, nothing needs to be done with the reserve.
|
||||||
break;
|
break;
|
||||||
case WithdrawalGroupStatus.Ready:
|
case WithdrawalGroupStatus.PendingReady:
|
||||||
// Continue with the actual withdrawal!
|
// Continue with the actual withdrawal!
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1847,8 +1857,8 @@ async function registerReserveWithBank(
|
|||||||
withdrawalGroupId,
|
withdrawalGroupId,
|
||||||
});
|
});
|
||||||
switch (withdrawalGroup?.status) {
|
switch (withdrawalGroup?.status) {
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1885,8 +1895,8 @@ async function registerReserveWithBank(
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
switch (r.status) {
|
switch (r.status) {
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1898,7 +1908,7 @@ async function registerReserveWithBank(
|
|||||||
AbsoluteTime.now(),
|
AbsoluteTime.now(),
|
||||||
);
|
);
|
||||||
const oldTxState = computeWithdrawalTransactionStatus(r);
|
const oldTxState = computeWithdrawalTransactionStatus(r);
|
||||||
r.status = WithdrawalGroupStatus.WaitConfirmBank;
|
r.status = WithdrawalGroupStatus.PendingWaitConfirmBank;
|
||||||
const newTxState = computeWithdrawalTransactionStatus(r);
|
const newTxState = computeWithdrawalTransactionStatus(r);
|
||||||
await tx.withdrawalGroups.put(r);
|
await tx.withdrawalGroups.put(r);
|
||||||
return {
|
return {
|
||||||
@ -1928,8 +1938,8 @@ async function processReserveBankStatus(
|
|||||||
withdrawalGroupId,
|
withdrawalGroupId,
|
||||||
});
|
});
|
||||||
switch (withdrawalGroup?.status) {
|
switch (withdrawalGroup?.status) {
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
@ -1969,8 +1979,8 @@ async function processReserveBankStatus(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (r.status) {
|
switch (r.status) {
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1981,7 +1991,7 @@ async function processReserveBankStatus(
|
|||||||
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
|
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
|
||||||
const oldTxState = computeWithdrawalTransactionStatus(r);
|
const oldTxState = computeWithdrawalTransactionStatus(r);
|
||||||
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
||||||
r.status = WithdrawalGroupStatus.BankAborted;
|
r.status = WithdrawalGroupStatus.FailedBankAborted;
|
||||||
const newTxState = computeWithdrawalTransactionStatus(r);
|
const newTxState = computeWithdrawalTransactionStatus(r);
|
||||||
await tx.withdrawalGroups.put(r);
|
await tx.withdrawalGroups.put(r);
|
||||||
return {
|
return {
|
||||||
@ -2002,7 +2012,7 @@ async function processReserveBankStatus(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Why do we do this?!
|
// FIXME: Why do we do this?!
|
||||||
if (withdrawalGroup.status === WithdrawalGroupStatus.RegisteringBank) {
|
if (withdrawalGroup.status === WithdrawalGroupStatus.PendingRegisteringBank) {
|
||||||
await registerReserveWithBank(ws, withdrawalGroupId);
|
await registerReserveWithBank(ws, withdrawalGroupId);
|
||||||
return await processReserveBankStatus(ws, withdrawalGroupId);
|
return await processReserveBankStatus(ws, withdrawalGroupId);
|
||||||
}
|
}
|
||||||
@ -2016,8 +2026,8 @@ async function processReserveBankStatus(
|
|||||||
}
|
}
|
||||||
// Re-check reserve status within transaction
|
// Re-check reserve status within transaction
|
||||||
switch (r.status) {
|
switch (r.status) {
|
||||||
case WithdrawalGroupStatus.RegisteringBank:
|
case WithdrawalGroupStatus.PendingRegisteringBank:
|
||||||
case WithdrawalGroupStatus.WaitConfirmBank:
|
case WithdrawalGroupStatus.PendingWaitConfirmBank:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -2030,7 +2040,7 @@ async function processReserveBankStatus(
|
|||||||
logger.info("withdrawal: transfer confirmed by bank.");
|
logger.info("withdrawal: transfer confirmed by bank.");
|
||||||
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
|
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
|
||||||
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
r.wgInfo.bankInfo.timestampBankConfirmed = now;
|
||||||
r.status = WithdrawalGroupStatus.QueryingStatus;
|
r.status = WithdrawalGroupStatus.PendingQueryingStatus;
|
||||||
// FIXME: Notification is deprecated with DD37.
|
// FIXME: Notification is deprecated with DD37.
|
||||||
ws.notify({
|
ws.notify({
|
||||||
type: NotificationType.WithdrawalGroupBankConfirmed,
|
type: NotificationType.WithdrawalGroupBankConfirmed,
|
||||||
@ -2276,7 +2286,7 @@ export async function acceptWithdrawalFromUri(
|
|||||||
},
|
},
|
||||||
restrictAge: req.restrictAge,
|
restrictAge: req.restrictAge,
|
||||||
forcedDenomSel: req.forcedDenomSel,
|
forcedDenomSel: req.forcedDenomSel,
|
||||||
reserveStatus: WithdrawalGroupStatus.RegisteringBank,
|
reserveStatus: WithdrawalGroupStatus.PendingRegisteringBank,
|
||||||
});
|
});
|
||||||
|
|
||||||
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
||||||
@ -2291,19 +2301,14 @@ export async function acceptWithdrawalFromUri(
|
|||||||
const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, {
|
const processedWithdrawalGroup = await getWithdrawalGroupRecordTx(ws.db, {
|
||||||
withdrawalGroupId,
|
withdrawalGroupId,
|
||||||
});
|
});
|
||||||
if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.BankAborted) {
|
if (processedWithdrawalGroup?.status === WithdrawalGroupStatus.FailedBankAborted) {
|
||||||
throw TalerError.fromDetail(
|
throw TalerError.fromDetail(
|
||||||
TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK,
|
TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start withdrawal in the background
|
ws.workAvailable.trigger();
|
||||||
processWithdrawalGroup(ws, withdrawalGroupId, {
|
|
||||||
forceNow: true,
|
|
||||||
}).catch((err) => {
|
|
||||||
logger.error("Processing withdrawal (after creation) failed:", err);
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reservePub: withdrawalGroup.reservePub,
|
reservePub: withdrawalGroup.reservePub,
|
||||||
@ -2337,7 +2342,7 @@ export async function createManualWithdrawal(
|
|||||||
exchangeBaseUrl: req.exchangeBaseUrl,
|
exchangeBaseUrl: req.exchangeBaseUrl,
|
||||||
forcedDenomSel: req.forcedDenomSel,
|
forcedDenomSel: req.forcedDenomSel,
|
||||||
restrictAge: req.restrictAge,
|
restrictAge: req.restrictAge,
|
||||||
reserveStatus: WithdrawalGroupStatus.QueryingStatus,
|
reserveStatus: WithdrawalGroupStatus.PendingQueryingStatus,
|
||||||
});
|
});
|
||||||
|
|
||||||
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
||||||
@ -2357,18 +2362,7 @@ export async function createManualWithdrawal(
|
|||||||
return await getFundingPaytoUris(tx, withdrawalGroup.withdrawalGroupId);
|
return await getFundingPaytoUris(tx, withdrawalGroup.withdrawalGroupId);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start withdrawal in the background (do not await!)
|
ws.workAvailable.trigger();
|
||||||
// FIXME: We could also interrupt the task look if it is waiting and
|
|
||||||
// rely on retry handling to re-process the withdrawal group.
|
|
||||||
runOperationWithErrorReporting(
|
|
||||||
ws,
|
|
||||||
TaskIdentifiers.forWithdrawal(withdrawalGroup),
|
|
||||||
async () => {
|
|
||||||
return await processWithdrawalGroup(ws, withdrawalGroupId, {
|
|
||||||
forceNow: true,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reservePub: withdrawalGroup.reservePub,
|
reservePub: withdrawalGroup.reservePub,
|
||||||
|
@ -37,9 +37,8 @@ export enum PendingTaskType {
|
|||||||
Withdraw = "withdraw",
|
Withdraw = "withdraw",
|
||||||
Deposit = "deposit",
|
Deposit = "deposit",
|
||||||
Backup = "backup",
|
Backup = "backup",
|
||||||
// FIXME: Rename to peer-push-debit and peer-pull-debit
|
PeerPushDebit = "peer-push-debit",
|
||||||
PeerPushInitiation = "peer-push-initiation",
|
PeerPullCredit = "peer-pull-credit",
|
||||||
PeerPullInitiation = "peer-pull-initiation",
|
|
||||||
PeerPushCredit = "peer-push-credit",
|
PeerPushCredit = "peer-push-credit",
|
||||||
PeerPullDebit = "peer-pull-debit",
|
PeerPullDebit = "peer-pull-debit",
|
||||||
}
|
}
|
||||||
@ -83,7 +82,7 @@ export interface PendingExchangeUpdateTask {
|
|||||||
* The wallet wants to send a peer push payment.
|
* The wallet wants to send a peer push payment.
|
||||||
*/
|
*/
|
||||||
export interface PendingPeerPushInitiationTask {
|
export interface PendingPeerPushInitiationTask {
|
||||||
type: PendingTaskType.PeerPushInitiation;
|
type: PendingTaskType.PeerPushDebit;
|
||||||
pursePub: string;
|
pursePub: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +90,7 @@ export interface PendingPeerPushInitiationTask {
|
|||||||
* The wallet wants to send a peer pull payment.
|
* The wallet wants to send a peer pull payment.
|
||||||
*/
|
*/
|
||||||
export interface PendingPeerPullInitiationTask {
|
export interface PendingPeerPullInitiationTask {
|
||||||
type: PendingTaskType.PeerPullInitiation;
|
type: PendingTaskType.PeerPullCredit;
|
||||||
pursePub: string;
|
pursePub: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,9 +197,9 @@ export type ParsedTaskIdentifier =
|
|||||||
| { tag: PendingTaskType.ExchangeCheckRefresh; exchangeBaseUrl: string }
|
| { tag: PendingTaskType.ExchangeCheckRefresh; exchangeBaseUrl: string }
|
||||||
| { tag: PendingTaskType.ExchangeUpdate; exchangeBaseUrl: string }
|
| { tag: PendingTaskType.ExchangeUpdate; exchangeBaseUrl: string }
|
||||||
| { tag: PendingTaskType.PeerPullDebit; peerPullPaymentIncomingId: string }
|
| { tag: PendingTaskType.PeerPullDebit; peerPullPaymentIncomingId: string }
|
||||||
| { tag: PendingTaskType.PeerPullInitiation; pursePub: string }
|
| { tag: PendingTaskType.PeerPullCredit; pursePub: string }
|
||||||
| { tag: PendingTaskType.PeerPushCredit; peerPushPaymentIncomingId: string }
|
| { tag: PendingTaskType.PeerPushCredit; peerPushPaymentIncomingId: string }
|
||||||
| { tag: PendingTaskType.PeerPushInitiation; pursePub: string }
|
| { tag: PendingTaskType.PeerPushDebit; pursePub: string }
|
||||||
| { tag: PendingTaskType.Purchase; proposalId: string }
|
| { tag: PendingTaskType.Purchase; proposalId: string }
|
||||||
| { tag: PendingTaskType.Recoup; recoupGroupId: string }
|
| { tag: PendingTaskType.Recoup; recoupGroupId: string }
|
||||||
| { tag: PendingTaskType.TipPickup; walletTipId: string }
|
| { tag: PendingTaskType.TipPickup; walletTipId: string }
|
||||||
@ -223,9 +223,9 @@ export function constructTaskIdentifier(p: ParsedTaskIdentifier): string {
|
|||||||
return `${p.tag}:${p.peerPullPaymentIncomingId}`;
|
return `${p.tag}:${p.peerPullPaymentIncomingId}`;
|
||||||
case PendingTaskType.PeerPushCredit:
|
case PendingTaskType.PeerPushCredit:
|
||||||
return `${p.tag}:${p.peerPushPaymentIncomingId}`;
|
return `${p.tag}:${p.peerPushPaymentIncomingId}`;
|
||||||
case PendingTaskType.PeerPullInitiation:
|
case PendingTaskType.PeerPullCredit:
|
||||||
return `${p.tag}:${p.pursePub}`;
|
return `${p.tag}:${p.pursePub}`;
|
||||||
case PendingTaskType.PeerPushInitiation:
|
case PendingTaskType.PeerPushDebit:
|
||||||
return `${p.tag}:${p.pursePub}`;
|
return `${p.tag}:${p.pursePub}`;
|
||||||
case PendingTaskType.Purchase:
|
case PendingTaskType.Purchase:
|
||||||
return `${p.tag}:${p.proposalId}`;
|
return `${p.tag}:${p.proposalId}`;
|
||||||
@ -276,12 +276,12 @@ export namespace TaskIdentifiers {
|
|||||||
export function forPeerPushPaymentInitiation(
|
export function forPeerPushPaymentInitiation(
|
||||||
ppi: PeerPushPaymentInitiationRecord,
|
ppi: PeerPushPaymentInitiationRecord,
|
||||||
): string {
|
): string {
|
||||||
return `${PendingTaskType.PeerPushInitiation}:${ppi.pursePub}`;
|
return `${PendingTaskType.PeerPushDebit}:${ppi.pursePub}`;
|
||||||
}
|
}
|
||||||
export function forPeerPullPaymentInitiation(
|
export function forPeerPullPaymentInitiation(
|
||||||
ppi: PeerPullPaymentInitiationRecord,
|
ppi: PeerPullPaymentInitiationRecord,
|
||||||
): string {
|
): string {
|
||||||
return `${PendingTaskType.PeerPullInitiation}:${ppi.pursePub}`;
|
return `${PendingTaskType.PeerPullCredit}:${ppi.pursePub}`;
|
||||||
}
|
}
|
||||||
export function forPeerPullPaymentDebit(
|
export function forPeerPullPaymentDebit(
|
||||||
ppi: PeerPullPaymentIncomingRecord,
|
ppi: PeerPullPaymentIncomingRecord,
|
||||||
|
@ -208,7 +208,7 @@ import {
|
|||||||
processPeerPullCredit,
|
processPeerPullCredit,
|
||||||
processPeerPullDebit,
|
processPeerPullDebit,
|
||||||
processPeerPushCredit,
|
processPeerPushCredit,
|
||||||
processPeerPushInitiation,
|
processPeerPushDebit,
|
||||||
} from "./operations/pay-peer.js";
|
} from "./operations/pay-peer.js";
|
||||||
import { getPendingOperations } from "./operations/pending.js";
|
import { getPendingOperations } from "./operations/pending.js";
|
||||||
import {
|
import {
|
||||||
@ -314,9 +314,9 @@ async function callOperationHandler(
|
|||||||
}
|
}
|
||||||
case PendingTaskType.Backup:
|
case PendingTaskType.Backup:
|
||||||
return await processBackupForProvider(ws, pending.backupProviderBaseUrl);
|
return await processBackupForProvider(ws, pending.backupProviderBaseUrl);
|
||||||
case PendingTaskType.PeerPushInitiation:
|
case PendingTaskType.PeerPushDebit:
|
||||||
return await processPeerPushInitiation(ws, pending.pursePub);
|
return await processPeerPushDebit(ws, pending.pursePub);
|
||||||
case PendingTaskType.PeerPullInitiation:
|
case PendingTaskType.PeerPullCredit:
|
||||||
return await processPeerPullCredit(ws, pending.pursePub);
|
return await processPeerPullCredit(ws, pending.pursePub);
|
||||||
case PendingTaskType.PeerPullDebit:
|
case PendingTaskType.PeerPullDebit:
|
||||||
return await processPeerPullDebit(ws, pending.peerPullPaymentIncomingId);
|
return await processPeerPullDebit(ws, pending.peerPullPaymentIncomingId);
|
||||||
@ -439,7 +439,7 @@ async function runTaskLoop(
|
|||||||
});
|
});
|
||||||
// Wait until either the timeout, or we are notified (via the latch)
|
// Wait until either the timeout, or we are notified (via the latch)
|
||||||
// that more work might be available.
|
// that more work might be available.
|
||||||
await Promise.race([timeout, ws.latch.wait()]);
|
await Promise.race([timeout, ws.workAvailable.wait()]);
|
||||||
} else {
|
} else {
|
||||||
logger.trace(
|
logger.trace(
|
||||||
`running ${pending.pendingOperations.length} pending operations`,
|
`running ${pending.pendingOperations.length} pending operations`,
|
||||||
@ -1659,7 +1659,7 @@ class InternalWalletStateImpl implements InternalWalletState {
|
|||||||
merchantInfoCache: Record<string, MerchantInfo> = {};
|
merchantInfoCache: Record<string, MerchantInfo> = {};
|
||||||
|
|
||||||
readonly timerGroup: TimerGroup;
|
readonly timerGroup: TimerGroup;
|
||||||
latch = new AsyncCondition();
|
workAvailable = new AsyncCondition();
|
||||||
stopped = false;
|
stopped = false;
|
||||||
|
|
||||||
listeners: NotificationListener[] = [];
|
listeners: NotificationListener[] = [];
|
||||||
|
Loading…
Reference in New Issue
Block a user