commit 35ebcf2dcd7e70c9300f80515e2d083bac0fbee6
parent 0fb407fe19cfe1b4b1159d0541ce88b70a71687d
Author: Florian Dold <florian@dold.me>
Date: Wed, 28 May 2025 19:30:18 +0200
wallet-core: improve checkKycStatus, do not pass secret key to API Client
Diffstat:
9 files changed, 174 insertions(+), 112 deletions(-)
diff --git a/packages/kyc-ui/src/pages/TriggerKyc.tsx b/packages/kyc-ui/src/pages/TriggerKyc.tsx
@@ -13,9 +13,6 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { encodeCrock } from "@gnu-taler/taler-util";
-import { WalletKycRequest } from "@gnu-taler/taler-util";
-import { signWalletAccountSetup } from "@gnu-taler/taler-util";
import {
AbsoluteTime,
AccessToken,
@@ -23,7 +20,12 @@ import {
Amounts,
assertUnreachable,
createNewWalletKycAccount,
+ eddsaGetPublic,
+ encodeCrock,
HttpStatusCode,
+ signKycAuth,
+ signWalletAccountSetup,
+ WalletKycRequest,
} from "@gnu-taler/taler-util";
import {
Button,
@@ -93,7 +95,13 @@ export function TriggerKyc({ onKycStarted }: Props): VNode {
const paytoHash = kycAccount;
async function check() {
const { signingKey } = await accountPromise;
- const result = await lib.exchange.checkKycStatus(signingKey, paytoHash);
+ const merchantPub = eddsaGetPublic(signingKey);
+ const accountOwnerSig = encodeCrock(signKycAuth(signingKey));
+ const result = await lib.exchange.checkKycStatus({
+ accountPub: encodeCrock(merchantPub),
+ accountSig: accountOwnerSig,
+ paytoHash,
+ });
switch (result.case) {
case "ok":
console.log("empty body");
@@ -109,7 +117,6 @@ export function TriggerKyc({ onKycStarted }: Props): VNode {
description: i18n.str`access denied`,
when: AbsoluteTime.now(),
});
-
break;
}
case HttpStatusCode.NotFound: {
@@ -119,7 +126,6 @@ export function TriggerKyc({ onKycStarted }: Props): VNode {
description: i18n.str`not found`,
when: AbsoluteTime.now(),
});
-
break;
}
case HttpStatusCode.Conflict: {
diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts
@@ -41,15 +41,17 @@ import {
createRFC8959AccessTokenEncoded,
createRFC8959AccessTokenPlain,
decodeCrock,
+ eddsaGetPublic,
encodeCrock,
generateIban,
getRandomBytes,
hashNormalizedPaytoUri,
j2s,
- parsePaytoUri,
+ parsePaytoUriOrThrow,
randomBytes,
rsaBlind,
setGlobalLogLevelFromString,
+ signKycAuth,
stringifyPayTemplateUri,
succeedOrThrow,
} from "@gnu-taler/taler-util";
@@ -1771,15 +1773,22 @@ merchantCli
const instanceId = args.checkKyc.id ?? "admin";
const { merchant_priv } = await db.getInstancePrivateKey(instanceId);
+ const merchantPub = eddsaGetPublic(merchant_priv);
+
const allAccounts = await db.getInstanceKycStatus(instanceId);
+ const accountOwnerSig = encodeCrock(signKycAuth(merchant_priv));
+
const info = await Promise.all(
allAccounts.map(async ({ exchange_url, payto_uri }) => {
const exchangeApi = new TalerExchangeHttpClient(exchange_url, {});
- const kyc_status = await exchangeApi.checkKycStatus(
- merchant_priv,
- encodeCrock(hashNormalizedPaytoUri(parsePaytoUri(payto_uri)!)),
- );
+ const kyc_status = await exchangeApi.checkKycStatus({
+ accountPub: encodeCrock(merchantPub),
+ accountSig: accountOwnerSig,
+ paytoHash: encodeCrock(
+ hashNormalizedPaytoUri(parsePaytoUriOrThrow(payto_uri)),
+ ),
+ });
return {
payto_uri,
exchange_url,
diff --git a/packages/taler-harness/src/integrationtests/test-kyc-peer-push.ts b/packages/taler-harness/src/integrationtests/test-kyc-peer-push.ts
@@ -115,6 +115,8 @@ export async function runKycPeerPushTest(t: GlobalTestState) {
t.assertTrue(!!kycPaytoHash);
+ t.assertTrue(!!txDet.kycAccessToken);
+
await postAmlDecisionNoRules(t, {
amlPriv: amlKeypair.priv,
amlPub: amlKeypair.pub,
diff --git a/packages/taler-util/src/http-client/exchange-client.ts b/packages/taler-util/src/http-client/exchange-client.ts
@@ -37,10 +37,12 @@ import {
opSuccessFromHttp,
opUnknownHttpFailure,
} from "../operation.js";
-import { EddsaPrivP, decodeCrock, encodeCrock } from "../taler-crypto.js";
+import { encodeCrock } from "../taler-crypto.js";
import {
AccessToken,
AmountString,
+ EddsaPublicKeyString,
+ EddsaSignatureString,
OfficerAccount,
PaginationParams,
ReserveAccount,
@@ -108,7 +110,6 @@ import {
LongpollQueue,
signAmlDecision,
signAmlQuery,
- signKycAuth,
signWalletAccountSetup,
} from "../index.js";
import { TalerErrorCode } from "../taler-error-codes.js";
@@ -613,14 +614,13 @@ export class TalerExchangeHttpClient2 {
* https://docs.taler.net/core/api-exchange.html#get--kyc-check-$H_NORMALIZED_PAYTO
*
*/
- async checkKycStatus(
- signingKey: EddsaPrivP | string,
- paytoHash: string,
- longpoll: boolean = false,
- params: {
- awaitAuth?: boolean;
- } = {},
- ): Promise<
+ async checkKycStatus(args: {
+ paytoHash: string;
+ accountPub: EddsaPublicKeyString;
+ accountSig: EddsaSignatureString;
+ longpoll?: boolean;
+ awaitAuth?: boolean;
+ }): Promise<
| OperationOk<void>
| OperationAlternative<HttpStatusCode.Ok, AccountKycStatus>
| OperationAlternative<HttpStatusCode.Accepted, AccountKycStatus>
@@ -628,22 +628,18 @@ export class TalerExchangeHttpClient2 {
| OperationFail<HttpStatusCode.NotFound>
| OperationFail<HttpStatusCode.Conflict>
> {
+ const { paytoHash, accountPub, accountSig, longpoll, awaitAuth } = args;
const url = new URL(`kyc-check/${paytoHash}`, this.baseUrl);
- if (params.awaitAuth !== undefined) {
- url.searchParams.set("await_auth", params.awaitAuth ? "YES" : "NO");
+ if (awaitAuth !== undefined) {
+ url.searchParams.set("await_auth", awaitAuth ? "YES" : "NO");
}
- const sigKeyPacked =
- typeof signingKey === "string" ? decodeCrock(signingKey) : signingKey;
-
- const signature = encodeCrock(signKycAuth(sigKeyPacked));
-
const resp = await this.fetch(
url,
{
headers: {
- "Account-Owner-Signature": signature,
- "Account-Owner-Pub": encodeCrock(sigKeyPacked),
+ "Account-Owner-Signature": accountSig,
+ "Account-Owner-Pub": accountPub,
},
},
longpoll,
diff --git a/packages/taler-util/src/http-client/exchange.ts b/packages/taler-util/src/http-client/exchange.ts
@@ -24,6 +24,7 @@ import { createPlatformHttpLib } from "../http.js";
import { LibtoolVersion } from "../libtool-version.js";
import {
FailCasesByMethod,
+ OperationAlternative,
OperationFail,
OperationOk,
ResultByMethod,
@@ -35,7 +36,7 @@ import {
opSuccessFromHttp,
opUnknownHttpFailure,
} from "../operation.js";
-import { EddsaPrivP, decodeCrock, encodeCrock } from "../taler-crypto.js";
+import { encodeCrock } from "../taler-crypto.js";
import {
AccessToken,
EddsaPublicKeyString,
@@ -43,10 +44,10 @@ import {
LongPollParams,
OfficerAccount,
PaginationParams,
- PaytoHash,
codecForTalerCommonConfigResponse,
} from "../types-taler-common.js";
import {
+ AccountKycStatus,
AmlDecisionRequest,
ExchangeKycUploadFormRequest,
ExchangePurseDeposits,
@@ -92,7 +93,6 @@ import {
LongpollQueue,
signAmlDecision,
signAmlQuery,
- signKycAuth,
} from "../index.js";
import { TalerErrorCode } from "../taler-error-codes.js";
import { AbsoluteTime } from "../time.js";
@@ -515,28 +515,30 @@ export class TalerExchangeHttpClient {
*
* https://docs.taler.net/core/api-exchange.html#get--kyc-check-$H_NORMALIZED_PAYTO
*/
- async checkKycStatus(
- signingKey: EddsaPrivP | string,
- paytoHash: PaytoHash,
- params: {
- awaitAuth?: boolean;
- } = {},
- ) {
+ async checkKycStatus(args: {
+ paytoHash: string;
+ accountPub: EddsaPublicKeyString;
+ accountSig: EddsaSignatureString;
+ longpoll?: boolean;
+ awaitAuth?: boolean;
+ }): Promise<
+ | OperationOk<void>
+ | OperationAlternative<HttpStatusCode.Ok, AccountKycStatus>
+ | OperationAlternative<HttpStatusCode.Accepted, AccountKycStatus>
+ | OperationFail<HttpStatusCode.Forbidden>
+ | OperationFail<HttpStatusCode.NotFound>
+ | OperationFail<HttpStatusCode.Conflict>
+ > {
+ const { paytoHash, accountPub, accountSig, longpoll, awaitAuth } = args;
const url = new URL(`kyc-check/${paytoHash}`, this.baseUrl);
-
- if (params.awaitAuth !== undefined) {
- url.searchParams.set("await_auth", params.awaitAuth ? "YES" : "NO");
+ if (awaitAuth !== undefined) {
+ url.searchParams.set("await_auth", awaitAuth ? "YES" : "NO");
}
- const sigKeyPacked =
- typeof signingKey === "string" ? decodeCrock(signingKey) : signingKey;
-
- const signature = encodeCrock(signKycAuth(sigKeyPacked));
-
const resp = await this.httpLib.fetch(url.href, {
headers: {
- "Account-Owner-Signature": signature,
- "Account-Owner-Pub": encodeCrock(sigKeyPacked),
+ "Account-Owner-Signature": accountSig,
+ "Account-Owner-Pub": accountPub,
},
});
diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts
@@ -375,7 +375,7 @@ export function stringifyReservePaytoUri(
return `payto://${target}/${domainWithOptPort}${optPath}/${reservePub}`;
}
-export function parsePaytoUriOrThrow(s: string): PaytoUri | undefined {
+export function parsePaytoUriOrThrow(s: string): PaytoUri {
const ret = parsePaytoUri(s);
if (!ret) {
throw Error("invalid payto URI");
diff --git a/packages/taler-wallet-core/src/pay-peer-common.ts b/packages/taler-wallet-core/src/pay-peer-common.ts
@@ -192,17 +192,22 @@ export async function waitForKycCompletion(
exchangeBaseUrl: exchangeUrl,
});
+ const accountPub = mergeReserveInfo.reservePub;
+ const accountPriv = mergeReserveInfo.reservePriv;
+
const sigResp = await wex.cryptoApi.signWalletKycAuth({
- accountPriv: mergeReserveInfo.reservePriv,
- accountPub: mergeReserveInfo.reservePub,
+ accountPriv,
+ accountPub,
});
const exchangeClient = walletExchangeClient(exchangeUrl, wex);
- const resp = await exchangeClient.checkKycStatus(
- sigResp.sig,
- kycPaytoHash,
- true,
- );
+ const resp = await exchangeClient.checkKycStatus({
+ accountPub,
+ accountSig: sigResp.sig,
+ paytoHash: kycPaytoHash,
+ longpoll: true,
+ });
+
switch (resp.case) {
case "ok":
case HttpStatusCode.Ok:
diff --git a/packages/taler-wallet-core/src/pay-peer-pull-credit.ts b/packages/taler-wallet-core/src/pay-peer-pull-credit.ts
@@ -876,7 +876,7 @@ async function processPeerPullCreditBalanceKyc(
async function processPeerPullCreditKycRequired(
wex: WalletExecutionContext,
peerIni: PeerPullCreditRecord,
- kycPayoHash: string,
+ kycPaytoHash: string,
): Promise<TaskRunResult> {
const ctx = new PeerPullCreditTransactionContext(wex, peerIni.pursePub);
@@ -891,7 +891,11 @@ async function processPeerPullCreditKycRequired(
});
const exchangeClient = walletExchangeClient(peerIni.exchangeBaseUrl, wex);
- const res = await exchangeClient.checkKycStatus(sigResp.sig, kycPayoHash);
+ const res = await exchangeClient.checkKycStatus({
+ accountPub: mergeReserveInfo.reservePub,
+ accountSig: sigResp.sig,
+ paytoHash: kycPaytoHash,
+ });
switch (res.case) {
case "ok":
@@ -901,9 +905,9 @@ async function processPeerPullCreditKycRequired(
case HttpStatusCode.Accepted: {
logger.info(`kyc status: ${j2s(res.body)}`);
await recordTransition(ctx, {}, async (rec) => {
- rec.kycPaytoHash = kycPayoHash;
+ rec.kycPaytoHash = kycPaytoHash;
logger.info(
- `setting peer-pull-credit kyc payto hash to ${kycPayoHash}`,
+ `setting peer-pull-credit kyc payto hash to ${kycPaytoHash}`,
);
rec.kycAccessToken = res.body.access_token;
rec.status = PeerPullPaymentCreditStatus.PendingMergeKycRequired;
diff --git a/packages/taler-wallet-core/src/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/pay-peer-push-credit.ts
@@ -103,7 +103,7 @@ import {
notifyTransition,
parseTransactionIdentifier,
} from "./transactions.js";
-import { walletExchangeClient, WalletExecutionContext } from "./wallet.js";
+import { WalletExecutionContext, walletExchangeClient } from "./wallet.js";
import {
PerformCreateWithdrawalGroupResult,
WithdrawTransactionContext,
@@ -134,8 +134,8 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
}
readonly store = "peerPushCredit";
- readonly recordId = this.peerPushCreditId
- readonly recordState = computePeerPushCreditTransactionState
+ readonly recordId = this.peerPushCreditId;
+ readonly recordState = computePeerPushCreditTransactionState;
readonly recordMeta = (rec: PeerPushPaymentIncomingRecord) => ({
transactionId: this.transactionId,
status: rec.status,
@@ -143,7 +143,9 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
currency: Amounts.currencyOf(rec.estimatedAmountEffective),
exchanges: [rec.exchangeBaseUrl],
});
- updateTransactionMeta = (tx: WalletDbReadWriteTransaction<["peerPushCredit", "transactionsMeta"]>) => recordUpdateMeta(this, tx)
+ updateTransactionMeta = (
+ tx: WalletDbReadWriteTransaction<["peerPushCredit", "transactionsMeta"]>,
+ ) => recordUpdateMeta(this, tx);
/**
* Get the full transaction details for the transaction.
@@ -226,7 +228,7 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
amountEffective: isUnsuccessfulTransaction(txState)
? Amounts.stringify(Amounts.zeroOfAmount(peerContractTerms.amount))
: // FIXME: This is wrong, needs to consider fees!
- Amounts.stringify(peerContractTerms.amount),
+ Amounts.stringify(peerContractTerms.amount),
amountRaw: Amounts.stringify(peerContractTerms.amount),
exchangeBaseUrl: pushInc.exchangeBaseUrl,
info: {
@@ -284,7 +286,7 @@ export class PeerPushCreditTransactionContext implements TransactionContext {
const res = await withdrawalCtx.deleteTransactionInTx(tx);
notifs.push(...res.notifs);
}
- })
+ });
}
async suspendTransaction(): Promise<void> {
@@ -491,9 +493,9 @@ export async function preparePeerPushCredit(
break;
case HttpStatusCode.NotFound:
// FIXME: appropriated error code
- throw Error("unknown P2P contract")
+ throw Error("unknown P2P contract");
default:
- assertUnreachable(contractResp)
+ assertUnreachable(contractResp);
}
const pursePub = contractResp.body.purse_pub;
@@ -510,12 +512,12 @@ export async function preparePeerPushCredit(
break;
case HttpStatusCode.Gone:
// FIXME: appropriated error code
- throw Error("aborted peer push credit")
+ throw Error("aborted peer push credit");
case HttpStatusCode.NotFound:
// FIXME: appropriated error code
- throw Error("unknown peer push credit")
+ throw Error("unknown peer push credit");
default:
- assertUnreachable(resp)
+ assertUnreachable(resp);
}
const purseStatus = resp.body;
@@ -546,29 +548,33 @@ export async function preparePeerPushCredit(
}
const ctx = new PeerPushCreditTransactionContext(wex, peerPushCreditId);
- await recordCreate(ctx, {
- extraStores: ["contractTerms"]
- }, async (tx) => {
- await tx.contractTerms.put({
- h: contractTermsHash,
- contractTermsRaw: dec.contractTerms,
- });
- return {
- peerPushCreditId,
- contractPriv: contractPriv,
- exchangeBaseUrl: exchangeBaseUrl,
- mergePriv: dec.mergePriv,
- pursePub: pursePub,
- timestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()),
- contractTermsHash,
- status: PeerPushCreditStatus.DialogProposed,
- withdrawalGroupId,
- currency: Amounts.currencyOf(purseStatus.balance),
- estimatedAmountEffective: Amounts.stringify(
- wi.withdrawalAmountEffective,
- ),
- };
- });
+ await recordCreate(
+ ctx,
+ {
+ extraStores: ["contractTerms"],
+ },
+ async (tx) => {
+ await tx.contractTerms.put({
+ h: contractTermsHash,
+ contractTermsRaw: dec.contractTerms,
+ });
+ return {
+ peerPushCreditId,
+ contractPriv: contractPriv,
+ exchangeBaseUrl: exchangeBaseUrl,
+ mergePriv: dec.mergePriv,
+ pursePub: pursePub,
+ timestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()),
+ contractTermsHash,
+ status: PeerPushCreditStatus.DialogProposed,
+ withdrawalGroupId,
+ currency: Amounts.currencyOf(purseStatus.balance),
+ estimatedAmountEffective: Amounts.stringify(
+ wi.withdrawalAmountEffective,
+ ),
+ };
+ },
+ );
wex.taskScheduler.startShepherdTask(ctx.taskId);
const currency = Amounts.currencyOf(wi.withdrawalAmountRaw);
@@ -578,8 +584,8 @@ export async function preparePeerPushCredit(
"exchanges",
"exchangeDetails",
"globalCurrencyExchanges",
- "globalCurrencyAuditors"
- ]
+ "globalCurrencyAuditors",
+ ],
},
(tx) => getExchangeScopeInfo(tx, exchangeBaseUrl, currency),
);
@@ -605,7 +611,11 @@ async function longpollKycStatus(
const done = await waitForKycCompletion(wex, exchangeUrl, kycPaytoHash);
if (done) {
const ctx = new PeerPushCreditTransactionContext(wex, peerPushCreditId);
- await recordTransitionStatus(ctx, PeerPushCreditStatus.PendingMergeKycRequired, PeerPushCreditStatus.PendingMerge);
+ await recordTransitionStatus(
+ ctx,
+ PeerPushCreditStatus.PendingMergeKycRequired,
+ PeerPushCreditStatus.PendingMerge,
+ );
return TaskRunResult.progress();
} else {
return TaskRunResult.longpollReturnedPending();
@@ -633,7 +643,11 @@ async function processPeerPushCreditKycRequired(
});
const exchangeClient = walletExchangeClient(peerInc.exchangeBaseUrl, wex);
- const resp = await exchangeClient.checkKycStatus(sigResp.sig, kycPending.h_payto)
+ const resp = await exchangeClient.checkKycStatus({
+ accountPub: mergeReserveInfo.reservePub,
+ accountSig: sigResp.sig,
+ paytoHash: kycPending.h_payto,
+ });
switch (resp.case) {
case "ok":
@@ -673,7 +687,7 @@ async function processPeerPushCreditKycRequired(
case HttpStatusCode.Conflict:
case HttpStatusCode.Forbidden:
case HttpStatusCode.NotFound:
- throw Error(`unexpected kyc status response ${resp.case}`)
+ throw Error(`unexpected kyc status response ${resp.case}`);
default:
assertUnreachable(resp);
}
@@ -699,7 +713,11 @@ async function handlePendingMerge(
amount: kycCheckRes.nextThreshold,
exchangeBaseUrl: peerInc.exchangeBaseUrl,
});
- await recordTransitionStatus(ctx, PeerPushCreditStatus.PendingMerge, PeerPushCreditStatus.PendingBalanceKycInit);
+ await recordTransitionStatus(
+ ctx,
+ PeerPushCreditStatus.PendingMerge,
+ PeerPushCreditStatus.PendingBalanceKycInit,
+ );
return TaskRunResult.progress();
}
@@ -734,7 +752,7 @@ async function handlePendingMerge(
reservePriv: mergeReserveInfo.reservePriv,
});
- const exchangeClient = walletExchangeClient(peerInc.exchangeBaseUrl, wex)
+ const exchangeClient = walletExchangeClient(peerInc.exchangeBaseUrl, wex);
const mergeReq: ExchangePurseMergeRequest = {
payto_uri: reservePayto,
@@ -745,7 +763,7 @@ async function handlePendingMerge(
const mergeResp = await exchangeClient.postPurseMerge(
peerInc.pursePub,
- mergeReq
+ mergeReq,
);
logger.trace(`merge request: ${j2s(mergeReq)}`);
@@ -761,14 +779,15 @@ async function handlePendingMerge(
case HttpStatusCode.Conflict:
// FIXME: Check signature.
// FIXME: status completed by other
- await recordTransitionStatus(ctx,
+ await recordTransitionStatus(
+ ctx,
PeerPushCreditStatus.PendingMerge,
PeerPushCreditStatus.Aborted,
);
return TaskRunResult.finished();
case HttpStatusCode.Gone:
// FIXME: status expired
- await ctx.abortTransaction()
+ await ctx.abortTransaction();
return TaskRunResult.finished();
case HttpStatusCode.Forbidden:
case HttpStatusCode.NotFound:
@@ -920,25 +939,36 @@ async function processPeerPushDebitDialogProposed(
pullIni.peerPushCreditId,
);
const exchangeClient = walletExchangeClient(pullIni.exchangeBaseUrl, wex);
- const resp = await exchangeClient.getPurseStatusAtMerge(pullIni.pursePub, true);
+ const resp = await exchangeClient.getPurseStatusAtMerge(
+ pullIni.pursePub,
+ true,
+ );
switch (resp.case) {
case "ok":
break;
case HttpStatusCode.Gone:
// Exchange says that purse doesn't exist anymore => expired!
- await recordTransitionStatus(ctx, PeerPushCreditStatus.DialogProposed, PeerPushCreditStatus.Aborted);
+ await recordTransitionStatus(
+ ctx,
+ PeerPushCreditStatus.DialogProposed,
+ PeerPushCreditStatus.Aborted,
+ );
return TaskRunResult.finished();
case HttpStatusCode.NotFound:
await ctx.failTransaction(resp.detail);
return TaskRunResult.finished();
default:
- assertUnreachable(resp)
+ assertUnreachable(resp);
}
if (isPurseMerged(resp.body)) {
logger.info("purse completed by another wallet");
- await recordTransitionStatus(ctx, PeerPushCreditStatus.DialogProposed, PeerPushCreditStatus.Aborted);
+ await recordTransitionStatus(
+ ctx,
+ PeerPushCreditStatus.DialogProposed,
+ PeerPushCreditStatus.Aborted,
+ );
return TaskRunResult.finished();
}
@@ -1056,7 +1086,11 @@ async function processPeerPushCreditBalanceKyc(
});
if (ret.result === "ok") {
- await recordTransitionStatus(ctx, PeerPushCreditStatus.PendingBalanceKycRequired, PeerPushCreditStatus.PendingMerge);
+ await recordTransitionStatus(
+ ctx,
+ PeerPushCreditStatus.PendingBalanceKycRequired,
+ PeerPushCreditStatus.PendingMerge,
+ );
return TaskRunResult.progress();
} else if (
peerInc.status === PeerPushCreditStatus.PendingBalanceKycInit &&
@@ -1127,7 +1161,11 @@ export async function confirmPeerPushCredit(
if (checkPeerCreditHardLimitExceeded(exchange, res.contractTerms.amount)) {
throw Error("peer credit would exceed hard KYC limit");
}
- await recordTransitionStatus(ctx, PeerPushCreditStatus.DialogProposed, PeerPushCreditStatus.PendingMerge);
+ await recordTransitionStatus(
+ ctx,
+ PeerPushCreditStatus.DialogProposed,
+ PeerPushCreditStatus.PendingMerge,
+ );
wex.taskScheduler.stopShepherdTask(ctx.taskId);
wex.taskScheduler.startShepherdTask(ctx.taskId);