diff options
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/taler-util/src/walletTypes.ts | 157 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/crypto/cryptoImplementation.ts | 9 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/db.ts | 65 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/backup/import.ts | 10 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/deposits.ts | 2 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/exchanges.ts | 7 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/withdraw.ts | 19 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 11 | 
8 files changed, 209 insertions, 71 deletions
| diff --git a/packages/taler-util/src/walletTypes.ts b/packages/taler-util/src/walletTypes.ts index eac9cf7db..7b482c60e 100644 --- a/packages/taler-util/src/walletTypes.ts +++ b/packages/taler-util/src/walletTypes.ts @@ -44,14 +44,17 @@ import {    codecForAny,    buildCodecForUnion,    codecForNumber, +  codecForMap,  } from "./codec.js";  import {    AmountString, +  AuditorDenomSig,    codecForContractTerms,    CoinEnvelope,    ContractTerms,    DenominationPubKey,    DenomKeyType, +  ExchangeAuditor,    UnblindedSignature,  } from "./talerTypes.js";  import { OrderShortInfo, codecForOrderShortInfo } from "./transactionsTypes.js"; @@ -580,13 +583,164 @@ export interface ExchangeTos {    contentType?: string;    content?: string;  } + +/** + * Wire fee for one wire method + */ +export interface WireFee { +  /** +   * Fee for wire transfers. +   */ +  wireFee: AmountJson; + +  /** +   * Fees to close and refund a reserve. +   */ +  closingFee: AmountJson; + +  /** +   * Fees for inter-exchange transfers from P2P payments. +   */ +  wadFee: AmountJson; + +  /** +   * Start date of the fee. +   */ +  startStamp: TalerProtocolTimestamp; + +  /** +   * End date of the fee. +   */ +  endStamp: TalerProtocolTimestamp; + +  /** +   * Signature made by the exchange master key. +   */ +  sig: string; +} + +/** + * Information about one of the exchange's bank accounts. + */ +export interface ExchangeAccount { +  payto_uri: string; +  master_sig: string; +} + +export type WireFeeMap = { [wireMethod: string]: WireFee[] } +export interface WireInfo { +  feesForType: WireFeeMap; +  accounts: ExchangeAccount[]; +} + +const codecForExchangeAccount = (): Codec<ExchangeAccount> => +  buildCodecForObject<ExchangeAccount>() +    .property("payto_uri", codecForString()) +    .property("master_sig", codecForString()) +    .build("codecForExchangeAccount"); + + +const codecForWireFee = (): Codec<WireFee> => +  buildCodecForObject<WireFee>() +    .property("sig", codecForString()) +    .property("wireFee", codecForAmountJson()) +    .property("wadFee", codecForAmountJson()) +    .property("closingFee", codecForAmountJson()) +    .property("startStamp", codecForTimestamp) +    .property("endStamp", codecForTimestamp) +    .build("codecForWireFee"); + +const codecForWireInfo = (): Codec<WireInfo> => +  buildCodecForObject<WireInfo>() +    .property("feesForType", codecForMap(codecForList(codecForWireFee()))) +    .property("accounts", codecForList(codecForExchangeAccount())) +    .build("codecForWireInfo"); + +const codecForDenominationInfo = (): Codec<DenominationInfo> => +  buildCodecForObject<DenominationInfo>() +    .property("denomPubHash", (codecForString())) +    .property("value", (codecForAmountJson())) +    .property("feeWithdraw", (codecForAmountJson())) +    .property("feeDeposit", (codecForAmountJson())) +    .property("feeRefresh", (codecForAmountJson())) +    .property("feeRefund", (codecForAmountJson())) +    .property("stampStart", (codecForTimestamp)) +    .property("stampExpireWithdraw", (codecForTimestamp)) +    .property("stampExpireLegal", (codecForTimestamp)) +    .property("stampExpireDeposit", (codecForTimestamp)) +    .build("codecForDenominationInfo"); + + +export interface DenominationInfo { +  value: AmountJson; +  denomPubHash: string; +  /** +   * Fee for withdrawing. +   */ +  feeWithdraw: AmountJson; + +  /** +   * Fee for depositing. +   */ +  feeDeposit: AmountJson; + +  /** +   * Fee for refreshing. +   */ +  feeRefresh: AmountJson; + +  /** +   * Fee for refunding. +   */ +  feeRefund: AmountJson; + +  /** +   * Validity start date of the denomination. +   */ +  stampStart: TalerProtocolTimestamp; + +  /** +   * Date after which the currency can't be withdrawn anymore. +   */ +  stampExpireWithdraw: TalerProtocolTimestamp; + +  /** +   * Date after the denomination officially doesn't exist anymore. +   */ +  stampExpireLegal: TalerProtocolTimestamp; + +  /** +   * Data after which coins of this denomination can't be deposited anymore. +   */ +  stampExpireDeposit: TalerProtocolTimestamp; + +} +  export interface ExchangeListItem {    exchangeBaseUrl: string;    currency: string;    paytoUris: string[];    tos: ExchangeTos; +  auditors: ExchangeAuditor[]; +  wireInfo: WireInfo; +  denominations: DenominationInfo[];  } + +const codecForAuditorDenomSig = (): Codec<AuditorDenomSig> => +  buildCodecForObject<AuditorDenomSig>() +    .property("denom_pub_h", codecForString()) +    .property("auditor_sig", codecForString()) +    .build("AuditorDenomSig"); + +const codecForExchangeAuditor = (): Codec<ExchangeAuditor> => +  buildCodecForObject<ExchangeAuditor>() +    .property("auditor_pub", codecForString()) +    .property("auditor_url", codecForString()) +    .property("denomination_keys", codecForList(codecForAuditorDenomSig())) +    .build("codecForExchangeAuditor"); + +  const codecForExchangeTos = (): Codec<ExchangeTos> =>    buildCodecForObject<ExchangeTos>()      .property("acceptedVersion", codecOptional(codecForString())) @@ -601,6 +755,9 @@ export const codecForExchangeListItem = (): Codec<ExchangeListItem> =>      .property("exchangeBaseUrl", codecForString())      .property("paytoUris", codecForList(codecForString()))      .property("tos", codecForExchangeTos()) +    .property("auditors", codecForList(codecForExchangeAuditor())) +    .property("wireInfo", codecForWireInfo()) +    .property("denominations", codecForList(codecForDenominationInfo()))      .build("ExchangeListItem");  export const codecForExchangesListResponse = (): Codec<ExchangesListRespose> => diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts index edb9cdccb..099bf09fe 100644 --- a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts @@ -76,11 +76,12 @@ import {    TalerProtocolTimestamp,    TalerSignaturePurpose,    UnblindedSignature, +  WireFee,    WithdrawalPlanchet,  } from "@gnu-taler/taler-util";  import bigint from "big-integer";  // FIXME: Crypto should not use DB Types! -import { DenominationRecord, WireFee } from "../db.js"; +import { DenominationRecord } from "../db.js";  import {    CreateRecoupRefreshReqRequest,    CreateRecoupReqRequest, @@ -1045,10 +1046,10 @@ export const nativeCryptoR: TalerCryptoInterfaceR = {        };        if (depositInfo.requiredMinimumAge != null) { -	      s.minimum_age_sig = minimumAgeSig; -	      s.age_commitment = depositInfo.ageCommitmentProof?.commitment.publicKeys; +        s.minimum_age_sig = minimumAgeSig; +        s.age_commitment = depositInfo.ageCommitmentProof?.commitment.publicKeys;        } else if (depositInfo.ageCommitmentProof) { -	      (s as any).h_age_commitment = hAgeCommitment; +        (s as any).h_age_commitment = hAgeCommitment;        }        return s; diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 8f558abd3..a34a09f75 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -44,6 +44,7 @@ import {    PayCoinSelection,    PeerContractTerms,    Location, +  WireInfo,  } from "@gnu-taler/taler-util";  import { RetryInfo } from "./util/retries.js";  import { Event, IDBDatabase } from "@gnu-taler/idb-bridge"; @@ -392,11 +393,6 @@ export interface ExchangeDetailsRecord {    wireInfo: WireInfo;  } -export interface WireInfo { -  feesForType: { [wireMethod: string]: WireFee[] }; - -  accounts: ExchangeBankAccount[]; -}  export interface ExchangeDetailsPointer {    masterPublicKey: string; @@ -926,41 +922,6 @@ export interface RefreshSessionRecord {    norevealIndex?: number;  } -/** - * Wire fee for one wire method as stored in the - * wallet's database. - */ -export interface WireFee { -  /** -   * Fee for wire transfers. -   */ -  wireFee: AmountJson; - -  /** -   * Fees to close and refund a reserve. -   */ -  closingFee: AmountJson; - -  /** -   * Fees for inter-exchange transfers from P2P payments. -   */ -  wadFee: AmountJson; - -  /** -   * Start date of the fee. -   */ -  startStamp: TalerProtocolTimestamp; - -  /** -   * End date of the fee. -   */ -  endStamp: TalerProtocolTimestamp; - -  /** -   * Signature made by the exchange master key. -   */ -  sig: string; -}  export enum RefundState {    Failed = "failed", @@ -1225,9 +1186,9 @@ export const WALLET_BACKUP_STATE_KEY = "walletBackupState";   */  export type ConfigRecord =    | { -      key: typeof WALLET_BACKUP_STATE_KEY; -      value: WalletBackupConfState; -    } +    key: typeof WALLET_BACKUP_STATE_KEY; +    value: WalletBackupConfState; +  }    | { key: "currencyDefaultsApplied"; value: boolean };  export interface WalletBackupConfState { @@ -1444,17 +1405,17 @@ export enum BackupProviderStateTag {  export type BackupProviderState =    | { -      tag: BackupProviderStateTag.Provisional; -    } +    tag: BackupProviderStateTag.Provisional; +  }    | { -      tag: BackupProviderStateTag.Ready; -      nextBackupTimestamp: TalerProtocolTimestamp; -    } +    tag: BackupProviderStateTag.Ready; +    nextBackupTimestamp: TalerProtocolTimestamp; +  }    | { -      tag: BackupProviderStateTag.Retrying; -      retryInfo: RetryInfo; -      lastError?: TalerErrorDetail; -    }; +    tag: BackupProviderStateTag.Retrying; +    retryInfo: RetryInfo; +    lastError?: TalerErrorDetail; +  };  export interface BackupProviderTerms {    supportedProtocolVersion: string; diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts index f26c42770..57d7449e0 100644 --- a/packages/taler-wallet-core/src/operations/backup/import.ts +++ b/packages/taler-wallet-core/src/operations/backup/import.ts @@ -31,6 +31,7 @@ import {    RefreshReason,    TalerProtocolTimestamp,    WalletBackupContentV1, +  WireInfo,  } from "@gnu-taler/taler-util";  import {    AbortStatus, @@ -50,7 +51,6 @@ import {    WalletContractData,    WalletRefundItem,    WalletStoresV1, -  WireInfo,  } from "../../db.js";  import { InternalWalletState } from "../../internal-wallet-state.js";  import { @@ -341,7 +341,7 @@ export async function importBackup(            }            const denomPubHash =              cryptoComp.rsaDenomPubToHash[ -              backupDenomination.denom_pub.rsa_public_key +            backupDenomination.denom_pub.rsa_public_key              ];            checkLogicInvariant(!!denomPubHash);            const existingDenom = await tx.denominations.get([ @@ -427,7 +427,7 @@ export async function importBackup(          } -      // FIXME: import reserves with new schema +        // FIXME: import reserves with new schema          // for (const backupReserve of backupExchangeDetails.reserves) {          //   const reservePub = @@ -560,7 +560,7 @@ export async function importBackup(              const amount = Amounts.parseOrThrow(parsedContractTerms.amount);              const contractTermsHash =                cryptoComp.proposalIdToContractTermsHash[ -                backupProposal.proposal_id +              backupProposal.proposal_id                ];              let maxWireFee: AmountJson;              if (parsedContractTerms.max_wire_fee) { @@ -706,7 +706,7 @@ export async function importBackup(            const amount = Amounts.parseOrThrow(parsedContractTerms.amount);            const contractTermsHash =              cryptoComp.proposalIdToContractTermsHash[ -              backupPurchase.proposal_id +            backupPurchase.proposal_id              ];            let maxWireFee: AmountJson;            if (parsedContractTerms.max_wire_fee) { diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index a016cb8e5..734bc4c2b 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -44,7 +44,7 @@ import {    TrackDepositGroupResponse,    URL,  } from "@gnu-taler/taler-util"; -import { DepositGroupRecord, OperationStatus, WireFee } from "../db.js"; +import { DepositGroupRecord, OperationStatus } from "../db.js";  import { InternalWalletState } from "../internal-wallet-state.js";  import { selectPayCoins } from "../util/coinSelection.js";  import { readSuccessResponseJsonOrThrow } from "../util/http.js"; diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 007dad685..6f8da5aee 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -44,6 +44,9 @@ import {    TalerProtocolDuration,    TalerProtocolTimestamp,    URL, +  WireFee, +  WireFeeMap, +  WireInfo,  } from "@gnu-taler/taler-util";  import {    DenominationRecord, @@ -51,8 +54,6 @@ import {    ExchangeDetailsRecord,    ExchangeRecord,    WalletStoresV1, -  WireFee, -  WireInfo,  } from "../db.js";  import { TalerError } from "../errors.js";  import { InternalWalletState, TrustInfo } from "../internal-wallet-state.js"; @@ -276,7 +277,7 @@ async function validateWireInfo(        throw Error("exchange acct signature invalid");      }    } -  const feesForType: { [wireMethod: string]: WireFee[] } = {}; +  const feesForType: WireFeeMap = {};    for (const wireMethod of Object.keys(wireInfo.fees)) {      const feeList: WireFee[] = [];      for (const x of wireInfo.fees[wireMethod]) { diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 484b9b962..721a043d7 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -241,7 +241,7 @@ export function selectWithdrawalDenominations(    for (const d of denoms) {      let count = 0;      const cost = Amounts.add(d.value, d.feeWithdraw).amount; -    for (;;) { +    for (; ;) {        if (Amounts.cmp(remaining, cost) < 0) {          break;        } @@ -898,8 +898,7 @@ export async function updateWithdrawalDenoms(          denom.verificationStatus === DenominationVerificationStatus.Unverified        ) {          logger.trace( -          `Validating denomination (${current + 1}/${ -            denominations.length +          `Validating denomination (${current + 1}/${denominations.length            }) signature of ${denom.denomPubHash}`,          );          let valid = false; @@ -1026,7 +1025,7 @@ async function queryReserve(      if (        resp.status === 404 &&        result.talerErrorResponse.code === -        TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN +      TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN      ) {        ws.notify({          type: NotificationType.ReserveNotYetFound, @@ -1316,7 +1315,7 @@ export async function getExchangeWithdrawalInfo(      ) {        logger.warn(          `wallet's support for exchange protocol version ${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` + -          `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`, +        `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`,        );      }    } @@ -1395,12 +1394,17 @@ export async function getWithdrawalDetailsForUri(      .mktx((x) => ({        exchanges: x.exchanges,        exchangeDetails: x.exchangeDetails, +      denominations: x.denominations,      }))      .runReadOnly(async (tx) => {        const exchangeRecords = await tx.exchanges.iter().toArray();        for (const r of exchangeRecords) {          const details = await ws.exchangeOps.getExchangeDetails(tx, r.baseUrl); -        if (details) { +        const denominations = await tx.denominations.indexes +          .byExchangeBaseUrl.iter(r.baseUrl).toArray(); +        if (details && denominations) { + +            exchanges.push({              exchangeBaseUrl: details.exchangeBaseUrl,              currency: details.currency, @@ -1411,6 +1415,9 @@ export async function getWithdrawalDetailsForUri(                content: details.termsOfServiceText,              },              paytoUris: details.wireInfo.accounts.map((x) => x.payto_uri), +            auditors: details.auditors, +            wireInfo: details.wireInfo, +            denominations: denominations            });          }        } diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 1b6b56691..593d2e0ff 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -553,6 +553,7 @@ async function getExchanges(      .mktx((x) => ({        exchanges: x.exchanges,        exchangeDetails: x.exchangeDetails, +      denominations: x.denominations,      }))      .runReadOnly(async (tx) => {        const exchangeRecords = await tx.exchanges.iter().toArray(); @@ -567,6 +568,13 @@ async function getExchanges(            continue;          } +        const denominations = await tx.denominations.indexes +          .byExchangeBaseUrl.iter(r.baseUrl).toArray(); + +        if (!denominations) { +          continue; +        } +          exchanges.push({            exchangeBaseUrl: r.baseUrl,            currency, @@ -577,6 +585,9 @@ async function getExchanges(              content: exchangeDetails.termsOfServiceText,            },            paytoUris: exchangeDetails.wireInfo.accounts.map((x) => x.payto_uri), +          auditors: exchangeDetails.auditors, +          wireInfo: exchangeDetails.wireInfo, +          denominations: denominations,          });        }      }); | 
