wallet-core: pending operation for peer push credit, save withdrawalGroupId

This commit is contained in:
Florian Dold 2023-02-20 00:36:02 +01:00
parent e6ed901626
commit 30b3949d2b
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
7 changed files with 232 additions and 31 deletions

View File

@ -1818,6 +1818,18 @@ export interface PeerPullPaymentInitiationRecord {
* Status of the peer pull payment initiation. * Status of the peer pull payment initiation.
*/ */
status: OperationStatus; status: OperationStatus;
withdrawalGroupId: string | undefined;
}
export enum PeerPushPaymentIncomingStatus {
Proposed = 30 /* USER_ATTENTION_START */,
Accepted = 10 /* ACTIVE_START */,
/**
* Merge was successful and withdrawal group has been created, now
* everything is in the hand of the withdrawal group.
*/
WithdrawalCreated = 50 /* DORMANT_START */,
} }
/** /**
@ -1847,7 +1859,12 @@ export interface PeerPushPaymentIncomingRecord {
/** /**
* Status of the peer push payment incoming initiation. * Status of the peer push payment incoming initiation.
*/ */
status: OperationStatus; status: PeerPushPaymentIncomingStatus;
/**
* Associated withdrawal group.
*/
withdrawalGroupId: string | undefined;
} }
export enum PeerPullPaymentIncomingStatus { export enum PeerPullPaymentIncomingStatus {
@ -2260,6 +2277,21 @@ export const WalletStoresV1 = {
"exchangeBaseUrl", "exchangeBaseUrl",
"pursePub", "pursePub",
]), ]),
byExchangeAndContractPriv: describeIndex(
"byExchangeAndContractPriv",
["exchangeBaseUrl", "contractPriv"],
{
versionAdded: 4,
unique: true,
},
),
byWithdrawalGroupId: describeIndex(
"byWithdrawalGroupId",
"withdrawalGroupId",
{
versionAdded: 4,
},
),
byStatus: describeIndex("byStatus", "status"), byStatus: describeIndex("byStatus", "status"),
}, },
), ),
@ -2291,6 +2323,13 @@ export const WalletStoresV1 = {
}), }),
{ {
byStatus: describeIndex("byStatus", "status"), byStatus: describeIndex("byStatus", "status"),
byWithdrawalGroupId: describeIndex(
"byWithdrawalGroupId",
"withdrawalGroupId",
{
versionAdded: 4,
},
),
}, },
), ),
peerPushPaymentInitiations: describeStore( peerPushPaymentInitiations: describeStore(

View File

@ -77,6 +77,7 @@ import {
PeerPullPaymentIncomingStatus, PeerPullPaymentIncomingStatus,
PeerPushPaymentCoinSelection, PeerPushPaymentCoinSelection,
PeerPushPaymentIncomingRecord, PeerPushPaymentIncomingRecord,
PeerPushPaymentIncomingStatus,
PeerPushPaymentInitiationStatus, PeerPushPaymentInitiationStatus,
ReserveRecord, ReserveRecord,
WithdrawalGroupStatus, WithdrawalGroupStatus,
@ -619,18 +620,50 @@ export const codecForExchangePurseStatus = (): Codec<ExchangePurseStatus> =>
.property("balance", codecForAmountString()) .property("balance", codecForAmountString())
.build("ExchangePurseStatus"); .build("ExchangePurseStatus");
export async function checkPeerPushPayment( export async function preparePeerPushCredit(
ws: InternalWalletState, ws: InternalWalletState,
req: CheckPeerPushPaymentRequest, req: CheckPeerPushPaymentRequest,
): Promise<CheckPeerPushPaymentResponse> { ): Promise<CheckPeerPushPaymentResponse> {
// FIXME: Check if existing record exists!
const uri = parsePayPushUri(req.talerUri); const uri = parsePayPushUri(req.talerUri);
if (!uri) { if (!uri) {
throw Error("got invalid taler://pay-push URI"); throw Error("got invalid taler://pay-push URI");
} }
const existing = await ws.db
.mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming])
.runReadOnly(async (tx) => {
const existingPushInc =
await tx.peerPushPaymentIncoming.indexes.byExchangeAndContractPriv.get([
uri.exchangeBaseUrl,
uri.contractPriv,
]);
if (!existingPushInc) {
return;
}
const existingContractTermsRec = await tx.contractTerms.get(
existingPushInc.contractTermsHash,
);
if (!existingContractTermsRec) {
throw Error(
"contract terms for peer push payment credit not found in database",
);
}
const existingContractTerms = codecForPeerContractTerms().decode(
existingContractTermsRec.contractTermsRaw,
);
return { existingPushInc, existingContractTerms };
});
if (existing) {
return {
amount: existing.existingContractTerms.amount,
contractTerms: existing.existingContractTerms,
peerPushPaymentIncomingId:
existing.existingPushInc.peerPushPaymentIncomingId,
};
}
const exchangeBaseUrl = uri.exchangeBaseUrl; const exchangeBaseUrl = uri.exchangeBaseUrl;
await updateExchangeFromUrl(ws, exchangeBaseUrl); await updateExchangeFromUrl(ws, exchangeBaseUrl);
@ -670,6 +703,8 @@ export async function checkPeerPushPayment(
dec.contractTerms, dec.contractTerms,
); );
const withdrawalGroupId = encodeCrock(getRandomBytes(32));
await ws.db await ws.db
.mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming]) .mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming])
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
@ -681,7 +716,8 @@ export async function checkPeerPushPayment(
pursePub: pursePub, pursePub: pursePub,
timestamp: TalerProtocolTimestamp.now(), timestamp: TalerProtocolTimestamp.now(),
contractTermsHash, contractTermsHash,
status: OperationStatus.Finished, status: PeerPushPaymentIncomingStatus.Proposed,
withdrawalGroupId,
}); });
await tx.contractTerms.put({ await tx.contractTerms.put({
@ -754,18 +790,16 @@ async function getMergeReserveInfo(
return mergeReserveRecord; return mergeReserveRecord;
} }
export async function acceptPeerPushPayment( export async function processPeerPushCredit(
ws: InternalWalletState, ws: InternalWalletState,
req: AcceptPeerPushPaymentRequest, peerPushPaymentIncomingId: string,
): Promise<AcceptPeerPushPaymentResponse> { ): Promise<OperationAttemptResult> {
let peerInc: PeerPushPaymentIncomingRecord | undefined; let peerInc: PeerPushPaymentIncomingRecord | undefined;
let contractTerms: PeerContractTerms | undefined; let contractTerms: PeerContractTerms | undefined;
await ws.db await ws.db
.mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming]) .mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming])
.runReadOnly(async (tx) => { .runReadWrite(async (tx) => {
peerInc = await tx.peerPushPaymentIncoming.get( peerInc = await tx.peerPushPaymentIncoming.get(peerPushPaymentIncomingId);
req.peerPushPaymentIncomingId,
);
if (!peerInc) { if (!peerInc) {
return; return;
} }
@ -773,18 +807,17 @@ export async function acceptPeerPushPayment(
if (ctRec) { if (ctRec) {
contractTerms = ctRec.contractTermsRaw; contractTerms = ctRec.contractTermsRaw;
} }
await tx.peerPushPaymentIncoming.put(peerInc);
}); });
if (!peerInc) { if (!peerInc) {
throw Error( throw Error(
`can't accept unknown incoming p2p push payment (${req.peerPushPaymentIncomingId})`, `can't accept unknown incoming p2p push payment (${peerPushPaymentIncomingId})`,
); );
} }
checkDbInvariant(!!contractTerms); checkDbInvariant(!!contractTerms);
await updateExchangeFromUrl(ws, peerInc.exchangeBaseUrl);
const amount = Amounts.parseOrThrow(contractTerms.amount); const amount = Amounts.parseOrThrow(contractTerms.amount);
const mergeReserveInfo = await getMergeReserveInfo(ws, { const mergeReserveInfo = await getMergeReserveInfo(ws, {
@ -825,16 +858,17 @@ export async function acceptPeerPushPayment(
const mergeHttpReq = await ws.http.postJson(mergePurseUrl.href, mergeReq); const mergeHttpReq = await ws.http.postJson(mergePurseUrl.href, mergeReq);
logger.info(`merge request: ${j2s(mergeReq)}`); logger.trace(`merge request: ${j2s(mergeReq)}`);
const res = await readSuccessResponseJsonOrThrow(mergeHttpReq, codecForAny()); const res = await readSuccessResponseJsonOrThrow(mergeHttpReq, codecForAny());
logger.info(`merge response: ${j2s(res)}`); logger.trace(`merge response: ${j2s(res)}`);
const wg = await internalCreateWithdrawalGroup(ws, { await internalCreateWithdrawalGroup(ws, {
amount, amount,
wgInfo: { wgInfo: {
withdrawalType: WithdrawalRecordType.PeerPushCredit, withdrawalType: WithdrawalRecordType.PeerPushCredit,
contractTerms, contractTerms,
}, },
forcedWithdrawalGroupId: peerInc.withdrawalGroupId,
exchangeBaseUrl: peerInc.exchangeBaseUrl, exchangeBaseUrl: peerInc.exchangeBaseUrl,
reserveStatus: WithdrawalGroupStatus.QueryingStatus, reserveStatus: WithdrawalGroupStatus.QueryingStatus,
reserveKeyPair: { reserveKeyPair: {
@ -843,10 +877,72 @@ export async function acceptPeerPushPayment(
}, },
}); });
await ws.db
.mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming])
.runReadWrite(async (tx) => {
const peerInc = await tx.peerPushPaymentIncoming.get(
peerPushPaymentIncomingId,
);
if (!peerInc) {
return;
}
if (peerInc.status === PeerPushPaymentIncomingStatus.Accepted) {
peerInc.status = PeerPushPaymentIncomingStatus.WithdrawalCreated;
}
await tx.peerPushPaymentIncoming.put(peerInc);
});
return {
type: OperationAttemptResultType.Finished,
result: undefined,
};
}
export async function acceptPeerPushPayment(
ws: InternalWalletState,
req: AcceptPeerPushPaymentRequest,
): Promise<AcceptPeerPushPaymentResponse> {
let peerInc: PeerPushPaymentIncomingRecord | undefined;
let contractTerms: PeerContractTerms | undefined;
await ws.db
.mktx((x) => [x.contractTerms, x.peerPushPaymentIncoming])
.runReadWrite(async (tx) => {
peerInc = await tx.peerPushPaymentIncoming.get(
req.peerPushPaymentIncomingId,
);
if (!peerInc) {
return;
}
const ctRec = await tx.contractTerms.get(peerInc.contractTermsHash);
if (ctRec) {
contractTerms = ctRec.contractTermsRaw;
}
if (peerInc.status === PeerPushPaymentIncomingStatus.Proposed) {
peerInc.status = PeerPushPaymentIncomingStatus.Accepted;
}
await tx.peerPushPaymentIncoming.put(peerInc);
});
if (!peerInc) {
throw Error(
`can't accept unknown incoming p2p push payment (${req.peerPushPaymentIncomingId})`,
);
}
checkDbInvariant(!!contractTerms);
await updateExchangeFromUrl(ws, peerInc.exchangeBaseUrl);
const retryTag = RetryTags.forPeerPushCredit(peerInc);
await runOperationWithErrorReporting(ws, retryTag, () =>
processPeerPushCredit(ws, req.peerPushPaymentIncomingId),
);
return { return {
transactionId: makeTransactionId( transactionId: makeTransactionId(
TransactionType.PeerPushCredit, TransactionType.PeerPushCredit,
wg.withdrawalGroupId, req.peerPushPaymentIncomingId,
), ),
}; };
} }
@ -1017,7 +1113,7 @@ export async function acceptIncomingPeerPullPayment(
* Look up information about an incoming peer pull payment. * Look up information about an incoming peer pull payment.
* Store the results in the wallet DB. * Store the results in the wallet DB.
*/ */
export async function prepareIncomingPeerPullPayment( export async function preparePeerPullCredit(
ws: InternalWalletState, ws: InternalWalletState,
req: CheckPeerPullPaymentRequest, req: CheckPeerPullPaymentRequest,
): Promise<CheckPeerPullPaymentResponse> { ): Promise<CheckPeerPullPaymentResponse> {
@ -1135,7 +1231,7 @@ export async function prepareIncomingPeerPullPayment(
}; };
} }
export async function processPeerPullInitiation( export async function processPeerPullCredit(
ws: InternalWalletState, ws: InternalWalletState,
pursePub: string, pursePub: string,
): Promise<OperationAttemptResult> { ): Promise<OperationAttemptResult> {
@ -1359,6 +1455,8 @@ export async function initiatePeerPullPayment(
const contractKeyPair = await ws.cryptoApi.createEddsaKeypair({}); const contractKeyPair = await ws.cryptoApi.createEddsaKeypair({});
const withdrawalGroupId = encodeCrock(getRandomBytes(32));
const mergeReserveRowId = mergeReserveInfo.rowId; const mergeReserveRowId = mergeReserveInfo.rowId;
checkDbInvariant(!!mergeReserveRowId); checkDbInvariant(!!mergeReserveRowId);
@ -1379,6 +1477,7 @@ export async function initiatePeerPullPayment(
mergeReserveRowId: mergeReserveRowId, mergeReserveRowId: mergeReserveRowId,
contractPriv: contractKeyPair.priv, contractPriv: contractKeyPair.priv,
contractPub: contractKeyPair.pub, contractPub: contractKeyPair.pub,
withdrawalGroupId,
}); });
await tx.contractTerms.put({ await tx.contractTerms.put({
contractTermsRaw: contractTerms, contractTermsRaw: contractTerms,
@ -1394,20 +1493,24 @@ export async function initiatePeerPullPayment(
ws, ws,
RetryTags.byPeerPullPaymentInitiationPursePub(pursePair.pub), RetryTags.byPeerPullPaymentInitiationPursePub(pursePair.pub),
async () => { async () => {
return processPeerPullInitiation(ws, pursePair.pub); return processPeerPullCredit(ws, pursePair.pub);
}, },
); );
// FIXME: Why do we create this only here? // FIXME: Why do we create this only here?
// What if the previous operation didn't succeed? // What if the previous operation didn't succeed?
const wg = await internalCreateWithdrawalGroup(ws, { // FIXME: Use a pre-computed withdrawal group ID
// so we don't create it multiple times.
await internalCreateWithdrawalGroup(ws, {
amount: instructedAmount, amount: instructedAmount,
wgInfo: { wgInfo: {
withdrawalType: WithdrawalRecordType.PeerPullCredit, withdrawalType: WithdrawalRecordType.PeerPullCredit,
contractTerms, contractTerms,
contractPriv: contractKeyPair.priv, contractPriv: contractKeyPair.priv,
}, },
forcedWithdrawalGroupId: withdrawalGroupId,
exchangeBaseUrl: exchangeBaseUrl, exchangeBaseUrl: exchangeBaseUrl,
reserveStatus: WithdrawalGroupStatus.QueryingStatus, reserveStatus: WithdrawalGroupStatus.QueryingStatus,
reserveKeyPair: { reserveKeyPair: {
@ -1423,7 +1526,7 @@ export async function initiatePeerPullPayment(
}), }),
transactionId: makeTransactionId( transactionId: makeTransactionId(
TransactionType.PeerPullCredit, TransactionType.PeerPullCredit,
wg.withdrawalGroupId, pursePair.pub,
), ),
}; };
} }

View File

@ -30,6 +30,7 @@ import {
OperationStatusRange, OperationStatusRange,
PeerPushPaymentInitiationStatus, PeerPushPaymentInitiationStatus,
PeerPullPaymentIncomingStatus, PeerPullPaymentIncomingStatus,
PeerPushPaymentIncomingStatus,
} from "../db.js"; } from "../db.js";
import { import {
PendingOperationsResponse, PendingOperationsResponse,
@ -430,6 +431,35 @@ async function gatherPeerPushInitiationPending(
}); });
} }
async function gatherPeerPushCreditPending(
ws: InternalWalletState,
tx: GetReadOnlyAccess<{
peerPushPaymentIncoming: typeof WalletStoresV1.peerPushPaymentIncoming;
operationRetries: typeof WalletStoresV1.operationRetries;
}>,
now: AbsoluteTime,
resp: PendingOperationsResponse,
): Promise<void> {
await tx.peerPushPaymentIncoming.iter().forEachAsync(async (pi) => {
switch (pi.status) {
case PeerPushPaymentIncomingStatus.Accepted:
return;
case PeerPushPaymentIncomingStatus.WithdrawalCreated:
return;
}
const opId = RetryTags.forPeerPushCredit(pi);
const retryRecord = await tx.operationRetries.get(opId);
const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now();
resp.pendingOperations.push({
type: PendingTaskType.PeerPushCredit,
...getPendingCommon(ws, opId, timestampDue),
givesLifeness: true,
retryInfo: retryRecord?.retryInfo,
peerPushPaymentIncomingId: pi.peerPushPaymentIncomingId,
});
});
}
export async function getPendingOperations( export async function getPendingOperations(
ws: InternalWalletState, ws: InternalWalletState,
): Promise<PendingOperationsResponse> { ): Promise<PendingOperationsResponse> {
@ -451,6 +481,7 @@ export async function getPendingOperations(
x.peerPullPaymentInitiations, x.peerPullPaymentInitiations,
x.peerPushPaymentInitiations, x.peerPushPaymentInitiations,
x.peerPullPaymentIncoming, x.peerPullPaymentIncoming,
x.peerPushPaymentIncoming,
]) ])
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const resp: PendingOperationsResponse = { const resp: PendingOperationsResponse = {
@ -467,6 +498,7 @@ export async function getPendingOperations(
await gatherPeerPushInitiationPending(ws, tx, now, resp); await gatherPeerPushInitiationPending(ws, tx, now, resp);
await gatherPeerPullInitiationPending(ws, tx, now, resp); await gatherPeerPullInitiationPending(ws, tx, now, resp);
await gatherPeerPullDebitPending(ws, tx, now, resp); await gatherPeerPullDebitPending(ws, tx, now, resp);
await gatherPeerPushCreditPending(ws, tx, now, resp);
return resp; return resp;
}); });
} }

View File

@ -1839,6 +1839,7 @@ export async function internalCreateWithdrawalGroup(
reserveStatus: WithdrawalGroupStatus; reserveStatus: WithdrawalGroupStatus;
amount: AmountJson; amount: AmountJson;
exchangeBaseUrl: string; exchangeBaseUrl: string;
forcedWithdrawalGroupId?: string;
forcedDenomSel?: ForcedDenomSel; forcedDenomSel?: ForcedDenomSel;
reserveKeyPair?: EddsaKeypair; reserveKeyPair?: EddsaKeypair;
restrictAge?: number; restrictAge?: number;
@ -1850,9 +1851,16 @@ export async function internalCreateWithdrawalGroup(
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
const secretSeed = encodeCrock(getRandomBytes(32)); const secretSeed = encodeCrock(getRandomBytes(32));
const canonExchange = canonicalizeBaseUrl(args.exchangeBaseUrl); const canonExchange = canonicalizeBaseUrl(args.exchangeBaseUrl);
const withdrawalGroupId = encodeCrock(getRandomBytes(32));
const amount = args.amount; const amount = args.amount;
let withdrawalGroupId;
if (args.forcedWithdrawalGroupId) {
withdrawalGroupId = args.forcedWithdrawalGroupId;
} else {
withdrawalGroupId = encodeCrock(getRandomBytes(32));
}
await updateWithdrawalDenoms(ws, canonExchange); await updateWithdrawalDenoms(ws, canonExchange);
const denoms = await getCandidateWithdrawalDenoms(ws, canonExchange); const denoms = await getCandidateWithdrawalDenoms(ws, canonExchange);

View File

@ -37,8 +37,10 @@ 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
PeerPushInitiation = "peer-push-initiation", PeerPushInitiation = "peer-push-initiation",
PeerPullInitiation = "peer-pull-initiation", PeerPullInitiation = "peer-pull-initiation",
PeerPushCredit = "peer-push-credit",
PeerPullDebit = "peer-pull-debit", PeerPullDebit = "peer-pull-debit",
} }
@ -59,6 +61,7 @@ export type PendingTaskInfo = PendingTaskInfoCommon &
| PendingPeerPushInitiationTask | PendingPeerPushInitiationTask
| PendingPeerPullInitiationTask | PendingPeerPullInitiationTask
| PendingPeerPullDebitTask | PendingPeerPullDebitTask
| PendingPeerPushCreditTask
); );
export interface PendingBackupTask { export interface PendingBackupTask {
@ -100,6 +103,13 @@ export interface PendingPeerPullDebitTask {
peerPullPaymentIncomingId: string; peerPullPaymentIncomingId: string;
} }
/**
*/
export interface PendingPeerPushCreditTask {
type: PendingTaskType.PeerPushCredit;
peerPushPaymentIncomingId: string;
}
/** /**
* The wallet should check whether coins from this exchange * The wallet should check whether coins from this exchange
* need to be auto-refreshed. * need to be auto-refreshed.

View File

@ -33,6 +33,7 @@ import {
ExchangeRecord, ExchangeRecord,
PeerPullPaymentIncomingRecord, PeerPullPaymentIncomingRecord,
PeerPullPaymentInitiationRecord, PeerPullPaymentInitiationRecord,
PeerPushPaymentIncomingRecord,
PeerPushPaymentInitiationRecord, PeerPushPaymentInitiationRecord,
PurchaseRecord, PurchaseRecord,
RecoupGroupRecord, RecoupGroupRecord,
@ -221,6 +222,11 @@ export namespace RetryTags {
): string { ): string {
return `${PendingTaskType.PeerPullDebit}:${ppi.pursePub}`; return `${PendingTaskType.PeerPullDebit}:${ppi.pursePub}`;
} }
export function forPeerPushCredit(
ppi: PeerPushPaymentIncomingRecord,
): string {
return `${PendingTaskType.PeerPushCredit}:${ppi.pursePub}`;
}
export function byPaymentProposalId(proposalId: string): string { export function byPaymentProposalId(proposalId: string): string {
return `${PendingTaskType.Purchase}:${proposalId}`; return `${PendingTaskType.Purchase}:${proposalId}`;
} }

View File

@ -197,15 +197,16 @@ import {
import { import {
acceptIncomingPeerPullPayment, acceptIncomingPeerPullPayment,
acceptPeerPushPayment, acceptPeerPushPayment,
prepareIncomingPeerPullPayment, preparePeerPullCredit,
checkPeerPushPayment, preparePeerPushCredit,
initiatePeerPullPayment, initiatePeerPullPayment,
initiatePeerPushPayment, initiatePeerPushPayment,
checkPeerPullPaymentInitiation, checkPeerPullPaymentInitiation,
preparePeerPushPayment, preparePeerPushPayment,
processPeerPullInitiation, processPeerPullCredit,
processPeerPushInitiation, processPeerPushInitiation,
processPeerPullDebit, processPeerPullDebit,
processPeerPushCredit,
} from "./operations/pay-peer.js"; } from "./operations/pay-peer.js";
import { getPendingOperations } from "./operations/pending.js"; import { getPendingOperations } from "./operations/pending.js";
import { import {
@ -328,9 +329,11 @@ async function callOperationHandler(
case PendingTaskType.PeerPushInitiation: case PendingTaskType.PeerPushInitiation:
return await processPeerPushInitiation(ws, pending.pursePub); return await processPeerPushInitiation(ws, pending.pursePub);
case PendingTaskType.PeerPullInitiation: case PendingTaskType.PeerPullInitiation:
return await processPeerPullInitiation(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);
case PendingTaskType.PeerPushCredit:
return await processPeerPushCredit(ws, pending.peerPushPaymentIncomingId);
default: default:
return assertUnreachable(pending); return assertUnreachable(pending);
} }
@ -1435,7 +1438,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
} }
case WalletApiOperation.CheckPeerPushPayment: { case WalletApiOperation.CheckPeerPushPayment: {
const req = codecForCheckPeerPushPaymentRequest().decode(payload); const req = codecForCheckPeerPushPaymentRequest().decode(payload);
return await checkPeerPushPayment(ws, req); return await preparePeerPushCredit(ws, req);
} }
case WalletApiOperation.AcceptPeerPushPayment: { case WalletApiOperation.AcceptPeerPushPayment: {
const req = codecForAcceptPeerPushPaymentRequest().decode(payload); const req = codecForAcceptPeerPushPaymentRequest().decode(payload);
@ -1451,7 +1454,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
} }
case WalletApiOperation.CheckPeerPullPayment: { case WalletApiOperation.CheckPeerPullPayment: {
const req = codecForCheckPeerPullPaymentRequest().decode(payload); const req = codecForCheckPeerPullPaymentRequest().decode(payload);
return await prepareIncomingPeerPullPayment(ws, req); return await preparePeerPullCredit(ws, req);
} }
case WalletApiOperation.AcceptPeerPullPayment: { case WalletApiOperation.AcceptPeerPullPayment: {
const req = codecForAcceptPeerPullPaymentRequest().decode(payload); const req = codecForAcceptPeerPullPaymentRequest().decode(payload);