aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/deposits.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/deposits.ts')
-rw-r--r--packages/taler-wallet-core/src/deposits.ts135
1 files changed, 84 insertions, 51 deletions
diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts
index 2004c12cb..36ebf3974 100644
--- a/packages/taler-wallet-core/src/deposits.ts
+++ b/packages/taler-wallet-core/src/deposits.ts
@@ -72,7 +72,7 @@ import {
stringToBytes,
} from "@gnu-taler/taler-util";
import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http";
-import { selectPayCoins } from "./coinSelection.js";
+import { selectPayCoins, selectPayCoinsInTx } from "./coinSelection.js";
import {
PendingTaskType,
TaskIdStr,
@@ -518,12 +518,13 @@ async function refundDepositGroup(
const res = await wex.db.runReadWriteTx(
{
storeNames: [
+ "coinAvailability",
+ "coinHistory",
+ "coins",
+ "denominations",
"depositGroups",
"refreshGroups",
"refreshSessions",
- "coins",
- "denominations",
- "coinAvailability",
],
},
async (tx) => {
@@ -668,12 +669,20 @@ async function processDepositGroupPendingKyc(
`kyc-check/${kycInfo.requirementRow}/${kycInfo.paytoHash}/${userType}`,
kycInfo.exchangeBaseUrl,
);
- url.searchParams.set("timeout_ms", "10000");
- logger.info(`kyc url ${url.href}`);
- const kycStatusRes = await wex.http.fetch(url.href, {
- method: "GET",
- cancellationToken: wex.cancellationToken,
- });
+
+ const kycStatusRes = await wex.ws.runLongpollQueueing(
+ wex,
+ url.hostname,
+ async (timeoutMs) => {
+ url.searchParams.set("timeout_ms", `${timeoutMs}`);
+ logger.info(`kyc url ${url.href}`);
+ return await wex.http.fetch(url.href, {
+ method: "GET",
+ cancellationToken: wex.cancellationToken,
+ });
+ },
+ );
+
if (
kycStatusRes.status === HttpStatusCode.Ok ||
//FIXME: NoContent is not expected https://docs.taler.net/core/api-exchange.html#post--purses-$PURSE_PUB-merge
@@ -979,43 +988,17 @@ async function processDepositGroupPendingDeposit(
if (!depositGroup.payCoinSelection) {
logger.info("missing coin selection for deposit group, selecting now");
- // FIXME: Consider doing the coin selection inside the txn
- const payCoinSel = await selectPayCoins(wex, {
- restrictExchanges: {
- auditors: [],
- exchanges: contractData.allowedExchanges,
- },
- restrictWireMethod: contractData.wireMethod,
- contractTermsAmount: Amounts.parseOrThrow(contractData.amount),
- depositFeeLimit: Amounts.parseOrThrow(contractData.maxDepositFee),
- prevPayCoins: [],
- });
-
- switch (payCoinSel.type) {
- case "success":
- logger.info("coin selection success");
- break;
- case "failure":
- logger.info("coin selection failure");
- throw TalerError.fromDetail(
- TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE,
- {
- insufficientBalanceDetails: payCoinSel.insufficientBalanceDetails,
- },
- );
- case "prospective":
- logger.info("coin selection prospective");
- throw Error("insufficient balance (waiting on pending refresh)");
- default:
- assertUnreachable(payCoinSel);
- }
const transitionDone = await wex.db.runReadWriteTx(
{
storeNames: [
+ "contractTerms",
+ "exchanges",
+ "exchangeDetails",
"depositGroups",
"coins",
"coinAvailability",
+ "coinHistory",
"refreshGroups",
"refreshSessions",
"denominations",
@@ -1029,6 +1012,45 @@ async function processDepositGroupPendingDeposit(
if (dg.statusPerCoin) {
return false;
}
+
+ const contractTermsRec = tx.contractTerms.get(
+ depositGroup.contractTermsHash,
+ );
+ if (!contractTermsRec) {
+ throw Error("contract terms for deposit not found in database");
+ }
+
+ const payCoinSel = await selectPayCoinsInTx(wex, tx, {
+ restrictExchanges: {
+ auditors: [],
+ exchanges: contractData.allowedExchanges,
+ },
+ restrictWireMethod: contractData.wireMethod,
+ contractTermsAmount: Amounts.parseOrThrow(contractData.amount),
+ depositFeeLimit: Amounts.parseOrThrow(contractData.maxDepositFee),
+ prevPayCoins: [],
+ });
+
+ switch (payCoinSel.type) {
+ case "success":
+ logger.info("coin selection success");
+ break;
+ case "failure":
+ logger.info("coin selection failure");
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE,
+ {
+ insufficientBalanceDetails:
+ payCoinSel.insufficientBalanceDetails,
+ },
+ );
+ case "prospective":
+ logger.info("coin selection prospective");
+ throw Error("insufficient balance (waiting on pending refresh)");
+ default:
+ assertUnreachable(payCoinSel);
+ }
+
dg.payCoinSelection = {
coinContributions: payCoinSel.coinSel.coins.map(
(x) => x.contribution,
@@ -1041,7 +1063,7 @@ async function processDepositGroupPendingDeposit(
);
await tx.depositGroups.put(dg);
await spendCoins(wex, tx, {
- allocationId: transactionId,
+ transactionId,
coinPubs: dg.payCoinSelection.coinPubs,
contributions: dg.payCoinSelection.coinContributions.map((x) =>
Amounts.parseOrThrow(x),
@@ -1168,6 +1190,10 @@ export async function processDepositGroup(
wex: WalletExecutionContext,
depositGroupId: string,
): Promise<TaskRunResult> {
+ if (!wex.ws.networkAvailable) {
+ return TaskRunResult.networkRequired();
+ }
+
const depositGroup = await wex.db.runReadOnlyTx(
{ storeNames: ["depositGroups"] },
async (tx) => {
@@ -1264,11 +1290,17 @@ async function trackDeposit(
wireHash,
});
url.searchParams.set("merchant_sig", sigResp.sig);
- url.searchParams.set("timeout_ms", "30000");
- const httpResp = await wex.http.fetch(url.href, {
- method: "GET",
- cancellationToken: wex.cancellationToken,
- });
+ const httpResp = await wex.ws.runLongpollQueueing(
+ wex,
+ url.hostname,
+ async (timeoutMs) => {
+ url.searchParams.set("timeout_ms", `${timeoutMs}`);
+ return await wex.http.fetch(url.href, {
+ method: "GET",
+ cancellationToken: wex.cancellationToken,
+ });
+ },
+ );
logger.trace(`deposits response status: ${httpResp.status}`);
switch (httpResp.status) {
case HttpStatusCode.Accepted: {
@@ -1606,20 +1638,21 @@ export async function createDepositGroup(
const newTxState = await wex.db.runReadWriteTx(
{
storeNames: [
- "depositGroups",
+ "coinAvailability",
+ "coinHistory",
"coins",
- "recoupGroups",
+ "contractTerms",
"denominations",
+ "depositGroups",
+ "recoupGroups",
"refreshGroups",
"refreshSessions",
- "coinAvailability",
- "contractTerms",
],
},
async (tx) => {
if (depositGroup.payCoinSelection) {
await spendCoins(wex, tx, {
- allocationId: transactionId,
+ transactionId,
coinPubs: depositGroup.payCoinSelection.coinPubs,
contributions: depositGroup.payCoinSelection.coinContributions.map(
(x) => Amounts.parseOrThrow(x),