diff options
Diffstat (limited to 'packages/taler-wallet-core/src/pay-peer-push-credit.ts')
-rw-r--r-- | packages/taler-wallet-core/src/pay-peer-push-credit.ts | 120 |
1 files changed, 57 insertions, 63 deletions
diff --git a/packages/taler-wallet-core/src/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/pay-peer-push-credit.ts index e629bffe4..772007bb6 100644 --- a/packages/taler-wallet-core/src/pay-peer-push-credit.ts +++ b/packages/taler-wallet-core/src/pay-peer-push-credit.ts @@ -83,7 +83,7 @@ import { notifyTransition, parseTransactionIdentifier, } from "./transactions.js"; -import { InternalWalletState } from "./wallet.js"; +import { InternalWalletState, WalletExecutionContext } from "./wallet.js"; import { PerformCreateWithdrawalGroupResult, getExchangeWithdrawalInfo, @@ -98,7 +98,7 @@ export class PeerPushCreditTransactionContext implements TransactionContext { readonly taskId: TaskIdStr; constructor( - public ws: InternalWalletState, + public wex: WalletExecutionContext, public peerPushCreditId: string, ) { this.transactionId = constructTransactionIdentifier({ @@ -112,8 +112,8 @@ export class PeerPushCreditTransactionContext implements TransactionContext { } async deleteTransaction(): Promise<void> { - const { ws, peerPushCreditId } = this; - await ws.db.runReadWriteTx( + const { wex, peerPushCreditId } = this; + await wex.db.runReadWriteTx( ["withdrawalGroups", "peerPushCredit", "tombstones"], async (tx) => { const pushInc = await tx.peerPushCredit.get(peerPushCreditId); @@ -141,8 +141,8 @@ export class PeerPushCreditTransactionContext implements TransactionContext { } async suspendTransaction(): Promise<void> { - const { ws, peerPushCreditId, taskId: retryTag, transactionId } = this; - const transitionInfo = await ws.db.runReadWriteTx( + const { wex, peerPushCreditId, taskId: retryTag, transactionId } = this; + const transitionInfo = await wex.db.runReadWriteTx( ["peerPushCredit"], async (tx) => { const pushCreditRec = await tx.peerPushCredit.get(peerPushCreditId); @@ -190,13 +190,13 @@ export class PeerPushCreditTransactionContext implements TransactionContext { return undefined; }, ); - notifyTransition(ws, transactionId, transitionInfo); - ws.taskScheduler.stopShepherdTask(retryTag); + notifyTransition(wex, transactionId, transitionInfo); + wex.taskScheduler.stopShepherdTask(retryTag); } async abortTransaction(): Promise<void> { - const { ws, peerPushCreditId, taskId: retryTag, transactionId } = this; - const transitionInfo = await ws.db.runReadWriteTx( + const { wex, peerPushCreditId, taskId: retryTag, transactionId } = this; + const transitionInfo = await wex.db.runReadWriteTx( ["peerPushCredit"], async (tx) => { const pushCreditRec = await tx.peerPushCredit.get(peerPushCreditId); @@ -247,12 +247,12 @@ export class PeerPushCreditTransactionContext implements TransactionContext { return undefined; }, ); - notifyTransition(ws, transactionId, transitionInfo); - ws.taskScheduler.startShepherdTask(retryTag); + notifyTransition(wex, transactionId, transitionInfo); + wex.taskScheduler.startShepherdTask(retryTag); } async resumeTransaction(): Promise<void> { - const { ws, peerPushCreditId, taskId: retryTag, transactionId } = this; + const { wex: ws, peerPushCreditId, taskId: retryTag, transactionId } = this; const transitionInfo = await ws.db.runReadWriteTx( ["peerPushCredit"], async (tx) => { @@ -305,7 +305,7 @@ export class PeerPushCreditTransactionContext implements TransactionContext { } async failTransaction(): Promise<void> { - const { ws, peerPushCreditId, taskId: retryTag, transactionId } = this; + const { wex: ws, peerPushCreditId, taskId: retryTag, transactionId } = this; const transitionInfo = await ws.db.runReadWriteTx( ["peerPushCredit"], async (tx) => { @@ -355,7 +355,7 @@ export class PeerPushCreditTransactionContext implements TransactionContext { } export async function preparePeerPushCredit( - ws: InternalWalletState, + wex: WalletExecutionContext, req: PreparePeerPushCreditRequest, ): Promise<PreparePeerPushCreditResponse> { const uri = parsePayPushUri(req.talerUri); @@ -364,7 +364,7 @@ export async function preparePeerPushCredit( throw Error("got invalid taler://pay-push URI"); } - const existing = await ws.db.runReadOnlyTx( + const existing = await wex.db.runReadOnlyTx( ["contractTerms", "peerPushCredit"], async (tx) => { const existingPushInc = @@ -407,14 +407,14 @@ export async function preparePeerPushCredit( const exchangeBaseUrl = uri.exchangeBaseUrl; - await fetchFreshExchange(ws, exchangeBaseUrl); + await fetchFreshExchange(wex, exchangeBaseUrl); const contractPriv = uri.contractPriv; const contractPub = encodeCrock(eddsaGetPublic(decodeCrock(contractPriv))); const getContractUrl = new URL(`contracts/${contractPub}`, exchangeBaseUrl); - const contractHttpResp = await ws.http.fetch(getContractUrl.href); + const contractHttpResp = await wex.http.fetch(getContractUrl.href); const contractResp = await readSuccessResponseJsonOrThrow( contractHttpResp, @@ -423,7 +423,7 @@ export async function preparePeerPushCredit( const pursePub = contractResp.purse_pub; - const dec = await ws.cryptoApi.decryptContractForMerge({ + const dec = await wex.cryptoApi.decryptContractForMerge({ ciphertext: contractResp.econtract, contractPriv: contractPriv, pursePub: pursePub, @@ -431,7 +431,7 @@ export async function preparePeerPushCredit( const getPurseUrl = new URL(`purses/${pursePub}/deposit`, exchangeBaseUrl); - const purseHttpResp = await ws.http.fetch(getPurseUrl.href); + const purseHttpResp = await wex.http.fetch(getPurseUrl.href); const contractTerms = codecForPeerContractTerms().decode(dec.contractTerms); @@ -453,13 +453,13 @@ export async function preparePeerPushCredit( const withdrawalGroupId = encodeCrock(getRandomBytes(32)); const wi = await getExchangeWithdrawalInfo( - ws, + wex, exchangeBaseUrl, Amounts.parseOrThrow(purseStatus.balance), undefined, ); - const transitionInfo = await ws.db.runReadWriteTx( + const transitionInfo = await wex.db.runReadWriteTx( ["contractTerms", "peerPushCredit"], async (tx) => { const rec: PeerPushPaymentIncomingRecord = { @@ -499,9 +499,9 @@ export async function preparePeerPushCredit( peerPushCreditId, }); - notifyTransition(ws, transactionId, transitionInfo); + notifyTransition(wex, transactionId, transitionInfo); - ws.notify({ + wex.ws.notify({ type: NotificationType.BalanceChange, hintTransactionId: transactionId, }); @@ -518,12 +518,11 @@ export async function preparePeerPushCredit( } async function longpollKycStatus( - ws: InternalWalletState, + wex: WalletExecutionContext, peerPushCreditId: string, exchangeUrl: string, kycInfo: KycPendingInfo, userType: KycUserType, - cancellationToken: CancellationToken, ): Promise<TaskRunResult> { const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, @@ -535,9 +534,9 @@ async function longpollKycStatus( ); url.searchParams.set("timeout_ms", "30000"); logger.info(`kyc url ${url.href}`); - const kycStatusRes = await ws.http.fetch(url.href, { + const kycStatusRes = await wex.http.fetch(url.href, { method: "GET", - cancellationToken, + cancellationToken: wex.cancellationToken, }); if ( kycStatusRes.status === HttpStatusCode.Ok || @@ -545,7 +544,7 @@ async function longpollKycStatus( // remove after the exchange is fixed or clarified kycStatusRes.status === HttpStatusCode.NoContent ) { - const transitionInfo = await ws.db.runReadWriteTx( + const transitionInfo = await wex.db.runReadWriteTx( ["peerPushCredit"], async (tx) => { const peerInc = await tx.peerPushCredit.get(peerPushCreditId); @@ -562,7 +561,7 @@ async function longpollKycStatus( return { oldTxState, newTxState }; }, ); - notifyTransition(ws, transactionId, transitionInfo); + notifyTransition(wex, transactionId, transitionInfo); return TaskRunResult.progress(); } else if (kycStatusRes.status === HttpStatusCode.Accepted) { // FIXME: Do we have to update the URL here? @@ -573,10 +572,9 @@ async function longpollKycStatus( } async function processPeerPushCreditKycRequired( - ws: InternalWalletState, + wex: WalletExecutionContext, peerInc: PeerPushPaymentIncomingRecord, kycPending: WalletKycUuid, - cancellationToken: CancellationToken, ): Promise<TaskRunResult> { const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, @@ -591,9 +589,9 @@ async function processPeerPushCreditKycRequired( ); logger.info(`kyc url ${url.href}`); - const kycStatusRes = await ws.http.fetch(url.href, { + const kycStatusRes = await wex.http.fetch(url.href, { method: "GET", - cancellationToken, + cancellationToken: wex.cancellationToken, }); if ( @@ -607,7 +605,7 @@ async function processPeerPushCreditKycRequired( } else if (kycStatusRes.status === HttpStatusCode.Accepted) { const kycStatus = await kycStatusRes.json(); logger.info(`kyc status: ${j2s(kycStatus)}`); - const { transitionInfo, result } = await ws.db.runReadWriteTx( + const { transitionInfo, result } = await wex.db.runReadWriteTx( ["peerPushCredit"], async (tx) => { const peerInc = await tx.peerPushCredit.get(peerPushCreditId); @@ -643,7 +641,7 @@ async function processPeerPushCreditKycRequired( }; }, ); - notifyTransition(ws, transactionId, transitionInfo); + notifyTransition(wex, transactionId, transitionInfo); return result; } else { throw Error(`unexpected response from kyc-check (${kycStatusRes.status})`); @@ -651,10 +649,9 @@ async function processPeerPushCreditKycRequired( } async function handlePendingMerge( - ws: InternalWalletState, + wex: WalletExecutionContext, peerInc: PeerPushPaymentIncomingRecord, contractTerms: PeerContractTerms, - cancellationToken: CancellationToken, ): Promise<TaskRunResult> { const { peerPushCreditId } = peerInc; const transactionId = constructTransactionIdentifier({ @@ -664,7 +661,7 @@ async function handlePendingMerge( const amount = Amounts.parseOrThrow(contractTerms.amount); - const mergeReserveInfo = await getMergeReserveInfo(ws, { + const mergeReserveInfo = await getMergeReserveInfo(wex, { exchangeBaseUrl: peerInc.exchangeBaseUrl, }); @@ -675,7 +672,7 @@ async function handlePendingMerge( mergeReserveInfo.reservePub, ); - const sigRes = await ws.cryptoApi.signPurseMerge({ + const sigRes = await wex.cryptoApi.signPurseMerge({ contractTermsHash: ContractTermsUtil.hashContractTerms(contractTerms), flags: WalletAccountMergeFlags.MergeFullyPaidPurse, mergePriv: peerInc.mergePriv, @@ -700,7 +697,7 @@ async function handlePendingMerge( reserve_sig: sigRes.accountSig, }; - const mergeHttpResp = await ws.http.fetch(mergePurseUrl.href, { + const mergeHttpResp = await wex.http.fetch(mergePurseUrl.href, { method: "POST", body: mergeReq, }); @@ -710,10 +707,9 @@ async function handlePendingMerge( const kycPending = codecForWalletKycUuid().decode(respJson); logger.info(`kyc uuid response: ${j2s(kycPending)}`); return processPeerPushCreditKycRequired( - ws, + wex, peerInc, kycPending, - cancellationToken, ); } @@ -724,7 +720,7 @@ async function handlePendingMerge( ); logger.trace(`merge response: ${j2s(res)}`); - const withdrawalGroupPrep = await internalPrepareCreateWithdrawalGroup(ws, { + const withdrawalGroupPrep = await internalPrepareCreateWithdrawalGroup(wex, { amount, wgInfo: { withdrawalType: WithdrawalRecordType.PeerPushCredit, @@ -738,7 +734,7 @@ async function handlePendingMerge( }, }); - const txRes = await ws.db.runReadWriteTx( + const txRes = await wex.db.runReadWriteTx( [ "contractTerms", "peerPushCredit", @@ -760,7 +756,7 @@ async function handlePendingMerge( case PeerPushCreditStatus.PendingMergeKycRequired: { peerInc.status = PeerPushCreditStatus.PendingWithdrawing; wgCreateRes = await internalPerformCreateWithdrawalGroup( - ws, + wex, tx, withdrawalGroupPrep, ); @@ -779,20 +775,20 @@ async function handlePendingMerge( ); // Transaction was committed, now we can emit notifications. if (txRes?.wgCreateRes?.exchangeNotif) { - ws.notify(txRes.wgCreateRes.exchangeNotif); + wex.ws.notify(txRes.wgCreateRes.exchangeNotif); } notifyTransition( - ws, + wex, withdrawalGroupPrep.transactionId, txRes?.wgCreateRes?.transitionInfo, ); - notifyTransition(ws, transactionId, txRes?.peerPushCreditTransition); + notifyTransition(wex, transactionId, txRes?.peerPushCreditTransition); return TaskRunResult.backoff(); } async function handlePendingWithdrawing( - ws: InternalWalletState, + wex: WalletExecutionContext, peerInc: PeerPushPaymentIncomingRecord, ): Promise<TaskRunResult> { if (!peerInc.withdrawalGroupId) { @@ -804,7 +800,7 @@ async function handlePendingWithdrawing( }); const wgId = peerInc.withdrawalGroupId; let finished: boolean = false; - const transitionInfo = await ws.db.runReadWriteTx( + const transitionInfo = await wex.db.runReadWriteTx( ["peerPushCredit", "withdrawalGroups"], async (tx) => { const ppi = await tx.peerPushCredit.get(peerInc.peerPushCreditId); @@ -837,7 +833,7 @@ async function handlePendingWithdrawing( }; }, ); - notifyTransition(ws, transactionId, transitionInfo); + notifyTransition(wex, transactionId, transitionInfo); if (finished) { return TaskRunResult.finished(); } else { @@ -847,13 +843,12 @@ async function handlePendingWithdrawing( } export async function processPeerPushCredit( - ws: InternalWalletState, + wex: WalletExecutionContext, peerPushCreditId: string, - cancellationToken: CancellationToken, ): Promise<TaskRunResult> { let peerInc: PeerPushPaymentIncomingRecord | undefined; let contractTerms: PeerContractTerms | undefined; - await ws.db.runReadWriteTx( + await wex.db.runReadWriteTx( ["contractTerms", "peerPushCredit"], async (tx) => { peerInc = await tx.peerPushCredit.get(peerPushCreditId); @@ -886,20 +881,19 @@ export async function processPeerPushCredit( throw Error("invalid state, kycInfo required"); } return await longpollKycStatus( - ws, + wex, peerPushCreditId, peerInc.exchangeBaseUrl, peerInc.kycInfo, "individual", - cancellationToken, ); } case PeerPushCreditStatus.PendingMerge: - return handlePendingMerge(ws, peerInc, contractTerms, cancellationToken); + return handlePendingMerge(wex, peerInc, contractTerms); case PeerPushCreditStatus.PendingWithdrawing: - return handlePendingWithdrawing(ws, peerInc); + return handlePendingWithdrawing(wex, peerInc); default: return TaskRunResult.finished(); @@ -907,7 +901,7 @@ export async function processPeerPushCredit( } export async function confirmPeerPushCredit( - ws: InternalWalletState, + wex: WalletExecutionContext, req: ConfirmPeerPushCreditRequest, ): Promise<AcceptPeerPushPaymentResponse> { let peerInc: PeerPushPaymentIncomingRecord | undefined; @@ -927,7 +921,7 @@ export async function confirmPeerPushCredit( throw Error("no transaction ID (or deprecated peerPushCreditId) provided"); } - await ws.db.runReadWriteTx( + await wex.db.runReadWriteTx( ["contractTerms", "peerPushCredit"], async (tx) => { peerInc = await tx.peerPushCredit.get(peerPushCreditId); @@ -947,9 +941,9 @@ export async function confirmPeerPushCredit( ); } - const ctx = new PeerPushCreditTransactionContext(ws, peerPushCreditId); + const ctx = new PeerPushCreditTransactionContext(wex, peerPushCreditId); - ws.taskScheduler.startShepherdTask(ctx.taskId); + wex.taskScheduler.startShepherdTask(ctx.taskId); const transactionId = constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, |