wallet-core,harness: introduce reserveIsReady flag, test tx lifeycle
This commit is contained in:
parent
79b77a0c3c
commit
22cb8adaa6
@ -1169,6 +1169,29 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
return !!this.exchangeWirewatchProc || !!this.exchangeHttpProc;
|
return !!this.exchangeWirewatchProc || !!this.exchangeHttpProc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the wirewatch service (which runs by default).
|
||||||
|
*
|
||||||
|
* Useful for some tests.
|
||||||
|
*/
|
||||||
|
async stopWirewatch(): Promise<void> {
|
||||||
|
const wirewatch = this.exchangeWirewatchProc;
|
||||||
|
if (wirewatch) {
|
||||||
|
wirewatch.proc.kill("SIGTERM");
|
||||||
|
await wirewatch.wait();
|
||||||
|
this.exchangeWirewatchProc = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async startWirewatch(): Promise<void> {
|
||||||
|
const wirewatch = this.exchangeWirewatchProc;
|
||||||
|
if (wirewatch) {
|
||||||
|
logger.warn("wirewatch already running");
|
||||||
|
} else {
|
||||||
|
this.internalCreateWirewatchProc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async stop(): Promise<void> {
|
async stop(): Promise<void> {
|
||||||
const wirewatch = this.exchangeWirewatchProc;
|
const wirewatch = this.exchangeWirewatchProc;
|
||||||
if (wirewatch) {
|
if (wirewatch) {
|
||||||
@ -1332,6 +1355,19 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private internalCreateWirewatchProc() {
|
||||||
|
this.exchangeWirewatchProc = this.globalState.spawnService(
|
||||||
|
"taler-exchange-wirewatch",
|
||||||
|
[
|
||||||
|
"-c",
|
||||||
|
this.configFilename,
|
||||||
|
"--longpoll-timeout=5s",
|
||||||
|
...this.timetravelArgArr,
|
||||||
|
],
|
||||||
|
`exchange-wirewatch-${this.name}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async start(): Promise<void> {
|
async start(): Promise<void> {
|
||||||
if (this.isRunning()) {
|
if (this.isRunning()) {
|
||||||
throw Error("exchange is already running");
|
throw Error("exchange is already running");
|
||||||
@ -1360,16 +1396,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
`exchange-crypto-rsa-${this.name}`,
|
`exchange-crypto-rsa-${this.name}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.exchangeWirewatchProc = this.globalState.spawnService(
|
this.internalCreateWirewatchProc();
|
||||||
"taler-exchange-wirewatch",
|
|
||||||
[
|
|
||||||
"-c",
|
|
||||||
this.configFilename,
|
|
||||||
"--longpoll-timeout=5s",
|
|
||||||
...this.timetravelArgArr,
|
|
||||||
],
|
|
||||||
`exchange-wirewatch-${this.name}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.exchangeHttpProc = this.globalState.spawnService(
|
this.exchangeHttpProc = this.globalState.spawnService(
|
||||||
"taler-exchange-httpd",
|
"taler-exchange-httpd",
|
||||||
|
@ -209,7 +209,7 @@ export async function createSimpleTestkudosEnvironmentV2(
|
|||||||
t: GlobalTestState,
|
t: GlobalTestState,
|
||||||
coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS")),
|
coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS")),
|
||||||
opts: EnvOptions = {},
|
opts: EnvOptions = {},
|
||||||
): Promise<SimpleTestEnvironment> {
|
): Promise<SimpleTestEnvironmentNg> {
|
||||||
const db = await setupDb(t);
|
const db = await setupDb(t);
|
||||||
|
|
||||||
const bank = await BankService.create(t, {
|
const bank = await BankService.create(t, {
|
||||||
@ -293,15 +293,32 @@ export async function createSimpleTestkudosEnvironmentV2(
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
const walletService = new WalletService(t, {
|
||||||
|
name: "wallet",
|
||||||
|
useInMemoryDb: true,
|
||||||
|
});
|
||||||
|
await walletService.start();
|
||||||
|
await walletService.pingUntilAvailable();
|
||||||
|
|
||||||
const wallet = new WalletCli(t);
|
const walletClient = new WalletClient({
|
||||||
|
unixPath: walletService.socketPath,
|
||||||
|
onNotification(n) {
|
||||||
|
console.log("got notification", n);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await walletClient.connect();
|
||||||
|
await walletClient.client.call(WalletApiOperation.InitWallet, {
|
||||||
|
skipDefaults: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("setup done!");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
commonDb: db,
|
commonDb: db,
|
||||||
exchange,
|
exchange,
|
||||||
merchant,
|
merchant,
|
||||||
wallet,
|
walletClient,
|
||||||
|
walletService,
|
||||||
bank,
|
bank,
|
||||||
exchangeBankAccount,
|
exchangeBankAccount,
|
||||||
};
|
};
|
||||||
|
@ -307,7 +307,7 @@ export async function runKycTest(t: GlobalTestState) {
|
|||||||
// Withdraw
|
// Withdraw
|
||||||
|
|
||||||
const kycNotificationCond = walletClient.waitForNotificationCond((x) => {
|
const kycNotificationCond = walletClient.waitForNotificationCond((x) => {
|
||||||
if (x.type === NotificationType.WithdrawalKycRequested) {
|
if (x.type === NotificationType.WithdrawalGroupKycRequested) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -18,13 +18,13 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
||||||
import {
|
import {
|
||||||
WalletApiOperation,
|
WalletApiOperation,
|
||||||
BankApi,
|
BankApi,
|
||||||
BankAccessApi,
|
BankAccessApi,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import { j2s } from "@gnu-taler/taler-util";
|
import { j2s, NotificationType, TransactionType, WithdrawalType } from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal.
|
* Run test for basic, bank-integrated withdrawal.
|
||||||
@ -32,7 +32,8 @@ import { j2s } from "@gnu-taler/taler-util";
|
|||||||
export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) {
|
export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { wallet, bank, exchange } = await createSimpleTestkudosEnvironment(t);
|
const { walletClient, bank, exchange } =
|
||||||
|
await createSimpleTestkudosEnvironmentV2(t);
|
||||||
|
|
||||||
// Create a withdrawal operation
|
// Create a withdrawal operation
|
||||||
|
|
||||||
@ -45,46 +46,117 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Hand it to the wallet
|
// Hand it to the wallet
|
||||||
|
|
||||||
const r1 = await wallet.client.call(
|
const r1 = await walletClient.client.call(
|
||||||
WalletApiOperation.GetWithdrawalDetailsForUri,
|
WalletApiOperation.GetWithdrawalDetailsForUri,
|
||||||
{
|
{
|
||||||
talerWithdrawUri: wop.taler_withdraw_uri,
|
talerWithdrawUri: wop.taler_withdraw_uri,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
await wallet.runPending();
|
|
||||||
|
|
||||||
// Withdraw
|
// Withdraw
|
||||||
|
|
||||||
const r2 = await wallet.client.call(
|
const withdrawalBankConfirmedCond = walletClient.waitForNotificationCond(
|
||||||
|
(x) => {
|
||||||
|
return x.type === NotificationType.WithdrawalGroupBankConfirmed;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const withdrawalFinishedCond = walletClient.waitForNotificationCond((x) => {
|
||||||
|
return x.type === NotificationType.WithdrawGroupFinished;
|
||||||
|
});
|
||||||
|
|
||||||
|
const withdrawalReserveReadyCond = walletClient.waitForNotificationCond(
|
||||||
|
(x) => {
|
||||||
|
return x.type === NotificationType.WithdrawalGroupReserveReady;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const r2 = await walletClient.client.call(
|
||||||
WalletApiOperation.AcceptBankIntegratedWithdrawal,
|
WalletApiOperation.AcceptBankIntegratedWithdrawal,
|
||||||
{
|
{
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
talerWithdrawUri: wop.taler_withdraw_uri,
|
talerWithdrawUri: wop.taler_withdraw_uri,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Do it twice to check idempotency
|
// Do it twice to check idempotency
|
||||||
const r3 = await wallet.client.call(
|
const r3 = await walletClient.client.call(
|
||||||
WalletApiOperation.AcceptBankIntegratedWithdrawal,
|
WalletApiOperation.AcceptBankIntegratedWithdrawal,
|
||||||
{
|
{
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
talerWithdrawUri: wop.taler_withdraw_uri,
|
talerWithdrawUri: wop.taler_withdraw_uri,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await wallet.runPending();
|
|
||||||
|
await exchange.stopWirewatch();
|
||||||
|
|
||||||
|
// Check status before withdrawal is confirmed by bank.
|
||||||
|
{
|
||||||
|
const txn = await walletClient.client.call(
|
||||||
|
WalletApiOperation.GetTransactions,
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
console.log("transactions before confirmation:", j2s(txn));
|
||||||
|
const tx0 = txn.transactions[0];
|
||||||
|
t.assertTrue(tx0.type === TransactionType.Withdrawal);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.type === WithdrawalType.TalerBankIntegrationApi);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.confirmed === false);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.reserveIsReady === false);
|
||||||
|
}
|
||||||
|
|
||||||
// Confirm it
|
// Confirm it
|
||||||
|
|
||||||
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
await wallet.runUntilDone();
|
await withdrawalBankConfirmedCond;
|
||||||
|
|
||||||
|
// Check status after withdrawal is confirmed by bank,
|
||||||
|
// but before funds are wired to the exchange.
|
||||||
|
{
|
||||||
|
const txn = await walletClient.client.call(
|
||||||
|
WalletApiOperation.GetTransactions,
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
console.log("transactions after confirmation:", j2s(txn));
|
||||||
|
const tx0 = txn.transactions[0];
|
||||||
|
t.assertTrue(tx0.type === TransactionType.Withdrawal);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.type === WithdrawalType.TalerBankIntegrationApi);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.confirmed === true);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.reserveIsReady === false);
|
||||||
|
}
|
||||||
|
|
||||||
|
await exchange.startWirewatch();
|
||||||
|
|
||||||
|
await withdrawalReserveReadyCond;
|
||||||
|
|
||||||
|
// Check status after funds were wired.
|
||||||
|
{
|
||||||
|
const txn = await walletClient.client.call(
|
||||||
|
WalletApiOperation.GetTransactions,
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
console.log("transactions after reserve ready:", j2s(txn));
|
||||||
|
const tx0 = txn.transactions[0];
|
||||||
|
t.assertTrue(tx0.type === TransactionType.Withdrawal);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.type === WithdrawalType.TalerBankIntegrationApi);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.confirmed === true);
|
||||||
|
t.assertTrue(tx0.withdrawalDetails.reserveIsReady === true);
|
||||||
|
}
|
||||||
|
|
||||||
|
await withdrawalFinishedCond;
|
||||||
|
|
||||||
// Check balance
|
// Check balance
|
||||||
|
|
||||||
const balResp = await wallet.client.call(WalletApiOperation.GetBalances, {});
|
const balResp = await walletClient.client.call(
|
||||||
|
WalletApiOperation.GetBalances,
|
||||||
|
{},
|
||||||
|
);
|
||||||
t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available);
|
t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available);
|
||||||
|
|
||||||
const txn = await wallet.client.call(WalletApiOperation.GetTransactions, {});
|
const txn = await walletClient.client.call(
|
||||||
|
WalletApiOperation.GetTransactions,
|
||||||
|
{},
|
||||||
|
);
|
||||||
console.log(`transactions: ${j2s(txn)}`);
|
console.log(`transactions: ${j2s(txn)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,9 @@ export enum NotificationType {
|
|||||||
PendingOperationProcessed = "pending-operation-processed",
|
PendingOperationProcessed = "pending-operation-processed",
|
||||||
ProposalRefused = "proposal-refused",
|
ProposalRefused = "proposal-refused",
|
||||||
ReserveRegisteredWithBank = "reserve-registered-with-bank",
|
ReserveRegisteredWithBank = "reserve-registered-with-bank",
|
||||||
WithdrawalKycRequested = "withdrawal-kyc-requested",
|
WithdrawalGroupKycRequested = "withdrawal-group-kyc-requested",
|
||||||
|
WithdrawalGroupBankConfirmed = "withdrawal-group-bank-confirmed",
|
||||||
|
WithdrawalGroupReserveReady = "withdrawal-group-reserve-ready",
|
||||||
DepositOperationError = "deposit-operation-error",
|
DepositOperationError = "deposit-operation-error",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,12 +120,22 @@ export interface RefreshMeltedNotification {
|
|||||||
type: NotificationType.RefreshMelted;
|
type: NotificationType.RefreshMelted;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WithdrawalKycRequested {
|
export interface WithdrawalGroupKycRequested {
|
||||||
type: NotificationType.WithdrawalKycRequested;
|
type: NotificationType.WithdrawalGroupKycRequested;
|
||||||
transactionId: string;
|
transactionId: string;
|
||||||
kycUrl: string;
|
kycUrl: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WithdrawalGroupBankConfirmed {
|
||||||
|
type: NotificationType.WithdrawalGroupBankConfirmed;
|
||||||
|
transactionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WithdrawalGroupReserveReady {
|
||||||
|
type: NotificationType.WithdrawalGroupReserveReady;
|
||||||
|
transactionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface RefreshRevealedNotification {
|
export interface RefreshRevealedNotification {
|
||||||
type: NotificationType.RefreshRevealed;
|
type: NotificationType.RefreshRevealed;
|
||||||
}
|
}
|
||||||
@ -293,4 +305,6 @@ export type WalletNotification =
|
|||||||
| ReserveRegisteredWithBankNotification
|
| ReserveRegisteredWithBankNotification
|
||||||
| ReserveNotYetFoundNotification
|
| ReserveNotYetFoundNotification
|
||||||
| PayOperationSuccessNotification
|
| PayOperationSuccessNotification
|
||||||
| WithdrawalKycRequested;
|
| WithdrawalGroupKycRequested
|
||||||
|
| WithdrawalGroupBankConfirmed
|
||||||
|
| WithdrawalGroupReserveReady;
|
||||||
|
@ -167,6 +167,11 @@ interface WithdrawalDetailsForManualTransfer {
|
|||||||
|
|
||||||
// Public key of the reserve
|
// Public key of the reserve
|
||||||
reservePub: string;
|
reservePub: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the reserve ready for withdrawal?
|
||||||
|
*/
|
||||||
|
reserveIsReady: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WithdrawalDetailsForTalerBankIntegrationApi {
|
interface WithdrawalDetailsForTalerBankIntegrationApi {
|
||||||
@ -187,6 +192,11 @@ interface WithdrawalDetailsForTalerBankIntegrationApi {
|
|||||||
|
|
||||||
// Public key of the reserve
|
// Public key of the reserve
|
||||||
reservePub: string;
|
reservePub: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the reserve ready for withdrawal?
|
||||||
|
*/
|
||||||
|
reserveIsReady: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should only be used for actual withdrawals
|
// This should only be used for actual withdrawals
|
||||||
|
@ -55,6 +55,7 @@ import {
|
|||||||
PeerPushPaymentInitiationStatus,
|
PeerPushPaymentInitiationStatus,
|
||||||
PeerPullPaymentIncomingStatus,
|
PeerPullPaymentIncomingStatus,
|
||||||
TransactionStatus,
|
TransactionStatus,
|
||||||
|
WithdrawalGroupStatus,
|
||||||
} from "../db.js";
|
} from "../db.js";
|
||||||
import { InternalWalletState } from "../internal-wallet-state.js";
|
import { InternalWalletState } from "../internal-wallet-state.js";
|
||||||
import { assertUnreachable } from "../util/assertUnreachable.js";
|
import { assertUnreachable } from "../util/assertUnreachable.js";
|
||||||
@ -515,6 +516,9 @@ function buildTransactionForBankIntegratedWithdraw(
|
|||||||
confirmed: wsr.wgInfo.bankInfo.timestampBankConfirmed ? true : false,
|
confirmed: wsr.wgInfo.bankInfo.timestampBankConfirmed ? true : false,
|
||||||
reservePub: wsr.reservePub,
|
reservePub: wsr.reservePub,
|
||||||
bankConfirmationUrl: wsr.wgInfo.bankInfo.confirmUrl,
|
bankConfirmationUrl: wsr.wgInfo.bankInfo.confirmUrl,
|
||||||
|
reserveIsReady:
|
||||||
|
wsr.status === WithdrawalGroupStatus.Finished ||
|
||||||
|
wsr.status === WithdrawalGroupStatus.Ready,
|
||||||
},
|
},
|
||||||
exchangeBaseUrl: wsr.exchangeBaseUrl,
|
exchangeBaseUrl: wsr.exchangeBaseUrl,
|
||||||
extendedStatus: wsr.timestampFinish
|
extendedStatus: wsr.timestampFinish
|
||||||
@ -558,6 +562,9 @@ function buildTransactionForManualWithdraw(
|
|||||||
type: WithdrawalType.ManualTransfer,
|
type: WithdrawalType.ManualTransfer,
|
||||||
reservePub: withdrawalGroup.reservePub,
|
reservePub: withdrawalGroup.reservePub,
|
||||||
exchangePaytoUris,
|
exchangePaytoUris,
|
||||||
|
reserveIsReady:
|
||||||
|
withdrawalGroup.status === WithdrawalGroupStatus.Finished ||
|
||||||
|
withdrawalGroup.status === WithdrawalGroupStatus.Ready,
|
||||||
},
|
},
|
||||||
exchangeBaseUrl: withdrawalGroup.exchangeBaseUrl,
|
exchangeBaseUrl: withdrawalGroup.exchangeBaseUrl,
|
||||||
extendedStatus: withdrawalGroup.timestampFinish
|
extendedStatus: withdrawalGroup.timestampFinish
|
||||||
|
@ -987,6 +987,14 @@ async function queryReserve(
|
|||||||
await tx.withdrawalGroups.put(wg);
|
await tx.withdrawalGroups.put(wg);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ws.notify({
|
||||||
|
type: NotificationType.WithdrawalGroupReserveReady,
|
||||||
|
transactionId: makeTransactionId(
|
||||||
|
TransactionType.Withdrawal,
|
||||||
|
withdrawalGroupId,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
return { ready: true };
|
return { ready: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1250,7 +1258,12 @@ export async function processWithdrawalGroup(
|
|||||||
|
|
||||||
if (numKycRequired > 0) {
|
if (numKycRequired > 0) {
|
||||||
if (kycInfo) {
|
if (kycInfo) {
|
||||||
await checkWithdrawalKycStatus(ws, withdrawalGroup, kycInfo, "individual");
|
await checkWithdrawalKycStatus(
|
||||||
|
ws,
|
||||||
|
withdrawalGroup,
|
||||||
|
kycInfo,
|
||||||
|
"individual",
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
type: OperationAttemptResultType.Pending,
|
type: OperationAttemptResultType.Pending,
|
||||||
result: undefined,
|
result: undefined,
|
||||||
@ -1310,7 +1323,7 @@ export async function checkWithdrawalKycStatus(
|
|||||||
const kycStatus = await kycStatusReq.json();
|
const kycStatus = await kycStatusReq.json();
|
||||||
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
||||||
ws.notify({
|
ws.notify({
|
||||||
type: NotificationType.WithdrawalKycRequested,
|
type: NotificationType.WithdrawalGroupKycRequested,
|
||||||
kycUrl: kycStatus.kyc_url,
|
kycUrl: kycStatus.kyc_url,
|
||||||
transactionId: makeTransactionId(
|
transactionId: makeTransactionId(
|
||||||
TransactionType.Withdrawal,
|
TransactionType.Withdrawal,
|
||||||
@ -1794,6 +1807,13 @@ async function processReserveBankStatus(
|
|||||||
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.QueryingStatus;
|
||||||
|
ws.notify({
|
||||||
|
type: NotificationType.WithdrawalGroupBankConfirmed,
|
||||||
|
transactionId: makeTransactionId(
|
||||||
|
TransactionType.Withdrawal,
|
||||||
|
r.withdrawalGroupId,
|
||||||
|
),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
logger.info("withdrawal: transfer not yet confirmed by bank");
|
logger.info("withdrawal: transfer not yet confirmed by bank");
|
||||||
r.wgInfo.bankInfo.confirmUrl = status.confirm_transfer_url;
|
r.wgInfo.bankInfo.confirmUrl = status.confirm_transfer_url;
|
||||||
|
Loading…
Reference in New Issue
Block a user