diff options
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/taler-util/src/amounts.ts | 11 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/common.ts | 3 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/deposits.ts | 129 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/exchanges.ts | 26 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/pay.ts | 7 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/withdraw.ts | 33 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/util/retries.ts | 15 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 5 | ||||
| -rw-r--r-- | packages/taler-wallet-webextension/src/wallet/DepositPage.tsx | 2 | 
9 files changed, 120 insertions, 111 deletions
| diff --git a/packages/taler-util/src/amounts.ts b/packages/taler-util/src/amounts.ts index 505a68f46..98cd4ad62 100644 --- a/packages/taler-util/src/amounts.ts +++ b/packages/taler-util/src/amounts.ts @@ -129,6 +129,17 @@ export class Amounts {      return Amounts.add(jsonAmounts[0], ...jsonAmounts.slice(1));    } +  static sumOrZero(currency: string, amounts: AmountLike[]): Result { +    if (amounts.length <= 0) { +      return { +        amount: Amounts.getZero(currency), +        saturated: false, +      }; +    } +    const jsonAmounts = amounts.map((x) => Amounts.jsonifyAmount(x)); +    return Amounts.add(jsonAmounts[0], ...jsonAmounts.slice(1)); +  } +    /**     * Add two amounts.  Return the result and whether     * the addition overflowed.  The overflow is always handled diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index 5261b114d..0fdde9dca 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -14,6 +14,9 @@   GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>   */ +/** + * Imports. + */  import { TalerErrorDetail, TalerErrorCode } from "@gnu-taler/taler-util";  import { CryptoApiStoppedError } from "../crypto/workers/cryptoDispatcher.js";  import { TalerError, getErrorDetailFromException } from "../errors.js"; diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index 2e14afdf1..501e9b76b 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -14,17 +14,15 @@   GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>   */ +/** + * Imports. + */  import {    AbsoluteTime,    AmountJson,    Amounts, -  buildCodecForObject,    canonicalJson, -  Codec,    codecForDepositSuccess, -  codecForString, -  codecForTimestamp, -  codecOptional,    ContractTerms,    CreateDepositGroupRequest,    CreateDepositGroupResponse, @@ -42,21 +40,22 @@ import {    TrackDepositGroupResponse,    URL,  } from "@gnu-taler/taler-util"; -import { InternalWalletState } from "../internal-wallet-state.js";  import { DepositGroupRecord, OperationStatus } from "../db.js"; +import { InternalWalletState } from "../internal-wallet-state.js";  import { PayCoinSelection, selectPayCoins } from "../util/coinSelection.js";  import { readSuccessResponseJsonOrThrow } from "../util/http.js"; -import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js"; +import { initRetryInfo, RetryInfo } from "../util/retries.js"; +import { guardOperationException } from "./common.js";  import { getExchangeDetails } from "./exchanges.js";  import {    applyCoinSpend, +  CoinSelectionRequest,    extractContractData,    generateDepositPermissions,    getCandidatePayCoins,    getTotalPaymentCost,  } from "./pay.js";  import { getTotalRefreshCost } from "./refresh.js"; -import { guardOperationException } from "./common.js";  /**   * Logger. @@ -73,17 +72,36 @@ async function resetDepositGroupRetry(      }))      .runReadWrite(async (tx) => {        const x = await tx.depositGroups.get(depositGroupId); -      if (x) { -        x.retryInfo = initRetryInfo(); -        await tx.depositGroups.put(x); +      if (!x) { +        return; +      } +      x.retryInfo = initRetryInfo(); +      delete x.lastError; +      await tx.depositGroups.put(x); +    }); +} + +async function incrementDepositGroupRetry( +  ws: InternalWalletState, +  depositGroupId: string, +): Promise<void> { +  await ws.db +    .mktx((x) => ({ depositGroups: x.depositGroups })) +    .runReadWrite(async (tx) => { +      const r = await tx.depositGroups.get(depositGroupId); +      if (!r) { +        return;        } +      r.retryInfo = RetryInfo.increment(r.retryInfo); +      delete r.lastError; +      await tx.depositGroups.put(r);      });  } -async function incrementDepositRetry( +async function reportDepositGroupError(    ws: InternalWalletState,    depositGroupId: string, -  err: TalerErrorDetail | undefined, +  err: TalerErrorDetail,  ): Promise<void> {    await ws.db      .mktx((x) => ({ depositGroups: x.depositGroups })) @@ -93,16 +111,15 @@ async function incrementDepositRetry(          return;        }        if (!r.retryInfo) { +        logger.error( +          `deposit group record (${depositGroupId}) reports error, but no retry active`, +        );          return;        } -      r.retryInfo.retryCounter++; -      updateRetryInfoTimeout(r.retryInfo);        r.lastError = err;        await tx.depositGroups.put(r);      }); -  if (err) { -    ws.notify({ type: NotificationType.DepositOperationError, error: err }); -  } +  ws.notify({ type: NotificationType.DepositOperationError, error: err });  }  export async function processDepositGroup( @@ -111,8 +128,8 @@ export async function processDepositGroup(    forceNow = false,  ): Promise<void> {    await ws.memoProcessDeposit.memo(depositGroupId, async () => { -    const onOpErr = (e: TalerErrorDetail): Promise<void> => -      incrementDepositRetry(ws, depositGroupId, e); +    const onOpErr = (err: TalerErrorDetail): Promise<void> => +      reportDepositGroupError(ws, depositGroupId, err);      return await guardOperationException(        async () => await processDepositGroupImpl(ws, depositGroupId, forceNow),        onOpErr, @@ -125,9 +142,6 @@ async function processDepositGroupImpl(    depositGroupId: string,    forceNow = false,  ): Promise<void> { -  if (forceNow) { -    await resetDepositGroupRetry(ws, depositGroupId); -  }    const depositGroup = await ws.db      .mktx((x) => ({        depositGroups: x.depositGroups, @@ -144,6 +158,12 @@ async function processDepositGroupImpl(      return;    } +  if (forceNow) { +    await resetDepositGroupRetry(ws, depositGroupId); +  } else { +    await incrementDepositGroupRetry(ws, depositGroupId); +  } +    const contractData = extractContractData(      depositGroup.contractTermsRaw,      depositGroup.contractTermsHash, @@ -306,42 +326,25 @@ export async function getFeeForDeposit(        }      }); -  const timestamp = AbsoluteTime.now(); -  const timestampRound = AbsoluteTime.toTimestamp(timestamp); -  const contractTerms: ContractTerms = { -    auditors: [], -    exchanges: exchangeInfos, -    amount: req.amount, -    max_fee: Amounts.stringify(amount), -    max_wire_fee: Amounts.stringify(amount), -    wire_method: p.targetType, -    timestamp: timestampRound, -    merchant_base_url: "", -    summary: "", -    nonce: "", -    wire_transfer_deadline: timestampRound, -    order_id: "", -    h_wire: "", -    pay_deadline: AbsoluteTime.toTimestamp( -      AbsoluteTime.addDuration(timestamp, durationFromSpec({ hours: 1 })), -    ), -    merchant: { -      name: "", -    }, -    merchant_pub: "", -    refund_deadline: TalerProtocolTimestamp.zero(), +  const csr: CoinSelectionRequest = { +    allowedAuditors: [], +    allowedExchanges: [], +    amount: Amounts.parseOrThrow(req.amount), +    maxDepositFee: Amounts.parseOrThrow(req.amount), +    maxWireFee: Amounts.parseOrThrow(req.amount), +    timestamp: TalerProtocolTimestamp.now(), +    wireFeeAmortization: 1, +    wireMethod: p.targetType,    }; -  const contractData = extractContractData(contractTerms, "", ""); - -  const candidates = await getCandidatePayCoins(ws, contractData); +  const candidates = await getCandidatePayCoins(ws, csr);    const payCoinSel = selectPayCoins({      candidates, -    contractTermsAmount: contractData.amount, -    depositFeeLimit: contractData.maxDepositFee, -    wireFeeAmortization: contractData.wireFeeAmortization ?? 1, -    wireFeeLimit: contractData.maxWireFee, +    contractTermsAmount: csr.amount, +    depositFeeLimit: csr.maxDepositFee, +    wireFeeAmortization: csr.wireFeeAmortization, +    wireFeeLimit: csr.maxWireFee,      prevPayCoins: [],    }); @@ -573,6 +576,7 @@ export async function getEffectiveDepositAmount(    return Amounts.sub(Amounts.sum(amt).amount, Amounts.sum(fees).amount).amount;  } +// FIXME: rename to DepositGroupFee  export interface DepositFee {    coin: AmountJson;    wire: AmountJson; @@ -594,8 +598,6 @@ export async function getTotalFeeForDepositAmount(    const refreshFee: AmountJson[] = [];    const exchangeSet: Set<string> = new Set(); -  // let acc: AmountJson = Amounts.getZero(total.currency); -    await ws.db      .mktx((x) => ({        coins: x.coins, @@ -658,17 +660,8 @@ export async function getTotalFeeForDepositAmount(      });    return { -    coin: -      coinFee.length === 0 -        ? Amounts.getZero(total.currency) -        : Amounts.sum(coinFee).amount, -    wire: -      wireFee.length === 0 -        ? Amounts.getZero(total.currency) -        : Amounts.sum(wireFee).amount, -    refresh: -      refreshFee.length === 0 -        ? Amounts.getZero(total.currency) -        : Amounts.sum(refreshFee).amount, +    coin: Amounts.sumOrZero(total.currency, coinFee).amount, +    wire: Amounts.sumOrZero(total.currency, wireFee).amount, +    refresh: Amounts.sumOrZero(total.currency, refreshFee).amount,    };  } diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 51b5c7806..09449c875 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -18,35 +18,31 @@   * Imports.   */  import { +  AbsoluteTime,    Amounts, -  ExchangeAuditor,    canonicalizeBaseUrl,    codecForExchangeKeysJson,    codecForExchangeWireJson, -  ExchangeDenomination, +  DenominationPubKey,    Duration,    durationFromSpec, +  encodeCrock, +  ExchangeAuditor, +  ExchangeDenomination,    ExchangeSignKeyJson,    ExchangeWireJson, +  hashDenomPub, +  LibtoolVersion,    Logger,    NotificationType,    parsePaytoUri,    Recoup,    TalerErrorCode, -  URL,    TalerErrorDetail, -  AbsoluteTime, -  hashDenomPub, -  LibtoolVersion, -  codecForAny, -  DenominationPubKey, -  DenomKeyType, -  ExchangeKeysJson, -  TalerProtocolTimestamp,    TalerProtocolDuration, +  TalerProtocolTimestamp, +  URL,  } from "@gnu-taler/taler-util"; -import { decodeCrock, encodeCrock, hash } from "@gnu-taler/taler-util"; -import { CryptoDispatcher } from "../crypto/workers/cryptoDispatcher.js";  import {    DenominationRecord,    DenominationVerificationStatus, @@ -56,6 +52,8 @@ import {    WireFee,    WireInfo,  } from "../db.js"; +import { TalerError } from "../errors.js"; +import { InternalWalletState, TrustInfo } from "../internal-wallet-state.js";  import {    getExpiry,    HttpRequestLibrary, @@ -64,8 +62,6 @@ import {  } from "../util/http.js";  import { DbAccess, GetReadOnlyAccess } from "../util/query.js";  import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js"; -import { TalerError } from "../errors.js"; -import { InternalWalletState, TrustInfo } from "../internal-wallet-state.js";  import {    WALLET_CACHE_BREAKER_CLIENT_VERSION,    WALLET_EXCHANGE_PROTOCOL_VERSION, diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts index 193ce54e2..b761367fb 100644 --- a/packages/taler-wallet-core/src/operations/pay.ts +++ b/packages/taler-wallet-core/src/operations/pay.ts @@ -98,6 +98,7 @@ import { GetReadWriteAccess } from "../util/query.js";  import {    getRetryDuration,    initRetryInfo, +  RetryInfo,    updateRetryInfoTimeout,  } from "../util/retries.js";  import { getExchangeDetails } from "./exchanges.js"; @@ -539,11 +540,7 @@ async function incrementPurchasePayRetry(        if (!pr) {          return;        } -      if (!pr.payRetryInfo) { -        pr.payRetryInfo = initRetryInfo(); -      } -      pr.payRetryInfo.retryCounter++; -      updateRetryInfoTimeout(pr.payRetryInfo); +      pr.payRetryInfo = RetryInfo.increment(pr.payRetryInfo);        delete pr.lastPayError;        await tx.purchases.put(pr);      }); diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 7997ab5be..4a7adbb9c 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -18,32 +18,31 @@   * Imports.   */  import { +  AbsoluteTime,    AmountJson,    Amounts, +  AmountString,    BankWithdrawDetails,    codecForTalerConfigResponse,    codecForWithdrawOperationStatusResponse,    codecForWithdrawResponse, +  DenomKeyType, +  Duration,    durationFromSpec,    ExchangeListItem, +  ExchangeWithdrawRequest, +  LibtoolVersion,    Logger,    NotificationType,    parseWithdrawUri,    TalerErrorCode,    TalerErrorDetail, -  AbsoluteTime, -  WithdrawResponse, +  TalerProtocolTimestamp, +  UnblindedSignature,    URL, -  WithdrawUriInfoResponse,    VersionMatchResult, -  DenomKeyType, -  LibtoolVersion, -  UnblindedSignature, -  ExchangeWithdrawRequest, -  Duration, -  TalerProtocolTimestamp, -  TransactionType, -  AmountString, +  WithdrawResponse, +  WithdrawUriInfoResponse,  } from "@gnu-taler/taler-util";  import {    CoinRecord, @@ -58,18 +57,18 @@ import {    PlanchetRecord,    WithdrawalGroupRecord,  } from "../db.js"; -import { walletCoreDebugFlags } from "../util/debugFlags.js"; -import { -  HttpRequestLibrary, -  readSuccessResponseJsonOrThrow, -} from "../util/http.js"; -import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";  import {    getErrorDetailFromException,    makeErrorDetail,    TalerError,  } from "../errors.js";  import { InternalWalletState } from "../internal-wallet-state.js"; +import { walletCoreDebugFlags } from "../util/debugFlags.js"; +import { +  HttpRequestLibrary, +  readSuccessResponseJsonOrThrow, +} from "../util/http.js"; +import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js";  import {    WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,    WALLET_EXCHANGE_PROTOCOL_VERSION, diff --git a/packages/taler-wallet-core/src/util/retries.ts b/packages/taler-wallet-core/src/util/retries.ts index 4b78d38ef..25b4c5055 100644 --- a/packages/taler-wallet-core/src/util/retries.ts +++ b/packages/taler-wallet-core/src/util/retries.ts @@ -92,3 +92,18 @@ export function initRetryInfo(p: RetryPolicy = defaultRetryPolicy): RetryInfo {    updateRetryInfoTimeout(info, p);    return info;  } + +export namespace RetryInfo { +  export function increment( +    r: RetryInfo | undefined, +    p: RetryPolicy = defaultRetryPolicy, +  ) { +    if (!r) { +      return initRetryInfo(p); +    } +    const r2 = { ...r }; +    r2.retryCounter++; +    updateRetryInfoTimeout(r2, p); +    return r2; +  } +} diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index bb560774a..943051153 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -193,10 +193,7 @@ import {  import { DbAccess, GetReadWriteAccess } from "./util/query.js";  import { TimerGroup } from "./util/timer.js";  import { WalletCoreApiClient } from "./wallet-api-types.js"; -import { -  TalerCryptoInterface, -  TalerCryptoInterfaceR, -} from "./crypto/cryptoImplementation.js"; +import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js";  const builtinAuditors: AuditorTrustRecord[] = [    { diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx index 65cdee4e9..2f1f84d94 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx @@ -22,7 +22,6 @@ import {    PaytoUri,  } from "@gnu-taler/taler-util";  import { DepositFee } from "@gnu-taler/taler-wallet-core/src/operations/deposits"; -import { saturate } from "polished";  import { Fragment, h, VNode } from "preact";  import { useEffect, useState } from "preact/hooks";  import { Loading } from "../components/Loading"; @@ -30,7 +29,6 @@ import { LoadingError } from "../components/LoadingError";  import { SelectList } from "../components/SelectList";  import {    Button, -  ButtonBoxWarning,    ButtonPrimary,    ErrorText,    Input, | 
