diff options
Diffstat (limited to 'packages/taler-wallet-core/src/types')
-rw-r--r-- | packages/taler-wallet-core/src/types/ReserveStatus.ts | 57 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/ReserveTransaction.ts | 253 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/backupTypes.ts | 1299 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/cryptoTypes.ts | 141 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/dbTypes.ts | 1775 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/notifications.ts | 271 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/pendingTypes.ts | 288 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/talerTypes.ts | 1457 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/transactionsTypes.ts | 364 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/types-test.ts | 93 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/types/walletTypes.ts | 1026 |
11 files changed, 0 insertions, 7024 deletions
diff --git a/packages/taler-wallet-core/src/types/ReserveStatus.ts b/packages/taler-wallet-core/src/types/ReserveStatus.ts deleted file mode 100644 index 8a6092a7f..000000000 --- a/packages/taler-wallet-core/src/types/ReserveStatus.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2019 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - 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/> - */ - -/** - * @author Florian Dold <dold@taler.net> - */ - -/** - * Imports. - */ -import { - codecForString, - buildCodecForObject, - codecForList, - Codec, -} from "../util/codec"; -import { AmountString } from "./talerTypes"; -import { - ReserveTransaction, - codecForReserveTransaction, -} from "./ReserveTransaction"; - -/** - * Status of a reserve. - * - * Schema type for the exchange's response to "/reserve/status". - */ -export interface ReserveStatus { - /** - * Balance left in the reserve. - */ - balance: AmountString; - - /** - * Transaction history for the reserve. - */ - history: ReserveTransaction[]; -} - -export const codecForReserveStatus = (): Codec<ReserveStatus> => - buildCodecForObject<ReserveStatus>() - .property("balance", codecForString()) - .property("history", codecForList(codecForReserveTransaction())) - .build("ReserveStatus"); diff --git a/packages/taler-wallet-core/src/types/ReserveTransaction.ts b/packages/taler-wallet-core/src/types/ReserveTransaction.ts deleted file mode 100644 index 6847d8376..000000000 --- a/packages/taler-wallet-core/src/types/ReserveTransaction.ts +++ /dev/null @@ -1,253 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2019 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - 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/> - */ - -/** - * Type declarations for the exchange's reserve transaction information. - * - * @author Florian Dold <dold@taler.net> - */ - -/** - * Imports. - */ -import { - codecForString, - buildCodecForObject, - codecForConstString, - buildCodecForUnion, - Codec, - codecForNumber, -} from "../util/codec"; -import { - AmountString, - Base32String, - EddsaSignatureString, - EddsaPublicKeyString, - CoinPublicKeyString, -} from "./talerTypes"; -import { Timestamp, codecForTimestamp } from "../util/time"; - -export enum ReserveTransactionType { - Withdraw = "WITHDRAW", - Credit = "CREDIT", - Recoup = "RECOUP", - Closing = "CLOSING", -} - -export interface ReserveWithdrawTransaction { - type: ReserveTransactionType.Withdraw; - - /** - * Amount withdrawn. - */ - amount: AmountString; - - /** - * Hash of the denomination public key of the coin. - */ - h_denom_pub: Base32String; - - /** - * Hash of the blinded coin to be signed - */ - h_coin_envelope: Base32String; - - /** - * Signature of 'TALER_WithdrawRequestPS' created with the reserves's - * private key. - */ - reserve_sig: EddsaSignatureString; - - /** - * Fee that is charged for withdraw. - */ - withdraw_fee: AmountString; -} - -export interface ReserveCreditTransaction { - type: ReserveTransactionType.Credit; - - /** - * Amount withdrawn. - */ - amount: AmountString; - - /** - * Sender account payto://-URL - */ - sender_account_url: string; - - /** - * Transfer details uniquely identifying the transfer. - */ - wire_reference: number; - - /** - * Timestamp of the incoming wire transfer. - */ - timestamp: Timestamp; -} - -export interface ReserveClosingTransaction { - type: ReserveTransactionType.Closing; - - /** - * Closing balance. - */ - amount: AmountString; - - /** - * Closing fee charged by the exchange. - */ - closing_fee: AmountString; - - /** - * Wire transfer subject. - */ - wtid: string; - - /** - * Hash of the wire account into which the funds were returned to. - */ - h_wire: string; - - /** - * This is a signature over a - * struct TALER_ReserveCloseConfirmationPS with purpose - * TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED. - */ - exchange_sig: EddsaSignatureString; - - /** - * Public key used to create exchange_sig. - */ - exchange_pub: EddsaPublicKeyString; - - /** - * Time when the reserve was closed. - */ - timestamp: Timestamp; -} - -export interface ReserveRecoupTransaction { - type: ReserveTransactionType.Recoup; - - /** - * Amount paid back. - */ - amount: AmountString; - - /** - * This is a signature over - * a struct TALER_PaybackConfirmationPS with purpose - * TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK. - */ - exchange_sig: EddsaSignatureString; - - /** - * Public key used to create exchange_sig. - */ - exchange_pub: EddsaPublicKeyString; - - /** - * Time when the funds were paid back into the reserve. - */ - timestamp: Timestamp; - - /** - * Public key of the coin that was paid back. - */ - coin_pub: CoinPublicKeyString; -} - -/** - * Format of the exchange's transaction history for a reserve. - */ -export type ReserveTransaction = - | ReserveWithdrawTransaction - | ReserveCreditTransaction - | ReserveClosingTransaction - | ReserveRecoupTransaction; - -export const codecForReserveWithdrawTransaction = (): Codec< - ReserveWithdrawTransaction -> => - buildCodecForObject<ReserveWithdrawTransaction>() - .property("amount", codecForString()) - .property("h_coin_envelope", codecForString()) - .property("h_denom_pub", codecForString()) - .property("reserve_sig", codecForString()) - .property("type", codecForConstString(ReserveTransactionType.Withdraw)) - .property("withdraw_fee", codecForString()) - .build("ReserveWithdrawTransaction"); - -export const codecForReserveCreditTransaction = (): Codec< - ReserveCreditTransaction -> => - buildCodecForObject<ReserveCreditTransaction>() - .property("amount", codecForString()) - .property("sender_account_url", codecForString()) - .property("timestamp", codecForTimestamp) - .property("wire_reference", codecForNumber()) - .property("type", codecForConstString(ReserveTransactionType.Credit)) - .build("ReserveCreditTransaction"); - -export const codecForReserveClosingTransaction = (): Codec< - ReserveClosingTransaction -> => - buildCodecForObject<ReserveClosingTransaction>() - .property("amount", codecForString()) - .property("closing_fee", codecForString()) - .property("exchange_pub", codecForString()) - .property("exchange_sig", codecForString()) - .property("h_wire", codecForString()) - .property("timestamp", codecForTimestamp) - .property("type", codecForConstString(ReserveTransactionType.Closing)) - .property("wtid", codecForString()) - .build("ReserveClosingTransaction"); - -export const codecForReserveRecoupTransaction = (): Codec< - ReserveRecoupTransaction -> => - buildCodecForObject<ReserveRecoupTransaction>() - .property("amount", codecForString()) - .property("coin_pub", codecForString()) - .property("exchange_pub", codecForString()) - .property("exchange_sig", codecForString()) - .property("timestamp", codecForTimestamp) - .property("type", codecForConstString(ReserveTransactionType.Recoup)) - .build("ReserveRecoupTransaction"); - -export const codecForReserveTransaction = (): Codec<ReserveTransaction> => - buildCodecForUnion<ReserveTransaction>() - .discriminateOn("type") - .alternative( - ReserveTransactionType.Withdraw, - codecForReserveWithdrawTransaction(), - ) - .alternative( - ReserveTransactionType.Closing, - codecForReserveClosingTransaction(), - ) - .alternative( - ReserveTransactionType.Recoup, - codecForReserveRecoupTransaction(), - ) - .alternative( - ReserveTransactionType.Credit, - codecForReserveCreditTransaction(), - ) - .build<ReserveTransaction>("ReserveTransaction"); diff --git a/packages/taler-wallet-core/src/types/backupTypes.ts b/packages/taler-wallet-core/src/types/backupTypes.ts deleted file mode 100644 index 7e6ceb04c..000000000 --- a/packages/taler-wallet-core/src/types/backupTypes.ts +++ /dev/null @@ -1,1299 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - 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/> - */ - -/** - * Type declarations for the backup content format. - * - * Contains some redundancy with the other type declarations, - * as the backup schema must remain very stable and should be self-contained. - * - * Future: - * 1. Ghost spends (coin unexpectedly spent by a wallet with shared data) - * 2. Ghost withdrawals (reserve unexpectedly emptied by another wallet with shared data) - * 3. Track losses through re-denomination of payments/refreshes - * 4. (Feature:) Payments to own bank account and P2P-payments need to be backed up - * 5. Track last/next update time, so on restore we need to do less work - * 6. Currency render preferences? - * - * Questions: - * 1. What happens when two backups are merged that have - * the same coin in different refresh groups? - * => Both are added, one will eventually fail - * 2. Should we make more information forgettable? I.e. is - * the coin selection still relevant for a purchase after the coins - * are legally expired? - * => Yes, still needs to be implemented - * 3. What about re-denominations / re-selection of payment coins? - * Is it enough to store a clock value for the selection? - * => Coin derivation should also consider denom pub hash - * - * General considerations / decisions: - * 1. Information about previously occurring errors and - * retries is never backed up. - * 2. The ToS text of an exchange is never backed up. - * 3. Derived information is never backed up (hashed values, public keys - * when we know the private key). - * - * @author Florian Dold <dold@taler.net> - */ - -/** - * Imports. - */ -import { Duration, Timestamp } from "../util/time"; - -/** - * Type alias for strings that are to be treated like amounts. - */ -type BackupAmountString = string; - -/** - * A human-recognizable identifier here that is - * reasonable unique and assigned the first time the wallet is - * started/installed, such as: - * - * `${wallet-implementation} ${os} ${hostname} (${short-uid})` - * => e.g. "GNU Taler Android iceking ABC123" - */ -type DeviceIdString = string; - -/** - * Lamport clock timestamp. - */ -export interface ClockStamp { - deviceId: string; - value: number; -} - -/** - * Contract terms JSON. - */ -type RawContractTerms = any; - -/** - * Content of the backup. - * - * The contents of the wallet must be serialized in a deterministic - * way across implementations, so that the normalized backup content - * JSON is identical when the wallet's content is identical. - */ -export interface WalletBackupContentV1 { - /** - * Magic constant to identify that this is a backup content JSON. - */ - schema_id: "gnu-taler-wallet-backup-content"; - - /** - * Version of the schema. - */ - schema_version: 1; - - /** - * Root public key of the wallet. This field is present as - * a sanity check if the backup content JSON is loaded from file. - */ - wallet_root_pub: string; - - /** - * Current device identifier that "owns" the backup. - * - * This identifier allows one wallet to notice when another - * wallet is "alive" and connected to the same sync provider. - */ - current_device_id: DeviceIdString; - - /** - * Monotonically increasing clock of the wallet, - * used to determine causality when merging backups. - * - * Information about other clocks, used to delete - * tombstones in the hopefully rare case that multiple wallets - * are connected to the same sync server. - */ - clocks: { [device_id: string]: number }; - - /** - * Timestamp of the backup. - * - * This timestamp should only be advanced if the content - * of the backup changes. - */ - timestamp: Timestamp; - - /** - * Per-exchange data sorted by exchange master public key. - * - * Sorted by the exchange public key. - */ - exchanges: BackupExchange[]; - - /** - * Grouped refresh sessions. - * - * Sorted by the refresh group ID. - */ - refresh_groups: BackupRefreshGroup[]; - - /** - * Tips. - * - * Sorted by the wallet tip ID. - */ - tips: BackupTip[]; - - /** - * Proposals from merchants. The proposal may - * be deleted as soon as it has been accepted (and thus - * turned into a purchase). - * - * Sorted by the proposal ID. - */ - proposals: BackupProposal[]; - - /** - * Accepted purchases. - * - * Sorted by the proposal ID. - */ - purchases: BackupPurchase[]; - - /** - * All backup providers. - * - * Sorted by the provider base URL. - */ - backup_providers: BackupBackupProvider[]; - - /** - * Recoup groups. - */ - recoup_groups: BackupRecoupGroup[]; - - /** - * Tombstones for deleting purchases. - */ - purchase_tombstones: { - /** - * Clock when the purchase was deleted - */ - clock_deleted: ClockStamp; - - /** - * Proposal ID identifying the purchase. - */ - proposal_id: string; - }[]; - - /** - * Trusted auditors, either for official (3 letter) or local (4-12 letter) - * currencies. - * - * Auditors are sorted by their canonicalized base URL. - */ - trusted_auditors: { [currency: string]: BackupTrustAuditor[] }; - - /** - * Trusted exchange. Only applicable for local currencies (4-12 letter currency code). - * - * Exchanges are sorted by their canonicalized base URL. - */ - trusted_exchanges: { [currency: string]: BackupTrustExchange[] }; - - /** - * Interning table for forgettable values of contract terms. - * - * Used to reduce storage space, as many forgettable items (product image, - * addresses, etc.) might be shared among many contract terms. - */ - intern_table: { [hash: string]: any }; - - /** - * Permanent error reports. - */ - error_reports: BackupErrorReport[]; -} - -/** - * Detailed error report. - * - * For auditor-relevant reports with attached cryptographic proof, - * the error report also should contain the submission status to - * the auditor(s). - */ -interface BackupErrorReport { - // FIXME: specify! -} - -/** - * Trust declaration for an auditor. - * - * The trust applies based on the public key of - * the auditor, irrespective of what base URL the exchange - * is referencing. - */ -export interface BackupTrustAuditor { - /** - * Base URL of the auditor. - */ - auditor_base_url: string; - - /** - * Public key of the auditor. - */ - auditor_pub: string; - - /** - * Clock when the auditor trust has been added. - * - * Can be undefined if this entry represents a removal delta - * from the wallet's defaults. - */ - clock_added?: ClockStamp; - - /** - * Clock for when the auditor trust has been removed. - */ - clock_removed?: ClockStamp; -} - -/** - * Trust declaration for an exchange. - * - * The trust only applies for the combination of base URL - * and public key. If the master public key changes while the base - * URL stays the same, the exchange has to be re-added by a wallet update - * or by the user. - */ -export interface BackupTrustExchange { - /** - * Canonicalized exchange base URL. - */ - exchange_base_url: string; - - /** - * Master public key of the exchange. - */ - exchange_master_pub: string; - - /** - * Clock when the exchange trust has been added. - * - * Can be undefined if this entry represents a removal delta - * from the wallet's defaults. - */ - clock_added?: ClockStamp; - - /** - * Clock for when the exchange trust has been removed. - */ - clock_removed?: ClockStamp; -} - -export class BackupBackupProviderTerms { - /** - * Last known supported protocol version. - */ - supported_protocol_version: string; - - /** - * Last known annual fee. - */ - annual_fee: BackupAmountString; - - /** - * Last known storage limit. - */ - storage_limit_in_megabytes: number; -} - -/** - * Backup information about one backup storage provider. - */ -export class BackupBackupProvider { - /** - * Canonicalized base URL of the provider. - */ - base_url: string; - - /** - * Last known terms. Might be unavailable in some situations, such - * as directly after restoring form a backup recovery document. - */ - terms?: BackupBackupProviderTerms; - - /** - * Proposal IDs for payments to this provider. - */ - pay_proposal_ids: string[]; -} - -/** - * Status of recoup operations that were grouped together. - * - * The remaining amount of the corresponding coins must be set to - * zero when the recoup group is created/imported. - */ -export interface BackupRecoupGroup { - /** - * Unique identifier for the recoup group record. - */ - recoup_group_id: string; - - /** - * Timestamp when the recoup was started. - */ - timestamp_created: Timestamp; - - timestamp_finish?: Timestamp; - finish_clock?: Timestamp; - finish_is_failure?: boolean; - - /** - * Information about each coin being recouped. - */ - coins: { - coin_pub: string; - recoup_finished: boolean; - old_amount: BackupAmountString; - }[]; -} - -/** - * Types of coin sources. - */ -export enum BackupCoinSourceType { - Withdraw = "withdraw", - Refresh = "refresh", - Tip = "tip", -} - -/** - * Metadata about a coin obtained via withdrawing. - */ -export interface BackupWithdrawCoinSource { - type: BackupCoinSourceType.Withdraw; - - /** - * Can be the empty string for orphaned coins. - */ - withdrawal_group_id: string; - - /** - * Index of the coin in the withdrawal session. - */ - coin_index: number; - - /** - * Reserve public key for the reserve we got this coin from. - */ - reserve_pub: string; -} - -/** - * Metadata about a coin obtained from refreshing. - * - * FIXME: Currently does not link to the refreshGroupId because - * the wallet DB doesn't do this. Not really necessary, - * but would be more consistent. - */ -export interface BackupRefreshCoinSource { - type: BackupCoinSourceType.Refresh; - - /** - * Public key of the coin that was refreshed into this coin. - */ - old_coin_pub: string; -} - -/** - * Metadata about a coin obtained from a tip. - */ -export interface BackupTipCoinSource { - type: BackupCoinSourceType.Tip; - - /** - * Wallet's identifier for the tip that this coin - * originates from. - */ - wallet_tip_id: string; - - /** - * Index in the tip planchets of the tip. - */ - coin_index: number; -} - -/** - * Metadata about a coin depending on the origin. - */ -export type BackupCoinSource = - | BackupWithdrawCoinSource - | BackupRefreshCoinSource - | BackupTipCoinSource; - -/** - * Backup information about a coin. - * - * (Always part of a BackupExchange/BackupDenom) - */ -export interface BackupCoin { - /** - * Where did the coin come from? Used for recouping coins. - */ - coin_source: BackupCoinSource; - - /** - * Private key to authorize operations on the coin. - */ - coin_priv: string; - - /** - * Unblinded signature by the exchange. - */ - denom_sig: string; - - /** - * Amount that's left on the coin. - */ - current_amount: BackupAmountString; - - /** - * Blinding key used when withdrawing the coin. - * Potentionally used again during payback. - */ - blinding_key: string; - - /** - * Does the wallet think that the coin is still fresh? - * - * Note that even if a fresh coin is imported, it should still - * be refreshed in most situations. - */ - fresh: boolean; - - /** - * Clock for the last update to current_amount/fresh. - */ - last_clock?: ClockStamp; -} - -/** - * Status of a tip we got from a merchant. - */ -export interface BackupTip { - /** - * Tip ID chosen by the wallet. - */ - wallet_tip_id: string; - - /** - * The merchant's identifier for this tip. - */ - merchant_tip_id: string; - - /** - * Secret seed used for the tipping planchets. - */ - secret_seed: string; - - /** - * Has the user accepted the tip? Only after the tip has been accepted coins - * withdrawn from the tip may be used. - */ - timestamp_accepted: Timestamp | undefined; - - /** - * When was the tip first scanned by the wallet? - */ - timestamp_created: Timestamp; - - timestamp_finished?: Timestamp; - finish_clock?: ClockStamp; - finish_is_failure?: boolean; - - /** - * The tipped amount. - */ - tip_amount_raw: BackupAmountString; - - /** - * Timestamp, the tip can't be picked up anymore after this deadline. - */ - timestamp_expiration: Timestamp; - - /** - * The exchange that will sign our coins, chosen by the merchant. - */ - exchange_base_url: string; - - /** - * Base URL of the merchant that is giving us the tip. - */ - merchant_base_url: string; - - /** - * Selected denominations. Determines the effective tip amount. - */ - selected_denoms: BackupDenomSel; - - selected_denoms_clock?: ClockStamp; -} - -/** - * Reasons for why a coin is being refreshed. - */ -export enum BackupRefreshReason { - Manual = "manual", - Pay = "pay", - Refund = "refund", - AbortPay = "abort-pay", - Recoup = "recoup", - BackupRestored = "backup-restored", - Scheduled = "scheduled", -} - -/** - * Information about one refresh session, always part - * of a refresh group. - * - * (Public key of the old coin is stored in the refresh group.) - */ -export interface BackupRefreshSession { - /** - * Hashed denominations of the newly requested coins. - */ - new_denoms: BackupDenomSel; - - /** - * Seed used to derive the planchets and - * transfer private keys for this refresh session. - */ - session_secret_seed: string; - - /** - * The no-reveal-index after we've done the melting. - */ - noreveal_index?: number; -} - -/** - * Refresh session for one coin inside a refresh group. - */ -export interface BackupRefreshOldCoin { - /** - * Public key of the old coin, - */ - coin_pub: string; - - /** - * Requested amount to refresh. Must be subtracted from the coin's remaining - * amount as soon as the coin is added to the refresh group. - */ - input_amount: BackupAmountString; - - /** - * Estimated output (may change if it takes a long time to create the - * actual session). - */ - estimated_output_amount: BackupAmountString; - - /** - * Did the refresh session finish (or was it unnecessary/impossible to create - * one) - */ - finished: boolean; - - /** - * Refresh session (if created) or undefined it not created yet. - */ - refresh_session: BackupRefreshSession | undefined; -} - -/** - * Information about one refresh group. - * - * May span more than one exchange, but typically doesn't - */ -export interface BackupRefreshGroup { - refresh_group_id: string; - - reason: BackupRefreshReason; - - /** - * Details per old coin. - */ - old_coins: BackupRefreshOldCoin[]; - - timestamp_created: Timestamp; - - timestamp_finish?: Timestamp; - finish_clock?: ClockStamp; - finish_is_failure?: boolean; -} - -/** - * Backup information for a withdrawal group. - * - * Always part of a BackupReserve. - */ -export interface BackupWithdrawalGroup { - withdrawal_group_id: string; - - /** - * Secret seed to derive the planchets. - */ - secret_seed: string; - - /** - * When was the withdrawal operation started started? - * Timestamp in milliseconds. - */ - timestamp_created: Timestamp; - - timestamp_finish?: Timestamp; - finish_clock?: ClockStamp; - finish_is_failure?: boolean; - - /** - * Amount including fees (i.e. the amount subtracted from the - * reserve to withdraw all coins in this withdrawal session). - * - * Note that this *includes* the amount remaining in the reserve - * that is too small to be withdrawn, and thus can't be derived - * from selectedDenoms. - */ - raw_withdrawal_amount: BackupAmountString; - - /** - * Multiset of denominations selected for withdrawal. - */ - selected_denoms: BackupDenomSel; - - selected_denoms_clock?: ClockStamp; -} - -export enum BackupRefundState { - Failed = "failed", - Applied = "applied", - Pending = "pending", -} - -/** - * Common information about a refund. - */ -export interface BackupRefundItemCommon { - /** - * Execution time as claimed by the merchant - */ - execution_time: Timestamp; - - /** - * Time when the wallet became aware of the refund. - */ - obtained_time: Timestamp; - - /** - * Amount refunded for the coin. - */ - refund_amount: BackupAmountString; - - /** - * Coin being refunded. - */ - coin_pub: string; - - /** - * The refund transaction ID for the refund. - */ - rtransaction_id: number; - - /** - * Upper bound on the refresh cost incurred by - * applying this refund. - * - * Might be lower in practice when two refunds on the same - * coin are refreshed in the same refresh operation. - * - * Used to display fees, and stored since it's expensive to recompute - * accurately. - */ - total_refresh_cost_bound: BackupAmountString; - - last_clock?: ClockStamp; -} - -/** - * Failed refund, either because the merchant did - * something wrong or it expired. - */ -export interface BackupRefundFailedItem extends BackupRefundItemCommon { - type: BackupRefundState.Failed; -} - -export interface BackupRefundPendingItem extends BackupRefundItemCommon { - type: BackupRefundState.Pending; -} - -export interface BackupRefundAppliedItem extends BackupRefundItemCommon { - type: BackupRefundState.Applied; -} - -/** - * State of one refund from the merchant, maintained by the wallet. - */ -export type BackupRefundItem = - | BackupRefundFailedItem - | BackupRefundPendingItem - | BackupRefundAppliedItem; - -export interface BackupPurchase { - /** - * Proposal ID for this purchase. Uniquely identifies the - * purchase and the proposal. - */ - proposal_id: string; - - /** - * Contract terms we got from the merchant. - */ - contract_terms_raw: RawContractTerms; - - /** - * Signature on the contract terms. - */ - merchant_sig: string; - - /** - * Private key for the nonce. Might eventually be used - * to prove ownership of the contract. - */ - nonce_priv: string; - - pay_coins: { - /** - * Public keys of the coins that were selected. - */ - coin_pub: string; - - /** - * Amount that each coin contributes. - */ - contribution: BackupAmountString; - }[]; - - /** - * Clock when the pay coin selection was made/updated. - */ - pay_coins_clock?: ClockStamp; - - /** - * Total cost initially shown to the user. - * - * This includes the amount taken by the merchant, fees (wire/deposit) contributed - * by the customer, refreshing fees, fees for withdraw-after-refresh and "trimmings" - * of coins that are too small to spend. - * - * Note that in rare situations, this cost might not be accurate (e.g. - * when the payment or refresh gets re-denominated). - * We might show adjustments to this later, but currently we don't do so. - */ - total_pay_cost: BackupAmountString; - - /** - * Timestamp of the first time that sending a payment to the merchant - * for this purchase was successful. - */ - timestamp_first_successful_pay: Timestamp | undefined; - - /** - * Signature by the merchant confirming the payment. - */ - merchant_pay_sig: string | undefined; - - /** - * When was the purchase made? - * Refers to the time that the user accepted. - */ - timestamp_accept: Timestamp; - - /** - * Pending refunds for the purchase. A refund is pending - * when the merchant reports a transient error from the exchange. - */ - refunds: BackupRefundItem[]; - - /** - * Is the purchase considered defunct (either during payment - * or during abort if abort_status is set). - */ - defunct?: boolean; - - /** - * Clock for last update to defunct status. - */ - defunct_clock?: ClockStamp; - - /** - * Abort status of the payment. - */ - abort_status?: "abort-refund" | "abort-finished"; - - /** - * Continue querying the refund status until this deadline has expired. - */ - auto_refund_deadline: Timestamp | undefined; -} - -/** - * Info about one denomination in the backup. - * - * Note that the wallet only backs up validated denominations. - */ -export interface BackupDenomination { - /** - * Value of one coin of the denomination. - */ - value: BackupAmountString; - - /** - * The denomination public key. - */ - denom_pub: string; - - /** - * Fee for withdrawing. - */ - fee_withdraw: BackupAmountString; - - /** - * Fee for depositing. - */ - fee_deposit: BackupAmountString; - - /** - * Fee for refreshing. - */ - fee_refresh: BackupAmountString; - - /** - * Fee for refunding. - */ - fee_refund: BackupAmountString; - - /** - * Validity start date of the denomination. - */ - stamp_start: Timestamp; - - /** - * Date after which the currency can't be withdrawn anymore. - */ - stamp_expire_withdraw: Timestamp; - - /** - * Date after the denomination officially doesn't exist anymore. - */ - stamp_expire_legal: Timestamp; - - /** - * Data after which coins of this denomination can't be deposited anymore. - */ - stamp_expire_deposit: Timestamp; - - /** - * Signature by the exchange's master key over the denomination - * information. - */ - master_sig: string; - - /** - * Was this denomination still offered by the exchange the last time - * we checked? - * Only false when the exchange redacts a previously published denomination. - */ - is_offered: boolean; - - /** - * Did the exchange revoke the denomination? - * When this field is set to true in the database, the same transaction - * should also mark all affected coins as revoked. - */ - is_revoked: boolean; - - /** - * Coins of this denomination. - */ - coins: BackupCoin[]; -} - -/** - * Denomination selection. - */ -export type BackupDenomSel = { - denom_pub_hash: string; - count: number; -}[]; - -export interface BackupReserve { - /** - * The reserve private key. - */ - reserve_priv: string; - - /** - * Time when the reserve was created. - */ - timestamp_created: Timestamp; - - /** - * Timestamp of the last observed activity. - * - * Used to compute when to give up querying the exchange. - */ - timestamp_last_activity: Timestamp; - - /** - * Timestamp of when the reserve closed. - * - * Note that the last activity can be after the closing time - * due to recouping. - */ - timestamp_closed?: Timestamp; - - /** - * Wire information (as payto URI) for the bank account that - * transfered funds for this reserve. - */ - sender_wire?: string; - - /** - * Amount that was sent by the user to fund the reserve. - */ - instructed_amount: BackupAmountString; - - /** - * Extra state for when this is a withdrawal involving - * a Taler-integrated bank. - */ - bank_info?: { - /** - * Status URL that the wallet will use to query the status - * of the Taler withdrawal operation on the bank's side. - */ - status_url: string; - - /** - * URL that the user should be instructed to navigate to - * in order to confirm the transfer (or show instructions/help - * on how to do that at a PoS terminal). - */ - confirm_url?: string; - - /** - * Exchange payto URI that the bank will use to fund the reserve. - */ - exchange_payto_uri: string; - - /** - * Time when the information about this reserve was posted to the bank. - */ - timestamp_reserve_info_posted: Timestamp | undefined; - - /** - * Time when the reserve was confirmed by the bank. - * - * Set to undefined if not confirmed yet. - */ - timestamp_bank_confirmed: Timestamp | undefined; - }; - - /** - * Pre-allocated withdrawal group ID that will be - * used for the first withdrawal. - * - * (Already created so it can be referenced in the transactions list - * before it really exists, as there'll be an entry for the withdrawal - * even before the withdrawal group really has been created). - */ - initial_withdrawal_group_id: string; - - /** - * Denominations selected for the initial withdrawal. - * Stored here to show costs before withdrawal has begun. - */ - initial_selected_denoms: BackupDenomSel; - - /** - * Groups of withdrawal operations for this reserve. Typically just one. - */ - withdrawal_groups: BackupWithdrawalGroup[]; - - defective?: boolean; - defective_clock?: ClockStamp; -} - -/** - * Wire fee for one wire payment target type as stored in the - * wallet's database. - * - * (Flattened to a list to make the declaration simpler). - */ -export interface BackupExchangeWireFee { - wire_type: string; - - /** - * Fee for wire transfers. - */ - wire_fee: string; - - /** - * Fees to close and refund a reserve. - */ - closing_fee: string; - - /** - * Start date of the fee. - */ - start_stamp: Timestamp; - - /** - * End date of the fee. - */ - end_stamp: Timestamp; - - /** - * Signature made by the exchange master key. - */ - sig: string; -} - -/** - * Structure of one exchange signing key in the /keys response. - */ -export class BackupExchangeSignKey { - stamp_start: Timestamp; - stamp_expire: Timestamp; - stamp_end: Timestamp; - key: string; - master_sig: string; -} - -/** - * Signature by the auditor that a particular denomination key is audited. - */ -export class AuditorDenomSig { - /** - * Denomination public key's hash. - */ - denom_pub_h: string; - - /** - * The signature. - */ - auditor_sig: string; -} - -/** - * Auditor information as given by the exchange in /keys. - */ -export class BackupExchangeAuditor { - /** - * Auditor's public key. - */ - auditor_pub: string; - - /** - * Base URL of the auditor. - */ - auditor_url: string; - - /** - * List of signatures for denominations by the auditor. - */ - denomination_keys: AuditorDenomSig[]; -} - -/** - * Backup information about an exchange. - */ -export interface BackupExchange { - /** - * Canonicalized base url of the exchange. - */ - base_url: string; - - /** - * Master public key of the exchange. - */ - master_public_key: string; - - /** - * Auditors (partially) auditing the exchange. - */ - auditors: BackupExchangeAuditor[]; - - /** - * Currency that the exchange offers. - */ - currency: string; - - /** - * Denominations offered by the exchange. - */ - denominations: BackupDenomination[]; - - /** - * Reserves at the exchange. - */ - reserves: BackupReserve[]; - - /** - * Last observed protocol version. - */ - protocol_version: string; - - /** - * Closing delay of reserves. - */ - reserve_closing_delay: Duration; - - /** - * Signing keys we got from the exchange, can also contain - * older signing keys that are not returned by /keys anymore. - */ - signing_keys: BackupExchangeSignKey[]; - - wire_fees: BackupExchangeWireFee[]; - - /** - * Bank accounts offered by the exchange; - */ - accounts: { - payto_uri: string; - master_sig: string; - }[]; - - /** - * ETag for last terms of service download. - */ - tos_etag_last: string | undefined; - - /** - * ETag for last terms of service download. - */ - tos_etag_accepted: string | undefined; - - /** - * Clock value of the last update. - */ - last_clock?: ClockStamp; - - /** - * Should this exchange be considered defective? - */ - defective?: boolean; - - defective_clock?: ClockStamp; -} - -export enum BackupProposalStatus { - /** - * Proposed (and either downloaded or not, - * depending on whether contract terms are present), - * but the user needs to accept/reject it. - */ - Proposed = "proposed", - /** - * The user has rejected the proposal. - */ - Refused = "refused", - /** - * Downloading or processing the proposal has failed permanently. - * - * FIXME: Should this be modeled as a "misbehavior report" instead? - */ - PermanentlyFailed = "permanently-failed", - /** - * Downloaded proposal was detected as a re-purchase. - */ - Repurchase = "repurchase", -} - -/** - * Proposal by a merchant. - */ -export interface BackupProposal { - /** - * Base URL of the merchant that proposed the purchase. - */ - merchant_base_url: string; - - /** - * Downloaded data from the merchant. - */ - contract_terms_raw?: RawContractTerms; - - /** - * Signature on the contract terms. - * - * Must be present if contract_terms_raw is present. - */ - merchant_sig?: string; - - /** - * Unique ID when the order is stored in the wallet DB. - */ - proposal_id: string; - - /** - * Merchant-assigned order ID of the proposal. - */ - order_id: string; - - /** - * Timestamp of when the record - * was created. - */ - timestamp: Timestamp; - - /** - * Private key for the nonce. - */ - nonce_priv: string; - - /** - * Claim token initially given by the merchant. - */ - claim_token: string | undefined; - - /** - * Status of the proposal. - */ - proposal_status: BackupProposalStatus; - - proposal_status_clock?: ClockStamp; - - /** - * Proposal that this one got "redirected" to as part of - * the repurchase detection. - */ - repurchase_proposal_id: string | undefined; - - /** - * Session ID we got when downloading the contract. - */ - download_session_id?: string; -} diff --git a/packages/taler-wallet-core/src/types/cryptoTypes.ts b/packages/taler-wallet-core/src/types/cryptoTypes.ts deleted file mode 100644 index 9b67b5963..000000000 --- a/packages/taler-wallet-core/src/types/cryptoTypes.ts +++ /dev/null @@ -1,141 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * Types used by the wallet crypto worker. - * - * These types are defined in a separate file make tree shaking easier, since - * some components use these types (via RPC) but do not depend on the wallet - * code directly. - * - * @author Florian Dold <dold@taler.net> - */ - -/** - * Imports. - */ -import { AmountJson } from "../util/amounts"; - -export interface RefreshNewDenomInfo { - count: number; - value: AmountJson; - feeWithdraw: AmountJson; - denomPub: string; -} - -/** - * Request to derive a refresh session from the refresh session - * secret seed. - */ -export interface DeriveRefreshSessionRequest { - sessionSecretSeed: string; - kappa: number; - meltCoinPub: string; - meltCoinPriv: string; - meltCoinDenomPubHash: string; - newCoinDenoms: RefreshNewDenomInfo[]; - feeRefresh: AmountJson; -} - -/** - * - */ -export interface DerivedRefreshSession { - /** - * Public key that's being melted in this session. - */ - meltCoinPub: string; - - /** - * Signature to confirm the melting. - */ - confirmSig: string; - - /** - * Planchets for each cut-and-choose instance. - */ - planchetsForGammas: { - /** - * Public key for the coin. - */ - publicKey: string; - - /** - * Private key for the coin. - */ - privateKey: string; - - /** - * Blinded public key. - */ - coinEv: string; - - /** - * Hash of the blinded public key. - */ - coinEvHash: string; - - /** - * Blinding key used. - */ - blindingKey: string; - }[][]; - - /** - * The transfer keys, kappa of them. - */ - transferPubs: string[]; - - /** - * Private keys for the transfer public keys. - */ - transferPrivs: string[]; - - /** - * Hash of the session. - */ - hash: string; - - /** - * Exact value that is being melted. - */ - meltValueWithFee: AmountJson; -} - -export interface DeriveTipRequest { - secretSeed: string; - denomPub: string; - planchetIndex: number; -} - -/** - * Tipping planchet stored in the database. - */ -export interface DerivedTipPlanchet { - blindingKey: string; - coinEv: string; - coinEvHash: string; - coinPriv: string; - coinPub: string; -} - -export interface SignTrackTransactionRequest { - contractTermsHash: string; - wireHash: string; - coinPub: string; - merchantPriv: string; - merchantPub: string; -} diff --git a/packages/taler-wallet-core/src/types/dbTypes.ts b/packages/taler-wallet-core/src/types/dbTypes.ts deleted file mode 100644 index 689055df8..000000000 --- a/packages/taler-wallet-core/src/types/dbTypes.ts +++ /dev/null @@ -1,1775 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2018-2020 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - 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/> - */ - -/** - * Types for records stored in the wallet's database. - * - * Types for the objects in the database should end in "-Record". - */ - -/** - * Imports. - */ -import { AmountJson } from "../util/amounts"; -import { - Auditor, - CoinDepositPermission, - ExchangeSignKeyJson, - MerchantInfo, - Product, - InternationalizedString, - AmountString, - ContractTerms, -} from "./talerTypes"; - -import { Index, Store } from "../util/query"; -import { TalerErrorDetails, RefreshReason } from "./walletTypes"; -import { ReserveTransaction } from "./ReserveTransaction"; -import { Timestamp, Duration } from "../util/time"; -import { IDBKeyPath } from "@gnu-taler/idb-bridge"; -import { RetryInfo } from "../util/retries"; -import { PayCoinSelection } from "../util/coinSelection"; - -export enum ReserveRecordStatus { - /** - * Reserve must be registered with the bank. - */ - REGISTERING_BANK = "registering-bank", - - /** - * We've registered reserve's information with the bank - * and are now waiting for the user to confirm the withdraw - * with the bank (typically 2nd factor auth). - */ - WAIT_CONFIRM_BANK = "wait-confirm-bank", - - /** - * Querying reserve status with the exchange. - */ - QUERYING_STATUS = "querying-status", - - /** - * The corresponding withdraw record has been created. - * No further processing is done, unless explicitly requested - * by the user. - */ - DORMANT = "dormant", - - /** - * The bank aborted the withdrawal. - */ - BANK_ABORTED = "bank-aborted", -} - -export interface ReserveBankInfo { - /** - * Status URL that the wallet will use to query the status - * of the Taler withdrawal operation on the bank's side. - */ - statusUrl: string; - - confirmUrl?: string; - - /** - * Exchange payto URI that the bank will use to fund the reserve. - */ - exchangePaytoUri: string; -} - -/** - * A reserve record as stored in the wallet's database. - */ -export interface ReserveRecord { - /** - * The reserve public key. - */ - reservePub: string; - - /** - * The reserve private key. - */ - reservePriv: string; - - /** - * The exchange base URL. - */ - exchangeBaseUrl: string; - - /** - * Currency of the reserve. - */ - currency: string; - - /** - * Time when the reserve was created. - */ - timestampCreated: Timestamp; - - /** - * Time when the information about this reserve was posted to the bank. - * - * Only applies if bankWithdrawStatusUrl is defined. - * - * Set to 0 if that hasn't happened yet. - */ - timestampReserveInfoPosted: Timestamp | undefined; - - /** - * Time when the reserve was confirmed by the bank. - * - * Set to undefined if not confirmed yet. - */ - timestampBankConfirmed: Timestamp | undefined; - - /** - * Wire information (as payto URI) for the bank account that - * transfered funds for this reserve. - */ - senderWire?: string; - - /** - * Amount that was sent by the user to fund the reserve. - */ - instructedAmount: AmountJson; - - /** - * Extra state for when this is a withdrawal involving - * a Taler-integrated bank. - */ - bankInfo?: ReserveBankInfo; - - initialWithdrawalGroupId: string; - - /** - * Did we start the first withdrawal for this reserve? - * - * We only report a pending withdrawal for the reserve before - * the first withdrawal has started. - */ - initialWithdrawalStarted: boolean; - - /** - * Initial denomination selection, stored here so that - * we can show this information in the transactions/balances - * before we have a withdrawal group. - */ - initialDenomSel: DenomSelectionState; - - reserveStatus: ReserveRecordStatus; - - /** - * Was a reserve query requested? If so, query again instead - * of going into dormant status. - */ - requestedQuery: boolean; - - /** - * Time of the last successful status query. - */ - lastSuccessfulStatusQuery: Timestamp | undefined; - - /** - * Retry info. This field is present even if no retry is scheduled, - * because we need it to be present for the index on the object store - * to work. - */ - retryInfo: RetryInfo; - - /** - * Last error that happened in a reserve operation - * (either talking to the bank or the exchange). - */ - lastError: TalerErrorDetails | undefined; -} - -/** - * Auditor record as stored with currencies in the exchange database. - */ -export interface AuditorRecord { - /** - * Base url of the auditor. - */ - baseUrl: string; - - /** - * Public signing key of the auditor. - */ - auditorPub: string; - - /** - * Time when the auditing expires. - */ - expirationStamp: number; -} - -/** - * Exchange for currencies as stored in the wallet's currency - * information database. - */ -export interface ExchangeForCurrencyRecord { - /** - * FIXME: unused? - */ - exchangeMasterPub: string; - - /** - * Base URL of the exchange. - */ - exchangeBaseUrl: string; -} - -/** - * Information about a currency as displayed in the wallet's database. - */ -export interface CurrencyRecord { - /** - * Name of the currency. - */ - name: string; - - /** - * Number of fractional digits to show when rendering the currency. - */ - fractionalDigits: number; - - /** - * Auditors that the wallet trusts for this currency. - */ - auditors: AuditorRecord[]; - - /** - * Exchanges that the wallet trusts for this currency. - */ - exchanges: ExchangeForCurrencyRecord[]; -} - -/** - * Status of a denomination. - */ -export enum DenominationStatus { - /** - * Verification was delayed. - */ - Unverified = "unverified", - /** - * Verified as valid. - */ - VerifiedGood = "verified-good", - /** - * Verified as invalid. - */ - VerifiedBad = "verified-bad", -} - -/** - * Denomination record as stored in the wallet's database. - */ -export interface DenominationRecord { - /** - * Value of one coin of the denomination. - */ - value: AmountJson; - - /** - * The denomination public key. - */ - denomPub: string; - - /** - * Hash of the denomination public key. - * Stored in the database for faster lookups. - */ - 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: Timestamp; - - /** - * Date after which the currency can't be withdrawn anymore. - */ - stampExpireWithdraw: Timestamp; - - /** - * Date after the denomination officially doesn't exist anymore. - */ - stampExpireLegal: Timestamp; - - /** - * Data after which coins of this denomination can't be deposited anymore. - */ - stampExpireDeposit: Timestamp; - - /** - * Signature by the exchange's master key over the denomination - * information. - */ - masterSig: string; - - /** - * Did we verify the signature on the denomination? - * - * FIXME: Rename to "verificationStatus"? - */ - status: DenominationStatus; - - /** - * Was this denomination still offered by the exchange the last time - * we checked? - * Only false when the exchange redacts a previously published denomination. - */ - isOffered: boolean; - - /** - * Did the exchange revoke the denomination? - * When this field is set to true in the database, the same transaction - * should also mark all affected coins as revoked. - */ - isRevoked: boolean; - - /** - * Base URL of the exchange. - */ - exchangeBaseUrl: string; -} - -/** - * Details about the exchange that we only know after - * querying /keys and /wire. - */ -export interface ExchangeDetails { - /** - * Master public key of the exchange. - */ - masterPublicKey: string; - - /** - * Auditors (partially) auditing the exchange. - */ - auditors: Auditor[]; - - /** - * Currency that the exchange offers. - */ - currency: string; - - /** - * Last observed protocol version. - */ - protocolVersion: string; - - reserveClosingDelay: Duration; - - /** - * Signing keys we got from the exchange, can also contain - * older signing keys that are not returned by /keys anymore. - */ - signingKeys: ExchangeSignKeyJson[]; - - /** - * Timestamp for last update. - */ - lastUpdateTime: Timestamp; - - /** - * When should we next update the information about the exchange? - */ - nextUpdateTime: Timestamp; -} - -export enum ExchangeUpdateStatus { - FetchKeys = "fetch-keys", - FetchWire = "fetch-wire", - FetchTerms = "fetch-terms", - FinalizeUpdate = "finalize-update", - Finished = "finished", -} - -export interface ExchangeBankAccount { - payto_uri: string; - master_sig: string; -} - -export interface ExchangeWireInfo { - feesForType: { [wireMethod: string]: WireFee[] }; - accounts: ExchangeBankAccount[]; -} - -export enum ExchangeUpdateReason { - Initial = "initial", - Forced = "forced", - Scheduled = "scheduled", -} - -/** - * Exchange record as stored in the wallet's database. - */ -export interface ExchangeRecord { - /** - * Base url of the exchange. - */ - baseUrl: string; - - /** - * Did we finish adding the exchange? - */ - addComplete: boolean; - - /** - * Is this a permanent or temporary exchange record? - */ - permanent: boolean; - - /** - * Was the exchange added as a built-in exchange? - */ - builtIn: boolean; - - /** - * Details, once known. - */ - details: ExchangeDetails | undefined; - - /** - * Mapping from wire method type to the wire fee. - */ - wireInfo: ExchangeWireInfo | undefined; - - /** - * Terms of service text or undefined if not downloaded yet. - * - * This is just used as a cache of the last downloaded ToS. - */ - termsOfServiceText: string | undefined; - - /** - * ETag for last terms of service download. - */ - termsOfServiceLastEtag: string | undefined; - - /** - * ETag for last terms of service download. - */ - termsOfServiceAcceptedEtag: string | undefined; - - /** - * Time when the update to the exchange has been started or - * undefined if no update is in progress. - */ - updateStarted: Timestamp | undefined; - - /** - * Status of updating the info about the exchange. - */ - updateStatus: ExchangeUpdateStatus; - - updateReason?: ExchangeUpdateReason; - - lastError?: TalerErrorDetails; - - /** - * Retry status for fetching updated information about the exchange. - */ - retryInfo: RetryInfo; - - /** - * Next time that we should check if coins need to be refreshed. - * - * Updated whenever the exchange's denominations are updated or when - * the refresh check has been done. - */ - nextRefreshCheck?: Timestamp; -} - -/** - * A coin that isn't yet signed by an exchange. - */ -export interface PlanchetRecord { - /** - * Public key of the coin. - */ - coinPub: string; - - /** - * Private key of the coin. - */ - coinPriv: string; - - /** - * Withdrawal group that this planchet belongs to - * (or the empty string). - */ - withdrawalGroupId: string; - - /** - * Index within the withdrawal group (or -1). - */ - coinIdx: number; - - withdrawalDone: boolean; - - lastError: TalerErrorDetails | undefined; - - /** - * Public key of the reserve that this planchet - * is being withdrawn from. - * - * Can be the empty string (non-null/undefined for DB indexing) - * if this is a tipping reserve. - */ - reservePub: string; - - denomPubHash: string; - - denomPub: string; - - blindingKey: string; - - withdrawSig: string; - - coinEv: string; - - coinEvHash: string; - - coinValue: AmountJson; - - isFromTip: boolean; -} - -/** - * Planchet for a coin during refrehs. - */ -export interface RefreshPlanchet { - /** - * Public key for the coin. - */ - publicKey: string; - - /** - * Private key for the coin. - */ - privateKey: string; - - /** - * Blinded public key. - */ - coinEv: string; - - coinEvHash: string; - - /** - * Blinding key used. - */ - blindingKey: string; -} - -/** - * Status of a coin. - */ -export enum CoinStatus { - /** - * Withdrawn and never shown to anybody. - */ - Fresh = "fresh", - /** - * A coin that has been spent and refreshed. - */ - Dormant = "dormant", -} - -export enum CoinSourceType { - Withdraw = "withdraw", - Refresh = "refresh", - Tip = "tip", -} - -export interface WithdrawCoinSource { - type: CoinSourceType.Withdraw; - - /** - * Can be the empty string for orphaned coins. - */ - withdrawalGroupId: string; - - /** - * Index of the coin in the withdrawal session. - */ - coinIndex: number; - - /** - * Reserve public key for the reserve we got this coin from. - */ - reservePub: string; -} - -export interface RefreshCoinSource { - type: CoinSourceType.Refresh; - oldCoinPub: string; -} - -export interface TipCoinSource { - type: CoinSourceType.Tip; - walletTipId: string; - coinIndex: number; -} - -export type CoinSource = WithdrawCoinSource | RefreshCoinSource | TipCoinSource; - -/** - * CoinRecord as stored in the "coins" data store - * of the wallet database. - */ -export interface CoinRecord { - /** - * Where did the coin come from? Used for recouping coins. - */ - coinSource: CoinSource; - - /** - * Public key of the coin. - */ - coinPub: string; - - /** - * Private key to authorize operations on the coin. - */ - coinPriv: string; - - /** - * Key used by the exchange used to sign the coin. - */ - denomPub: string; - - /** - * Hash of the public key that signs the coin. - */ - denomPubHash: string; - - /** - * Unblinded signature by the exchange. - */ - denomSig: string; - - /** - * Amount that's left on the coin. - */ - currentAmount: AmountJson; - - /** - * Base URL that identifies the exchange from which we got the - * coin. - */ - exchangeBaseUrl: string; - - /** - * The coin is currently suspended, and will not be used for payments. - */ - suspended: boolean; - - /** - * Blinding key used when withdrawing the coin. - * Potentionally used again during payback. - */ - blindingKey: string; - - /** - * Hash of the coin envelope. - * - * Stored here for indexing purposes, so that when looking at a - * reserve history, we can quickly find the coin for a withdrawal transaction. - */ - coinEvHash: string; - - /** - * Status of the coin. - */ - status: CoinStatus; -} - -export enum ProposalStatus { - /** - * Not downloaded yet. - */ - DOWNLOADING = "downloading", - /** - * Proposal downloaded, but the user needs to accept/reject it. - */ - PROPOSED = "proposed", - /** - * The user has accepted the proposal. - */ - ACCEPTED = "accepted", - /** - * The user has rejected the proposal. - */ - REFUSED = "refused", - /** - * Downloading or processing the proposal has failed permanently. - */ - PERMANENTLY_FAILED = "permanently-failed", - /** - * Downloaded proposal was detected as a re-purchase. - */ - REPURCHASE = "repurchase", -} - -export interface ProposalDownload { - /** - * The contract that was offered by the merchant. - */ - contractTermsRaw: any; - - contractData: WalletContractData; -} - -/** - * Record for a downloaded order, stored in the wallet's database. - */ -export interface ProposalRecord { - orderId: string; - - merchantBaseUrl: string; - - /** - * Downloaded data from the merchant. - */ - download: ProposalDownload | undefined; - - /** - * Unique ID when the order is stored in the wallet DB. - */ - proposalId: string; - - /** - * Timestamp (in ms) of when the record - * was created. - */ - timestamp: Timestamp; - - /** - * Private key for the nonce. - */ - noncePriv: string; - - /** - * Public key for the nonce. - */ - noncePub: string; - - claimToken: string | undefined; - - proposalStatus: ProposalStatus; - - repurchaseProposalId: string | undefined; - - /** - * Session ID we got when downloading the contract. - */ - downloadSessionId?: string; - - /** - * Retry info, even present when the operation isn't active to allow indexing - * on the next retry timestamp. - */ - retryInfo: RetryInfo; - - lastError: TalerErrorDetails | undefined; -} - -/** - * Status of a tip we got from a merchant. - */ -export interface TipRecord { - lastError: TalerErrorDetails | undefined; - - /** - * Has the user accepted the tip? Only after the tip has been accepted coins - * withdrawn from the tip may be used. - */ - acceptedTimestamp: Timestamp | undefined; - - /** - * The tipped amount. - */ - tipAmountRaw: AmountJson; - - tipAmountEffective: AmountJson; - - /** - * Timestamp, the tip can't be picked up anymore after this deadline. - */ - tipExpiration: Timestamp; - - /** - * The exchange that will sign our coins, chosen by the merchant. - */ - exchangeBaseUrl: string; - - /** - * Base URL of the merchant that is giving us the tip. - */ - merchantBaseUrl: string; - - /** - * Denomination selection made by the wallet for picking up - * this tip. - */ - denomsSel: DenomSelectionState; - - /** - * Tip ID chosen by the wallet. - */ - walletTipId: string; - - /** - * Secret seed used to derive planchets for this tip. - */ - secretSeed: string; - - /** - * The merchant's identifier for this tip. - */ - merchantTipId: string; - - createdTimestamp: Timestamp; - - /** - * Timestamp for when the wallet finished picking up the tip - * from the merchant. - */ - pickedUpTimestamp: Timestamp | undefined; - - /** - * Retry info, even present when the operation isn't active to allow indexing - * on the next retry timestamp. - */ - retryInfo: RetryInfo; -} - -export interface RefreshGroupRecord { - /** - * Retry info, even present when the operation isn't active to allow indexing - * on the next retry timestamp. - */ - retryInfo: RetryInfo; - - lastError: TalerErrorDetails | undefined; - - lastErrorPerCoin: { [coinIndex: number]: TalerErrorDetails }; - - refreshGroupId: string; - - reason: RefreshReason; - - oldCoinPubs: string[]; - - refreshSessionPerCoin: (RefreshSessionRecord | undefined)[]; - - inputPerCoin: AmountJson[]; - - estimatedOutputPerCoin: AmountJson[]; - - /** - * Flag for each coin whether refreshing finished. - * If a coin can't be refreshed (remaining value too small), - * it will be marked as finished, but no refresh session will - * be created. - */ - finishedPerCoin: boolean[]; - - timestampCreated: Timestamp; - - /** - * Timestamp when the refresh session finished. - */ - timestampFinished: Timestamp | undefined; -} - -/** - * Ongoing refresh - */ -export interface RefreshSessionRecord { - /** - * 512-bit secret that can be used to derive - * the other cryptographic material for the refresh session. - * - * FIXME: We currently store the derived material, but - * should always derive it. - */ - sessionSecretSeed: string; - - /** - * Sum of the value of denominations we want - * to withdraw in this session, without fees. - */ - amountRefreshOutput: AmountJson; - - /** - * Hashed denominations of the newly requested coins. - */ - newDenoms: { - denomPubHash: string; - count: number; - }[]; - - /** - * The no-reveal-index after we've done the melting. - */ - 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; - - /** - * Start date of the fee. - */ - startStamp: Timestamp; - - /** - * End date of the fee. - */ - endStamp: Timestamp; - - /** - * Signature made by the exchange master key. - */ - sig: string; -} - -/** - * Record to store information about a refund event. - * - * All information about a refund is stored with the purchase, - * this event is just for the history. - * - * The event is only present for completed refunds. - */ -export interface RefundEventRecord { - timestamp: Timestamp; - merchantExecutionTimestamp: Timestamp; - refundGroupId: string; - proposalId: string; -} - -export enum RefundState { - Failed = "failed", - Applied = "applied", - Pending = "pending", -} - -/** - * State of one refund from the merchant, maintained by the wallet. - */ -export type WalletRefundItem = - | WalletRefundFailedItem - | WalletRefundPendingItem - | WalletRefundAppliedItem; - -export interface WalletRefundItemCommon { - // Execution time as claimed by the merchant - executionTime: Timestamp; - - /** - * Time when the wallet became aware of the refund. - */ - obtainedTime: Timestamp; - - refundAmount: AmountJson; - - refundFee: AmountJson; - - /** - * Upper bound on the refresh cost incurred by - * applying this refund. - * - * Might be lower in practice when two refunds on the same - * coin are refreshed in the same refresh operation. - */ - totalRefreshCostBound: AmountJson; - - coinPub: string; - - rtransactionId: number; -} - -/** - * Failed refund, either because the merchant did - * something wrong or it expired. - */ -export interface WalletRefundFailedItem extends WalletRefundItemCommon { - type: RefundState.Failed; -} - -export interface WalletRefundPendingItem extends WalletRefundItemCommon { - type: RefundState.Pending; -} - -export interface WalletRefundAppliedItem extends WalletRefundItemCommon { - type: RefundState.Applied; -} - -export enum RefundReason { - /** - * Normal refund given by the merchant. - */ - NormalRefund = "normal-refund", - /** - * Refund from an aborted payment. - */ - AbortRefund = "abort-pay-refund", -} - -/** - * Record stored for every time we successfully submitted - * a payment to the merchant (both first time and re-play). - */ -export interface PayEventRecord { - proposalId: string; - sessionId: string | undefined; - isReplay: boolean; - timestamp: Timestamp; -} - -export interface ExchangeUpdatedEventRecord { - exchangeBaseUrl: string; - timestamp: Timestamp; -} - -export interface ReserveUpdatedEventRecord { - amountReserveBalance: string; - amountExpected: string; - reservePub: string; - timestamp: Timestamp; - reserveUpdateId: string; - newHistoryTransactions: ReserveTransaction[]; -} - -export interface AllowedAuditorInfo { - auditorBaseUrl: string; - auditorPub: string; -} - -export interface AllowedExchangeInfo { - exchangeBaseUrl: string; - exchangePub: string; -} - -/** - * Data extracted from the contract terms that is relevant for payment - * processing in the wallet. - */ -export interface WalletContractData { - products?: Product[]; - summaryI18n: { [lang_tag: string]: string } | undefined; - - /** - * Fulfillment URL, or the empty string if the order has no fulfillment URL. - * - * Stored as a non-nullable string as we use this field for IndexedDB indexing. - */ - fulfillmentUrl: string; - - contractTermsHash: string; - fulfillmentMessage?: string; - fulfillmentMessageI18n?: InternationalizedString; - merchantSig: string; - merchantPub: string; - merchant: MerchantInfo; - amount: AmountJson; - orderId: string; - merchantBaseUrl: string; - summary: string; - autoRefund: Duration | undefined; - maxWireFee: AmountJson; - wireFeeAmortization: number; - payDeadline: Timestamp; - refundDeadline: Timestamp; - allowedAuditors: AllowedAuditorInfo[]; - allowedExchanges: AllowedExchangeInfo[]; - timestamp: Timestamp; - wireMethod: string; - wireInfoHash: string; - maxDepositFee: AmountJson; -} - - -export enum AbortStatus { - None = "none", - AbortRefund = "abort-refund", - AbortFinished = "abort-finished", -} - -/** - * Record that stores status information about one purchase, starting from when - * the customer accepts a proposal. Includes refund status if applicable. - */ -export interface PurchaseRecord { - /** - * Proposal ID for this purchase. Uniquely identifies the - * purchase and the proposal. - */ - proposalId: string; - - /** - * Private key for the nonce. - */ - noncePriv: string; - - /** - * Public key for the nonce. - */ - noncePub: string; - - /** - * Downloaded and parsed proposal data. - */ - download: ProposalDownload; - - /** - * Deposit permissions, available once the user has accepted the payment. - * - * This value is cached and derived from payCoinSelection. - */ - coinDepositPermissions: CoinDepositPermission[] | undefined; - - payCoinSelection: PayCoinSelection; - - /** - * Pending removals from pay coin selection. - * - * Used when a the pay coin selection needs to be changed - * because a coin became known as double-spent or invalid, - * but a new coin selection can't immediately be done, as - * there is not enough balance (e.g. when waiting for a refresh). - */ - pendingRemovedCoinPubs?: string[]; - - totalPayCost: AmountJson; - - /** - * Timestamp of the first time that sending a payment to the merchant - * for this purchase was successful. - */ - timestampFirstSuccessfulPay: Timestamp | undefined; - - merchantPaySig: string | undefined; - - /** - * When was the purchase made? - * Refers to the time that the user accepted. - */ - timestampAccept: Timestamp; - - /** - * Pending refunds for the purchase. A refund is pending - * when the merchant reports a transient error from the exchange. - */ - refunds: { [refundKey: string]: WalletRefundItem }; - - /** - * When was the last refund made? - * Set to 0 if no refund was made on the purchase. - */ - timestampLastRefundStatus: Timestamp | undefined; - - /** - * Last session signature that we submitted to /pay (if any). - */ - lastSessionId: string | undefined; - - /** - * Set for the first payment, or on re-plays. - */ - paymentSubmitPending: boolean; - - /** - * Do we need to query the merchant for the refund status - * of the payment? - */ - refundQueryRequested: boolean; - - abortStatus: AbortStatus; - - payRetryInfo: RetryInfo; - - lastPayError: TalerErrorDetails | undefined; - - /** - * Retry information for querying the refund status with the merchant. - */ - refundStatusRetryInfo: RetryInfo; - - /** - * Last error (or undefined) for querying the refund status with the merchant. - */ - lastRefundStatusError: TalerErrorDetails | undefined; - - /** - * Continue querying the refund status until this deadline has expired. - */ - autoRefundDeadline: Timestamp | undefined; -} - -/** - * Configuration key/value entries to configure - * the wallet. - */ -export interface ConfigRecord<T> { - key: string; - value: T; -} - -/** - * FIXME: Eliminate this in favor of DenomSelectionState. - */ -export interface DenominationSelectionInfo { - totalCoinValue: AmountJson; - totalWithdrawCost: AmountJson; - selectedDenoms: { - /** - * How many times do we withdraw this denomination? - */ - count: number; - denom: DenominationRecord; - }[]; -} - -/** - * Selected denominations withn some extra info. - */ -export interface DenomSelectionState { - totalCoinValue: AmountJson; - totalWithdrawCost: AmountJson; - selectedDenoms: { - denomPubHash: string; - count: number; - }[]; -} - -/** - * Group of withdrawal operations that need to be executed. - * (Either for a normal withdrawal or from a tip.) - * - * The withdrawal group record is only created after we know - * the coin selection we want to withdraw. - */ -export interface WithdrawalGroupRecord { - withdrawalGroupId: string; - - /** - * Secret seed used to derive planchets. - */ - secretSeed: string; - - reservePub: string; - - exchangeBaseUrl: string; - - /** - * When was the withdrawal operation started started? - * Timestamp in milliseconds. - */ - timestampStart: Timestamp; - - /** - * When was the withdrawal operation completed? - */ - timestampFinish?: Timestamp; - - /** - * Amount including fees (i.e. the amount subtracted from the - * reserve to withdraw all coins in this withdrawal session). - */ - rawWithdrawalAmount: AmountJson; - - denomsSel: DenomSelectionState; - - /** - * Retry info, always present even on completed operations so that indexing works. - */ - retryInfo: RetryInfo; - - lastError: TalerErrorDetails | undefined; -} - -export interface BankWithdrawUriRecord { - /** - * The withdraw URI we got from the bank. - */ - talerWithdrawUri: string; - - /** - * Reserve that was created for the withdraw URI. - */ - reservePub: string; -} - -/** - * Status of recoup operations that were grouped together. - * - * The remaining amount of involved coins should be set to zero - * in the same transaction that inserts the RecoupGroupRecord. - */ -export interface RecoupGroupRecord { - /** - * Unique identifier for the recoup group record. - */ - recoupGroupId: string; - - timestampStarted: Timestamp; - - timestampFinished: Timestamp | undefined; - - /** - * Public keys that identify the coins being recouped - * as part of this session. - * - * (Structured like this to enable multiEntry indexing in IndexedDB.) - */ - coinPubs: string[]; - - /** - * Array of flags to indicate whether the recoup finished on each individual coin. - */ - recoupFinishedPerCoin: boolean[]; - - /** - * We store old amount (i.e. before recoup) of recouped coins here, - * as the balance of a recouped coin is set to zero when the - * recoup group is created. - */ - oldAmountPerCoin: AmountJson[]; - - /** - * Public keys of coins that should be scheduled for refreshing - * after all individual recoups are done. - */ - scheduleRefreshCoins: string[]; - - /** - * Retry info. - */ - retryInfo: RetryInfo; - - /** - * Last error that occured, if any. - */ - lastError: TalerErrorDetails | undefined; -} - -export enum ImportPayloadType { - CoreSchema = "core-schema", -} - -export enum BackupProviderStatus { - PaymentRequired = "payment-required", - Ready = "ready", -} - -export interface BackupProviderRecord { - baseUrl: string; - - /** - * Terms of service of the provider. - * Might be unavailable in the DB in certain situations - * (such as loading a recovery document). - */ - terms?: { - supportedProtocolVersion: string; - annualFee: AmountString; - storageLimitInMegabytes: number; - }; - - active: boolean; - - /** - * Hash of the last encrypted backup that we already merged - * or successfully uploaded ourselves. - */ - lastBackupHash?: string; - - /** - * Clock of the last backup that we already - * merged. - */ - lastBackupClock?: number; - - lastBackupTimestamp?: Timestamp; - - /** - * Proposal that we're currently trying to pay for. - * - * (Also included in paymentProposalIds.) - */ - currentPaymentProposalId?: string; - - /** - * Proposals that were used to pay (or attempt to pay) the provider. - * - * Stored to display a history of payments to the provider, and - * to make sure that the wallet isn't overpaying. - */ - paymentProposalIds: string[]; - - /** - * Next scheduled backup. - */ - nextBackupTimestamp?: Timestamp; - - /** - * Retry info. - */ - retryInfo: RetryInfo; - - /** - * Last error that occured, if any. - */ - lastError: TalerErrorDetails | undefined; -} - -/** - * Group of deposits made by the wallet. - */ -export interface DepositGroupRecord { - depositGroupId: string; - - merchantPub: string; - merchantPriv: string; - - noncePriv: string; - noncePub: string; - - /** - * Wire information used by all deposits in this - * deposit group. - */ - wire: { - payto_uri: string; - salt: string; - }; - - /** - * Verbatim contract terms. - */ - contractTermsRaw: ContractTerms; - - contractTermsHash: string; - - payCoinSelection: PayCoinSelection; - - totalPayCost: AmountJson; - - effectiveDepositAmount: AmountJson; - - depositedPerCoin: boolean[]; - - timestampCreated: Timestamp; - - timestampFinished: Timestamp | undefined; - - lastError: TalerErrorDetails | undefined; - - /** - * Retry info. - */ - retryInfo: RetryInfo; -} - -/** - * Record for a deposits that the wallet observed - * as a result of double spending, but which is not - * present in the wallet's own database otherwise. - */ -export interface GhostDepositGroupRecord { - /** - * When multiple deposits for the same contract terms hash - * have a different timestamp, we choose the earliest one. - */ - timestamp: Timestamp; - - contractTermsHash: string; - - deposits: { - coinPub: string; - amount: AmountString; - timestamp: Timestamp; - depositFee: AmountString; - merchantPub: string; - coinSig: string; - wireHash: string; - }[]; -} - -class ExchangesStore extends Store<"exchanges", ExchangeRecord> { - constructor() { - super("exchanges", { keyPath: "baseUrl" }); - } -} - -class CoinsStore extends Store<"coins", CoinRecord> { - constructor() { - super("coins", { keyPath: "coinPub" }); - } - - exchangeBaseUrlIndex = new Index< - "coins", - "exchangeBaseUrl", - string, - CoinRecord - >(this, "exchangeBaseUrl", "exchangeBaseUrl"); - - denomPubHashIndex = new Index< - "coins", - "denomPubHashIndex", - string, - CoinRecord - >(this, "denomPubHashIndex", "denomPubHash"); - - coinEvHashIndex = new Index<"coins", "coinEvHashIndex", string, CoinRecord>( - this, - "coinEvHashIndex", - "coinEvHash", - ); -} - -class ProposalsStore extends Store<"proposals", ProposalRecord> { - constructor() { - super("proposals", { keyPath: "proposalId" }); - } - urlAndOrderIdIndex = new Index< - "proposals", - "urlIndex", - string, - ProposalRecord - >(this, "urlIndex", ["merchantBaseUrl", "orderId"]); -} - -class PurchasesStore extends Store<"purchases", PurchaseRecord> { - constructor() { - super("purchases", { keyPath: "proposalId" }); - } - - fulfillmentUrlIndex = new Index< - "purchases", - "fulfillmentUrlIndex", - string, - PurchaseRecord - >(this, "fulfillmentUrlIndex", "download.contractData.fulfillmentUrl"); - - orderIdIndex = new Index<"purchases", "orderIdIndex", string, PurchaseRecord>( - this, - "orderIdIndex", - ["download.contractData.merchantBaseUrl", "download.contractData.orderId"], - ); -} - -class DenominationsStore extends Store<"denominations", DenominationRecord> { - constructor() { - // cast needed because of bug in type annotations - super("denominations", { - keyPath: (["exchangeBaseUrl", "denomPubHash"] as any) as IDBKeyPath, - }); - } - exchangeBaseUrlIndex = new Index< - "denominations", - "exchangeBaseUrlIndex", - string, - DenominationRecord - >(this, "exchangeBaseUrlIndex", "exchangeBaseUrl"); -} - -class CurrenciesStore extends Store<"currencies", CurrencyRecord> { - constructor() { - super("currencies", { keyPath: "name" }); - } -} - -class ConfigStore extends Store<"config", ConfigRecord<any>> { - constructor() { - super("config", { keyPath: "key" }); - } -} - -class ReservesStore extends Store<"reserves", ReserveRecord> { - constructor() { - super("reserves", { keyPath: "reservePub" }); - } -} - -class TipsStore extends Store<"tips", TipRecord> { - constructor() { - super("tips", { keyPath: "walletTipId" }); - } - // Added in version 2 - byMerchantTipIdAndBaseUrl = new Index< - "tips", - "tipsByMerchantTipIdAndOriginIndex", - [string, string], - TipRecord - >(this, "tipsByMerchantTipIdAndOriginIndex", [ - "merchantTipId", - "merchantBaseUrl", - ]); -} - -class WithdrawalGroupsStore extends Store< - "withdrawals", - WithdrawalGroupRecord -> { - constructor() { - super("withdrawals", { keyPath: "withdrawalGroupId" }); - } - byReservePub = new Index< - "withdrawals", - "withdrawalsByReserveIndex", - string, - WithdrawalGroupRecord - >(this, "withdrawalsByReserveIndex", "reservePub"); -} - -class PlanchetsStore extends Store<"planchets", PlanchetRecord> { - constructor() { - super("planchets", { keyPath: "coinPub" }); - } - byGroupAndIndex = new Index< - "planchets", - "withdrawalGroupAndCoinIdxIndex", - string, - PlanchetRecord - >(this, "withdrawalGroupAndCoinIdxIndex", ["withdrawalGroupId", "coinIdx"]); - byGroup = new Index< - "planchets", - "withdrawalGroupIndex", - string, - PlanchetRecord - >(this, "withdrawalGroupIndex", "withdrawalGroupId"); - - coinEvHashIndex = new Index< - "planchets", - "coinEvHashIndex", - string, - PlanchetRecord - >(this, "coinEvHashIndex", "coinEvHash"); -} - -/** - * This store is effectively a materialized index for - * reserve records that are for a bank-integrated withdrawal. - */ -class BankWithdrawUrisStore extends Store< - "bankWithdrawUris", - BankWithdrawUriRecord -> { - constructor() { - super("bankWithdrawUris", { keyPath: "talerWithdrawUri" }); - } -} - -/** - */ -class BackupProvidersStore extends Store< - "backupProviders", - BackupProviderRecord -> { - constructor() { - super("backupProviders", { keyPath: "baseUrl" }); - } -} - -class DepositGroupsStore extends Store<"depositGroups", DepositGroupRecord> { - constructor() { - super("depositGroups", { keyPath: "depositGroupId" }); - } -} - -/** - * The stores and indices for the wallet database. - */ -export const Stores = { - coins: new CoinsStore(), - config: new ConfigStore(), - currencies: new CurrenciesStore(), - denominations: new DenominationsStore(), - exchanges: new ExchangesStore(), - proposals: new ProposalsStore(), - refreshGroups: new Store<"refreshGroups", RefreshGroupRecord>( - "refreshGroups", - { - keyPath: "refreshGroupId", - }, - ), - recoupGroups: new Store<"recoupGroups", RecoupGroupRecord>("recoupGroups", { - keyPath: "recoupGroupId", - }), - reserves: new ReservesStore(), - purchases: new PurchasesStore(), - tips: new TipsStore(), - withdrawalGroups: new WithdrawalGroupsStore(), - planchets: new PlanchetsStore(), - bankWithdrawUris: new BankWithdrawUrisStore(), - backupProviders: new BackupProvidersStore(), - depositGroups: new DepositGroupsStore(), - ghostDepositGroups: new Store<"ghostDepositGroups", GhostDepositGroupRecord>( - "ghostDepositGroups", - { - keyPath: "contractTermsHash", - }, - ), -}; - -export class MetaConfigStore extends Store<"metaConfig", ConfigRecord<any>> { - constructor() { - super("metaConfig", { keyPath: "key" }); - } -} - -export const MetaStores = { - metaConfig: new MetaConfigStore(), -}; diff --git a/packages/taler-wallet-core/src/types/notifications.ts b/packages/taler-wallet-core/src/types/notifications.ts deleted file mode 100644 index edfb377b9..000000000 --- a/packages/taler-wallet-core/src/types/notifications.ts +++ /dev/null @@ -1,271 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2019 GNUnet e.V. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - 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/> - */ - -/** - * Type and schema definitions for notifications from the wallet to clients - * of the wallet. - */ - -/** - * Imports. - */ -import { TalerErrorDetails } from "./walletTypes"; - -export enum NotificationType { - CoinWithdrawn = "coin-withdrawn", - ProposalAccepted = "proposal-accepted", - ProposalDownloaded = "proposal-downloaded", - RefundsSubmitted = "refunds-submitted", - RecoupStarted = "recoup-started", - RecoupFinished = "recoup-finished", - RefreshRevealed = "refresh-revealed", - RefreshMelted = "refresh-melted", - RefreshStarted = "refresh-started", - RefreshUnwarranted = "refresh-unwarranted", - ReserveUpdated = "reserve-updated", - ReserveConfirmed = "reserve-confirmed", - ReserveCreated = "reserve-created", - WithdrawGroupCreated = "withdraw-group-created", - WithdrawGroupFinished = "withdraw-group-finished", - WaitingForRetry = "waiting-for-retry", - RefundStarted = "refund-started", - RefundQueried = "refund-queried", - RefundFinished = "refund-finished", - ExchangeOperationError = "exchange-operation-error", - RefreshOperationError = "refresh-operation-error", - RecoupOperationError = "recoup-operation-error", - RefundApplyOperationError = "refund-apply-error", - RefundStatusOperationError = "refund-status-error", - ProposalOperationError = "proposal-error", - TipOperationError = "tip-error", - PayOperationError = "pay-error", - PayOperationSuccess = "pay-operation-success", - WithdrawOperationError = "withdraw-error", - ReserveNotYetFound = "reserve-not-yet-found", - ReserveOperationError = "reserve-error", - InternalError = "internal-error", - PendingOperationProcessed = "pending-operation-processed", - ProposalRefused = "proposal-refused", - ReserveRegisteredWithBank = "reserve-registered-with-bank", - DepositOperationError = "deposit-operation-error", -} - -export interface ProposalAcceptedNotification { - type: NotificationType.ProposalAccepted; - proposalId: string; -} - -export interface InternalErrorNotification { - type: NotificationType.InternalError; - message: string; - exception: any; -} - -export interface ReserveNotYetFoundNotification { - type: NotificationType.ReserveNotYetFound; - reservePub: string; -} - -export interface CoinWithdrawnNotification { - type: NotificationType.CoinWithdrawn; -} - -export interface RefundStartedNotification { - type: NotificationType.RefundStarted; -} - -export interface RefundQueriedNotification { - type: NotificationType.RefundQueried; -} - -export interface ProposalDownloadedNotification { - type: NotificationType.ProposalDownloaded; - proposalId: string; -} - -export interface RefundsSubmittedNotification { - type: NotificationType.RefundsSubmitted; - proposalId: string; -} - -export interface RecoupStartedNotification { - type: NotificationType.RecoupStarted; -} - -export interface RecoupFinishedNotification { - type: NotificationType.RecoupFinished; -} - -export interface RefreshMeltedNotification { - type: NotificationType.RefreshMelted; -} - -export interface RefreshRevealedNotification { - type: NotificationType.RefreshRevealed; -} - -export interface RefreshStartedNotification { - type: NotificationType.RefreshStarted; -} - -export interface RefreshRefusedNotification { - type: NotificationType.RefreshUnwarranted; -} - -export interface ReserveConfirmedNotification { - type: NotificationType.ReserveConfirmed; -} - -export interface WithdrawalGroupCreatedNotification { - type: NotificationType.WithdrawGroupCreated; - withdrawalGroupId: string; -} - -export interface WithdrawalGroupFinishedNotification { - type: NotificationType.WithdrawGroupFinished; - reservePub: string; -} - -export interface WaitingForRetryNotification { - type: NotificationType.WaitingForRetry; - numPending: number; - numGivingLiveness: number; -} - -export interface RefundFinishedNotification { - type: NotificationType.RefundFinished; -} - -export interface ExchangeOperationErrorNotification { - type: NotificationType.ExchangeOperationError; - error: TalerErrorDetails; -} - -export interface RefreshOperationErrorNotification { - type: NotificationType.RefreshOperationError; - error: TalerErrorDetails; -} - -export interface RefundStatusOperationErrorNotification { - type: NotificationType.RefundStatusOperationError; - error: TalerErrorDetails; -} - -export interface RefundApplyOperationErrorNotification { - type: NotificationType.RefundApplyOperationError; - error: TalerErrorDetails; -} - -export interface PayOperationErrorNotification { - type: NotificationType.PayOperationError; - error: TalerErrorDetails; -} - -export interface ProposalOperationErrorNotification { - type: NotificationType.ProposalOperationError; - error: TalerErrorDetails; -} - -export interface TipOperationErrorNotification { - type: NotificationType.TipOperationError; - error: TalerErrorDetails; -} - -export interface WithdrawOperationErrorNotification { - type: NotificationType.WithdrawOperationError; - error: TalerErrorDetails; -} - -export interface RecoupOperationErrorNotification { - type: NotificationType.RecoupOperationError; - error: TalerErrorDetails; -} - -export interface DepositOperationErrorNotification { - type: NotificationType.DepositOperationError; - error: TalerErrorDetails; -} - -export interface ReserveOperationErrorNotification { - type: NotificationType.ReserveOperationError; - error: TalerErrorDetails; -} - -export interface ReserveCreatedNotification { - type: NotificationType.ReserveCreated; - reservePub: string; -} - -export interface PendingOperationProcessedNotification { - type: NotificationType.PendingOperationProcessed; -} - -export interface ProposalRefusedNotification { - type: NotificationType.ProposalRefused; -} - -export interface ReserveRegisteredWithBankNotification { - type: NotificationType.ReserveRegisteredWithBank; -} - -/** - * Notification sent when a pay (or pay replay) operation succeeded. - * - * We send this notification because the confirmPay request can return - * a "confirmed" response that indicates that the payment has been confirmed - * by the user, but we're still waiting for the payment to succeed or fail. - */ -export interface PayOperationSuccessNotification { - type: NotificationType.PayOperationSuccess; - proposalId: string; -} - -export type WalletNotification = - | WithdrawOperationErrorNotification - | ReserveOperationErrorNotification - | ExchangeOperationErrorNotification - | RefreshOperationErrorNotification - | RefundStatusOperationErrorNotification - | RefundApplyOperationErrorNotification - | ProposalOperationErrorNotification - | PayOperationErrorNotification - | TipOperationErrorNotification - | ProposalAcceptedNotification - | ProposalDownloadedNotification - | RefundsSubmittedNotification - | RecoupStartedNotification - | RecoupFinishedNotification - | RefreshMeltedNotification - | RefreshRevealedNotification - | RefreshStartedNotification - | RefreshRefusedNotification - | ReserveCreatedNotification - | ReserveConfirmedNotification - | WithdrawalGroupFinishedNotification - | WaitingForRetryNotification - | RefundStartedNotification - | RefundFinishedNotification - | RefundQueriedNotification - | WithdrawalGroupCreatedNotification - | CoinWithdrawnNotification - | RecoupOperationErrorNotification - | DepositOperationErrorNotification - | InternalErrorNotification - | PendingOperationProcessedNotification - | ProposalRefusedNotification - | ReserveRegisteredWithBankNotification - | ReserveNotYetFoundNotification - | PayOperationSuccessNotification; diff --git a/packages/taler-wallet-core/src/types/pendingTypes.ts b/packages/taler-wallet-core/src/types/pendingTypes.ts deleted file mode 100644 index d41d2a977..000000000 --- a/packages/taler-wallet-core/src/types/pendingTypes.ts +++ /dev/null @@ -1,288 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2019 GNUnet e.V. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - 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/> - */ - -/** - * Type and schema definitions for pending operations in the wallet. - */ - -/** - * Imports. - */ -import { TalerErrorDetails, BalancesResponse } from "./walletTypes"; -import { ReserveRecordStatus } from "./dbTypes"; -import { Timestamp, Duration } from "../util/time"; -import { RetryInfo } from "../util/retries"; - -export enum PendingOperationType { - Bug = "bug", - ExchangeUpdate = "exchange-update", - ExchangeCheckRefresh = "exchange-check-refresh", - Pay = "pay", - ProposalChoice = "proposal-choice", - ProposalDownload = "proposal-download", - Refresh = "refresh", - Reserve = "reserve", - Recoup = "recoup", - RefundQuery = "refund-query", - TipChoice = "tip-choice", - TipPickup = "tip-pickup", - Withdraw = "withdraw", - Deposit = "deposit", -} - -/** - * Information about a pending operation. - */ -export type PendingOperationInfo = PendingOperationInfoCommon & - ( - | PendingBugOperation - | PendingExchangeUpdateOperation - | PendingExchangeCheckRefreshOperation - | PendingPayOperation - | PendingProposalChoiceOperation - | PendingProposalDownloadOperation - | PendingRefreshOperation - | PendingRefundQueryOperation - | PendingReserveOperation - | PendingTipChoiceOperation - | PendingTipPickupOperation - | PendingWithdrawOperation - | PendingRecoupOperation - | PendingDepositOperation - ); - -/** - * The wallet is currently updating information about an exchange. - */ -export interface PendingExchangeUpdateOperation { - type: PendingOperationType.ExchangeUpdate; - stage: ExchangeUpdateOperationStage; - reason: string; - exchangeBaseUrl: string; - lastError: TalerErrorDetails | undefined; -} - -/** - * The wallet should check whether coins from this exchange - * need to be auto-refreshed. - */ -export interface PendingExchangeCheckRefreshOperation { - type: PendingOperationType.ExchangeCheckRefresh; - exchangeBaseUrl: string; -} - -/** - * Some interal error happened in the wallet. This pending operation - * should *only* be reported for problems in the wallet, not when - * a problem with a merchant/exchange/etc. occurs. - */ -export interface PendingBugOperation { - type: PendingOperationType.Bug; - message: string; - details: any; -} - -/** - * Current state of an exchange update operation. - */ -export enum ExchangeUpdateOperationStage { - FetchKeys = "fetch-keys", - FetchWire = "fetch-wire", - FinalizeUpdate = "finalize-update", -} - -export enum ReserveType { - /** - * Manually created. - */ - Manual = "manual", - /** - * Withdrawn from a bank that has "tight" Taler integration - */ - TalerBankWithdraw = "taler-bank-withdraw", -} - -/** - * Status of processing a reserve. - * - * Does *not* include the withdrawal operation that might result - * from this. - */ -export interface PendingReserveOperation { - type: PendingOperationType.Reserve; - retryInfo: RetryInfo | undefined; - stage: ReserveRecordStatus; - timestampCreated: Timestamp; - reserveType: ReserveType; - reservePub: string; - bankWithdrawConfirmUrl?: string; -} - -/** - * Status of an ongoing withdrawal operation. - */ -export interface PendingRefreshOperation { - type: PendingOperationType.Refresh; - lastError?: TalerErrorDetails; - refreshGroupId: string; - finishedPerCoin: boolean[]; - retryInfo: RetryInfo; -} - -/** - * Status of downloading signed contract terms from a merchant. - */ -export interface PendingProposalDownloadOperation { - type: PendingOperationType.ProposalDownload; - merchantBaseUrl: string; - proposalTimestamp: Timestamp; - proposalId: string; - orderId: string; - lastError?: TalerErrorDetails; - retryInfo: RetryInfo; -} - -/** - * User must choose whether to accept or reject the merchant's - * proposed contract terms. - */ -export interface PendingProposalChoiceOperation { - type: PendingOperationType.ProposalChoice; - merchantBaseUrl: string; - proposalTimestamp: Timestamp; - proposalId: string; -} - -/** - * The wallet is picking up a tip that the user has accepted. - */ -export interface PendingTipPickupOperation { - type: PendingOperationType.TipPickup; - tipId: string; - merchantBaseUrl: string; - merchantTipId: string; -} - -/** - * The wallet has been offered a tip, and the user now needs to - * decide whether to accept or reject the tip. - */ -export interface PendingTipChoiceOperation { - type: PendingOperationType.TipChoice; - tipId: string; - merchantBaseUrl: string; - merchantTipId: string; -} - -/** - * The wallet is signing coins and then sending them to - * the merchant. - */ -export interface PendingPayOperation { - type: PendingOperationType.Pay; - proposalId: string; - isReplay: boolean; - retryInfo: RetryInfo; - lastError: TalerErrorDetails | undefined; -} - -/** - * The wallet is querying the merchant about whether any refund - * permissions are available for a purchase. - */ -export interface PendingRefundQueryOperation { - type: PendingOperationType.RefundQuery; - proposalId: string; - retryInfo: RetryInfo; - lastError: TalerErrorDetails | undefined; -} - -export interface PendingRecoupOperation { - type: PendingOperationType.Recoup; - recoupGroupId: string; - retryInfo: RetryInfo; - lastError: TalerErrorDetails | undefined; -} - -/** - * Status of an ongoing withdrawal operation. - */ -export interface PendingWithdrawOperation { - type: PendingOperationType.Withdraw; - lastError: TalerErrorDetails | undefined; - retryInfo: RetryInfo; - withdrawalGroupId: string; - numCoinsWithdrawn: number; - numCoinsTotal: number; -} - -/** - * Status of an ongoing deposit operation. - */ -export interface PendingDepositOperation { - type: PendingOperationType.Deposit; - lastError: TalerErrorDetails | undefined; - retryInfo: RetryInfo; - depositGroupId: string; -} - -/** - * Fields that are present in every pending operation. - */ -export interface PendingOperationInfoCommon { - /** - * Type of the pending operation. - */ - type: PendingOperationType; - - /** - * Set to true if the operation indicates that something is really in progress, - * as opposed to some regular scheduled operation or a permanent failure. - */ - givesLifeness: boolean; - - /** - * Retry info, not available on all pending operations. - * If it is available, it must have the same name. - */ - retryInfo?: RetryInfo; -} - -/** - * Response returned from the pending operations API. - */ -export interface PendingOperationsResponse { - /** - * List of pending operations. - */ - pendingOperations: PendingOperationInfo[]; - - /** - * Current wallet balance, including pending balances. - */ - walletBalance: BalancesResponse; - - /** - * When is the next pending operation due to be re-tried? - */ - nextRetryDelay: Duration; - - /** - * Does this response only include pending operations that - * are due to be executed right now? - */ - onlyDue: boolean; -} diff --git a/packages/taler-wallet-core/src/types/talerTypes.ts b/packages/taler-wallet-core/src/types/talerTypes.ts deleted file mode 100644 index fe1370cb7..000000000 --- a/packages/taler-wallet-core/src/types/talerTypes.ts +++ /dev/null @@ -1,1457 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2019 GNUnet e.V. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - 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/> - */ - -/** - * Type and schema definitions and helpers for the core GNU Taler protocol. - * - * All types here should be "@Checkable". - * - * Even though the rest of the wallet uses camelCase for fields, use snake_case - * here, since that's the convention for the Taler JSON+HTTP API. - */ - -/** - * Imports. - */ - -import { - buildCodecForObject, - codecForString, - codecForList, - codecOptional, - codecForAny, - codecForNumber, - codecForBoolean, - codecForMap, - Codec, - codecForConstNumber, - buildCodecForUnion, - codecForConstString, -} from "../util/codec"; -import { - Timestamp, - codecForTimestamp, - Duration, - codecForDuration, -} from "../util/time"; -import { codecForAmountString } from "../util/amounts"; - -/** - * Denomination as found in the /keys response from the exchange. - */ -export class Denomination { - /** - * Value of one coin of the denomination. - */ - value: string; - - /** - * Public signing key of the denomination. - */ - denom_pub: string; - - /** - * Fee for withdrawing. - */ - fee_withdraw: string; - - /** - * Fee for depositing. - */ - fee_deposit: string; - - /** - * Fee for refreshing. - */ - fee_refresh: string; - - /** - * Fee for refunding. - */ - fee_refund: string; - - /** - * Start date from which withdraw is allowed. - */ - stamp_start: Timestamp; - - /** - * End date for withdrawing. - */ - stamp_expire_withdraw: Timestamp; - - /** - * Expiration date after which the exchange can forget about - * the currency. - */ - stamp_expire_legal: Timestamp; - - /** - * Date after which the coins of this denomination can't be - * deposited anymore. - */ - stamp_expire_deposit: Timestamp; - - /** - * Signature over the denomination information by the exchange's master - * signing key. - */ - master_sig: string; -} - -/** - * Signature by the auditor that a particular denomination key is audited. - */ -export class AuditorDenomSig { - /** - * Denomination public key's hash. - */ - denom_pub_h: string; - - /** - * The signature. - */ - auditor_sig: string; -} - -/** - * Auditor information as given by the exchange in /keys. - */ -export class Auditor { - /** - * Auditor's public key. - */ - auditor_pub: string; - - /** - * Base URL of the auditor. - */ - auditor_url: string; - - /** - * List of signatures for denominations by the auditor. - */ - denomination_keys: AuditorDenomSig[]; -} - -/** - * Request that we send to the exchange to get a payback. - */ -export interface RecoupRequest { - /** - * Hashed enomination public key of the coin we want to get - * paid back. - */ - denom_pub_hash: string; - - /** - * Signature over the coin public key by the denomination. - */ - denom_sig: string; - - /** - * Coin public key of the coin we want to refund. - */ - coin_pub: string; - - /** - * Blinding key that was used during withdraw, - * used to prove that we were actually withdrawing the coin. - */ - coin_blind_key_secret: string; - - /** - * Signature made by the coin, authorizing the payback. - */ - coin_sig: string; - - /** - * Was the coin refreshed (and thus the recoup should go to the old coin)? - */ - refreshed: boolean; -} - -/** - * Response that we get from the exchange for a payback request. - */ -export class RecoupConfirmation { - /** - * Public key of the reserve that will receive the payback. - */ - reserve_pub?: string; - - /** - * Public key of the old coin that will receive the recoup, - * provided if refreshed was true. - */ - old_coin_pub?: string; -} - -/** - * Deposit permission for a single coin. - */ -export interface CoinDepositPermission { - /** - * Signature by the coin. - */ - coin_sig: string; - /** - * Public key of the coin being spend. - */ - coin_pub: string; - /** - * Signature made by the denomination public key. - */ - ub_sig: string; - /** - * The denomination public key associated with this coin. - */ - h_denom: string; - /** - * The amount that is subtracted from this coin with this payment. - */ - contribution: string; - - /** - * URL of the exchange this coin was withdrawn from. - */ - exchange_url: string; -} - -/** - * Information about an exchange as stored inside a - * merchant's contract terms. - */ -export class ExchangeHandle { - /** - * Master public signing key of the exchange. - */ - master_pub: string; - - /** - * Base URL of the exchange. - */ - url: string; -} - -export class AuditorHandle { - /** - * Official name of the auditor. - */ - name: string; - - /** - * Master public signing key of the auditor. - */ - auditor_pub: string; - - /** - * Base URL of the auditor. - */ - url: string; -} - -// Delivery location, losely modeled as a subset of -// ISO20022's PostalAddress25. -export interface Location { - // Nation with its own government. - country?: string; - - // Identifies a subdivision of a country such as state, region, county. - country_subdivision?: string; - - // Identifies a subdivision within a country sub-division. - district?: string; - - // Name of a built-up area, with defined boundaries, and a local government. - town?: string; - - // Specific location name within the town. - town_location?: string; - - // Identifier consisting of a group of letters and/or numbers that - // is added to a postal address to assist the sorting of mail. - post_code?: string; - - // Name of a street or thoroughfare. - street?: string; - - // Name of the building or house. - building_name?: string; - - // Number that identifies the position of a building on a street. - building_number?: string; - - // Free-form address lines, should not exceed 7 elements. - address_lines?: string[]; -} - -export interface MerchantInfo { - name: string; - jurisdiction?: Location; - address?: Location; -} - -export interface Tax { - // the name of the tax - name: string; - - // amount paid in tax - tax: AmountString; -} - -export interface Product { - // merchant-internal identifier for the product. - product_id?: string; - - // Human-readable product description. - description: string; - - // Map from IETF BCP 47 language tags to localized descriptions - description_i18n?: { [lang_tag: string]: string }; - - // The number of units of the product to deliver to the customer. - quantity?: number; - - // The unit in which the product is measured (liters, kilograms, packages, etc.) - unit?: string; - - // The price of the product; this is the total price for quantity times unit of this product. - price?: AmountString; - - // An optional base64-encoded product image - image?: string; - - // a list of taxes paid by the merchant for this product. Can be empty. - taxes?: Tax[]; - - // time indicating when this product should be delivered - delivery_date?: Timestamp; -} - -export interface InternationalizedString { - [lang_tag: string]: string; -} - -/** - * Contract terms from a merchant. - */ -export class ContractTerms { - /** - * Hash of the merchant's wire details. - */ - h_wire: string; - - /** - * Hash of the merchant's wire details. - */ - auto_refund?: Duration; - - /** - * Wire method the merchant wants to use. - */ - wire_method: string; - - /** - * Human-readable short summary of the contract. - */ - summary: string; - - summary_i18n?: InternationalizedString; - - /** - * Nonce used to ensure freshness. - */ - nonce: string; - - /** - * Total amount payable. - */ - amount: string; - - /** - * Auditors accepted by the merchant. - */ - auditors: AuditorHandle[]; - - /** - * Deadline to pay for the contract. - */ - pay_deadline: Timestamp; - - /** - * Maximum deposit fee covered by the merchant. - */ - max_fee: string; - - /** - * Information about the merchant. - */ - merchant: MerchantInfo; - - /** - * Public key of the merchant. - */ - merchant_pub: string; - - /** - * Time indicating when the order should be delivered. - * May be overwritten by individual products. - */ - delivery_date?: Timestamp; - - /** - * Delivery location for (all!) products. - */ - delivery_location?: Location; - - /** - * List of accepted exchanges. - */ - exchanges: ExchangeHandle[]; - - /** - * Products that are sold in this contract. - */ - products?: Product[]; - - /** - * Deadline for refunds. - */ - refund_deadline: Timestamp; - - /** - * Deadline for the wire transfer. - */ - wire_transfer_deadline: Timestamp; - - /** - * Time when the contract was generated by the merchant. - */ - timestamp: Timestamp; - - /** - * Order id to uniquely identify the purchase within - * one merchant instance. - */ - order_id: string; - - /** - * Base URL of the merchant's backend. - */ - merchant_base_url: string; - - /** - * Fulfillment URL to view the product or - * delivery status. - */ - fulfillment_url?: string; - - /** - * Plain text fulfillment message in the merchant's default language. - */ - fulfillment_message?: string; - - /** - * Internationalized fulfillment messages. - */ - fulfillment_message_i18n?: InternationalizedString; - - /** - * Share of the wire fee that must be settled with one payment. - */ - wire_fee_amortization?: number; - - /** - * Maximum wire fee that the merchant agrees to pay for. - */ - max_wire_fee?: string; - - /** - * Extra data, interpreted by the mechant only. - */ - extra?: any; -} - -/** - * Refund permission in the format that the merchant gives it to us. - */ -export class MerchantAbortPayRefundDetails { - /** - * Amount to be refunded. - */ - refund_amount: string; - - /** - * Fee for the refund. - */ - refund_fee: string; - - /** - * Public key of the coin being refunded. - */ - coin_pub: string; - - /** - * Refund transaction ID between merchant and exchange. - */ - rtransaction_id: number; - - /** - * Exchange's key used for the signature. - */ - exchange_pub?: string; - - /** - * Exchange's signature to confirm the refund. - */ - exchange_sig?: string; - - /** - * Error replay from the exchange (if any). - */ - exchange_reply?: any; - - /** - * Error code from the exchange (if any). - */ - exchange_code?: number; - - /** - * HTTP status code of the exchange's response - * to the merchant's refund request. - */ - exchange_http_status: number; -} - -/** - * Response for a refund pickup or a /pay in abort mode. - */ -export class MerchantRefundResponse { - /** - * Public key of the merchant - */ - merchant_pub: string; - - /** - * Contract terms hash of the contract that - * is being refunded. - */ - h_contract_terms: string; - - /** - * The signed refund permissions, to be sent to the exchange. - */ - refunds: MerchantAbortPayRefundDetails[]; -} - -/** - * Planchet detail sent to the merchant. - */ -export interface TipPlanchetDetail { - /** - * Hashed denomination public key. - */ - denom_pub_hash: string; - - /** - * Coin's blinded public key. - */ - coin_ev: string; -} - -/** - * Request sent to the merchant to pick up a tip. - */ -export interface TipPickupRequest { - /** - * Identifier of the tip. - */ - tip_id: string; - - /** - * List of planchets the wallet wants to use for the tip. - */ - planchets: TipPlanchetDetail[]; -} - -/** - * Reserve signature, defined as separate class to facilitate - * schema validation with "@Checkable". - */ -export class BlindSigWrapper { - /** - * Reserve signature. - */ - blind_sig: string; -} - -/** - * Response of the merchant - * to the TipPickupRequest. - */ -export class TipResponse { - /** - * The order of the signatures matches the planchets list. - */ - blind_sigs: BlindSigWrapper[]; -} - -/** - * Element of the payback list that the - * exchange gives us in /keys. - */ -export class Recoup { - /** - * The hash of the denomination public key for which the payback is offered. - */ - h_denom_pub: string; -} - -/** - * Structure of one exchange signing key in the /keys response. - */ -export class ExchangeSignKeyJson { - stamp_start: Timestamp; - stamp_expire: Timestamp; - stamp_end: Timestamp; - key: EddsaPublicKeyString; - master_sig: EddsaSignatureString; -} - -/** - * Structure that the exchange gives us in /keys. - */ -export class ExchangeKeysJson { - /** - * List of offered denominations. - */ - denoms: Denomination[]; - - /** - * The exchange's master public key. - */ - master_public_key: string; - - /** - * The list of auditors (partially) auditing the exchange. - */ - auditors: Auditor[]; - - /** - * Timestamp when this response was issued. - */ - list_issue_date: Timestamp; - - /** - * List of revoked denominations. - */ - recoup?: Recoup[]; - - /** - * Short-lived signing keys used to sign online - * responses. - */ - signkeys: ExchangeSignKeyJson[]; - - /** - * Protocol version. - */ - version: string; - - reserve_closing_delay: Duration; -} - -/** - * Wire fees as anounced by the exchange. - */ -export class WireFeesJson { - /** - * Cost of a wire transfer. - */ - wire_fee: string; - - /** - * Cost of clising a reserve. - */ - closing_fee: string; - - /** - * Signature made with the exchange's master key. - */ - sig: string; - - /** - * Date from which the fee applies. - */ - start_date: Timestamp; - - /** - * Data after which the fee doesn't apply anymore. - */ - end_date: Timestamp; -} - -export class AccountInfo { - payto_uri: string; - master_sig: string; -} - -export class ExchangeWireJson { - accounts: AccountInfo[]; - fees: { [methodName: string]: WireFeesJson[] }; -} - -/** - * Proposal returned from the contract URL. - */ -export class Proposal { - /** - * Contract terms for the propoal. - * Raw, un-decoded JSON object. - */ - contract_terms: any; - - /** - * Signature over contract, made by the merchant. The public key used for signing - * must be contract_terms.merchant_pub. - */ - sig: string; -} - -/** - * Response from the internal merchant API. - */ -export class CheckPaymentResponse { - order_status: string; - refunded: boolean | undefined; - refunded_amount: string | undefined; - contract_terms: any | undefined; - taler_pay_uri: string | undefined; - contract_url: string | undefined; -} - -/** - * Response from the bank. - */ -export class WithdrawOperationStatusResponse { - selection_done: boolean; - - transfer_done: boolean; - - aborted: boolean; - - amount: string; - - sender_wire?: string; - - suggested_exchange?: string; - - confirm_transfer_url?: string; - - wire_types: string[]; -} - -/** - * Response from the merchant. - */ -export class TipPickupGetResponse { - tip_amount: string; - - exchange_url: string; - - expiration: Timestamp; -} - -export class WithdrawResponse { - ev_sig: string; -} - -/** - * Easy to process format for the public data of coins - * managed by the wallet. - */ -export interface CoinDumpJson { - coins: Array<{ - /** - * The coin's denomination's public key. - */ - denom_pub: string; - /** - * Hash of denom_pub. - */ - denom_pub_hash: string; - /** - * Value of the denomination (without any fees). - */ - denom_value: string; - /** - * Public key of the coin. - */ - coin_pub: string; - /** - * Base URL of the exchange for the coin. - */ - exchange_base_url: string; - /** - * Remaining value on the coin, to the knowledge of - * the wallet. - */ - remaining_value: string; - /** - * Public key of the parent coin. - * Only present if this coin was obtained via refreshing. - */ - refresh_parent_coin_pub: string | undefined; - /** - * Public key of the reserve for this coin. - * Only present if this coin was obtained via refreshing. - */ - withdrawal_reserve_pub: string | undefined; - /** - * Is the coin suspended? - * Suspended coins are not considered for payments. - */ - coin_suspended: boolean; - }>; -} - -export interface MerchantPayResponse { - sig: string; -} - -export interface ExchangeMeltResponse { - /** - * Which of the kappa indices does the client not have to reveal. - */ - noreveal_index: number; - - /** - * Signature of TALER_RefreshMeltConfirmationPS whereby the exchange - * affirms the successful melt and confirming the noreveal_index - */ - exchange_sig: EddsaSignatureString; - - /* - * public EdDSA key of the exchange that was used to generate the signature. - * Should match one of the exchange's signing keys from /keys. Again given - * explicitly as the client might otherwise be confused by clock skew as to - * which signing key was used. - */ - exchange_pub: EddsaPublicKeyString; - - /* - * Base URL to use for operations on the refresh context - * (so the reveal operation). If not given, - * the base URL is the same as the one used for this request. - * Can be used if the base URL for /refreshes/ differs from that - * for /coins/, i.e. for load balancing. Clients SHOULD - * respect the refresh_base_url if provided. Any HTTP server - * belonging to an exchange MUST generate a 307 or 308 redirection - * to the correct base URL should a client uses the wrong base - * URL, or if the base URL has changed since the melt. - * - * When melting the same coin twice (technically allowed - * as the response might have been lost on the network), - * the exchange may return different values for the refresh_base_url. - */ - refresh_base_url?: string; -} - -export interface ExchangeRevealItem { - ev_sig: string; -} - -export interface ExchangeRevealResponse { - // List of the exchange's blinded RSA signatures on the new coins. - ev_sigs: ExchangeRevealItem[]; -} - -interface MerchantOrderStatusPaid { - /** - * Was the payment refunded (even partially, via refund or abort)? - */ - refunded: boolean; - - /** - * Amount that was refunded in total. - */ - refund_amount: AmountString; -} - -interface MerchantOrderRefundResponse { - /** - * Amount that was refunded in total. - */ - refund_amount: AmountString; - - /** - * Successful refunds for this payment, empty array for none. - */ - refunds: MerchantCoinRefundStatus[]; - - /** - * Public key of the merchant. - */ - merchant_pub: EddsaPublicKeyString; -} - -export type MerchantCoinRefundStatus = - | MerchantCoinRefundSuccessStatus - | MerchantCoinRefundFailureStatus; - -export interface MerchantCoinRefundSuccessStatus { - type: "success"; - - // HTTP status of the exchange request, 200 (integer) required for refund confirmations. - exchange_status: 200; - - // the EdDSA :ref:signature (binary-only) with purpose - // TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND using a current signing key of the - // exchange affirming the successful refund - exchange_sig: EddsaSignatureString; - - // public EdDSA key of the exchange that was used to generate the signature. - // Should match one of the exchange's signing keys from /keys. It is given - // explicitly as the client might otherwise be confused by clock skew as to - // which signing key was used. - exchange_pub: EddsaPublicKeyString; - - // Refund transaction ID. - rtransaction_id: number; - - // public key of a coin that was refunded - coin_pub: EddsaPublicKeyString; - - // Amount that was refunded, including refund fee charged by the exchange - // to the customer. - refund_amount: AmountString; - - execution_time: Timestamp; -} - -export interface MerchantCoinRefundFailureStatus { - type: "failure"; - - // HTTP status of the exchange request, must NOT be 200. - exchange_status: number; - - // Taler error code from the exchange reply, if available. - exchange_code?: number; - - // If available, HTTP reply from the exchange. - exchange_reply?: any; - - // Refund transaction ID. - rtransaction_id: number; - - // public key of a coin that was refunded - coin_pub: EddsaPublicKeyString; - - // Amount that was refunded, including refund fee charged by the exchange - // to the customer. - refund_amount: AmountString; - - execution_time: Timestamp; -} - -export interface MerchantOrderStatusUnpaid { - /** - * URI that the wallet must process to complete the payment. - */ - taler_pay_uri: string; - - /** - * Alternative order ID which was paid for already in the same session. - * - * Only given if the same product was purchased before in the same session. - */ - already_paid_order_id?: string; -} - -/** - * Response body for the following endpoint: - * - * POST {talerBankIntegrationApi}/withdrawal-operation/{wopid} - */ -export interface BankWithdrawalOperationPostResponse { - transfer_done: boolean; -} - -export const codecForBankWithdrawalOperationPostResponse = (): Codec< - BankWithdrawalOperationPostResponse -> => - buildCodecForObject<BankWithdrawalOperationPostResponse>() - .property("transfer_done", codecForBoolean()) - .build("BankWithdrawalOperationPostResponse"); - -export type AmountString = string; -export type Base32String = string; -export type EddsaSignatureString = string; -export type EddsaPublicKeyString = string; -export type CoinPublicKeyString = string; - -export const codecForDenomination = (): Codec<Denomination> => - buildCodecForObject<Denomination>() - .property("value", codecForString()) - .property("denom_pub", codecForString()) - .property("fee_withdraw", codecForString()) - .property("fee_deposit", codecForString()) - .property("fee_refresh", codecForString()) - .property("fee_refund", codecForString()) - .property("stamp_start", codecForTimestamp) - .property("stamp_expire_withdraw", codecForTimestamp) - .property("stamp_expire_legal", codecForTimestamp) - .property("stamp_expire_deposit", codecForTimestamp) - .property("master_sig", codecForString()) - .build("Denomination"); - -export const codecForAuditorDenomSig = (): Codec<AuditorDenomSig> => - buildCodecForObject<AuditorDenomSig>() - .property("denom_pub_h", codecForString()) - .property("auditor_sig", codecForString()) - .build("AuditorDenomSig"); - -export const codecForAuditor = (): Codec<Auditor> => - buildCodecForObject<Auditor>() - .property("auditor_pub", codecForString()) - .property("auditor_url", codecForString()) - .property("denomination_keys", codecForList(codecForAuditorDenomSig())) - .build("Auditor"); - -export const codecForExchangeHandle = (): Codec<ExchangeHandle> => - buildCodecForObject<ExchangeHandle>() - .property("master_pub", codecForString()) - .property("url", codecForString()) - .build("ExchangeHandle"); - -export const codecForAuditorHandle = (): Codec<AuditorHandle> => - buildCodecForObject<AuditorHandle>() - .property("name", codecForString()) - .property("auditor_pub", codecForString()) - .property("url", codecForString()) - .build("AuditorHandle"); - -export const codecForLocation = (): Codec<Location> => - buildCodecForObject<Location>() - .property("country", codecOptional(codecForString())) - .property("country_subdivision", codecOptional(codecForString())) - .property("building_name", codecOptional(codecForString())) - .property("building_number", codecOptional(codecForString())) - .property("district", codecOptional(codecForString())) - .property("street", codecOptional(codecForString())) - .property("post_code", codecOptional(codecForString())) - .property("town", codecOptional(codecForString())) - .property("town_location", codecOptional(codecForString())) - .property("address_lines", codecOptional(codecForList(codecForString()))) - .build("Location"); - -export const codecForMerchantInfo = (): Codec<MerchantInfo> => - buildCodecForObject<MerchantInfo>() - .property("name", codecForString()) - .property("address", codecOptional(codecForLocation())) - .property("jurisdiction", codecOptional(codecForLocation())) - .build("MerchantInfo"); - -export const codecForTax = (): Codec<Tax> => - buildCodecForObject<Tax>() - .property("name", codecForString()) - .property("tax", codecForString()) - .build("Tax"); - -export const codecForInternationalizedString = (): Codec< - InternationalizedString -> => codecForMap(codecForString()); - -export const codecForProduct = (): Codec<Product> => - buildCodecForObject<Product>() - .property("product_id", codecOptional(codecForString())) - .property("description", codecForString()) - .property( - "description_i18n", - codecOptional(codecForInternationalizedString()), - ) - .property("quantity", codecOptional(codecForNumber())) - .property("unit", codecOptional(codecForString())) - .property("price", codecOptional(codecForString())) - .build("Tax"); - -export const codecForContractTerms = (): Codec<ContractTerms> => - buildCodecForObject<ContractTerms>() - .property("order_id", codecForString()) - .property("fulfillment_url", codecOptional(codecForString())) - .property("fulfillment_message", codecOptional(codecForString())) - .property( - "fulfillment_message_i18n", - codecOptional(codecForInternationalizedString()), - ) - .property("merchant_base_url", codecForString()) - .property("h_wire", codecForString()) - .property("auto_refund", codecOptional(codecForDuration)) - .property("wire_method", codecForString()) - .property("summary", codecForString()) - .property("summary_i18n", codecOptional(codecForInternationalizedString())) - .property("nonce", codecForString()) - .property("amount", codecForString()) - .property("auditors", codecForList(codecForAuditorHandle())) - .property("pay_deadline", codecForTimestamp) - .property("refund_deadline", codecForTimestamp) - .property("wire_transfer_deadline", codecForTimestamp) - .property("timestamp", codecForTimestamp) - .property("delivery_location", codecOptional(codecForLocation())) - .property("delivery_date", codecOptional(codecForTimestamp)) - .property("max_fee", codecForString()) - .property("max_wire_fee", codecOptional(codecForString())) - .property("merchant", codecForMerchantInfo()) - .property("merchant_pub", codecForString()) - .property("exchanges", codecForList(codecForExchangeHandle())) - .property("products", codecOptional(codecForList(codecForProduct()))) - .property("extra", codecForAny()) - .build("ContractTerms"); - -export const codecForMerchantRefundPermission = (): Codec< - MerchantAbortPayRefundDetails -> => - buildCodecForObject<MerchantAbortPayRefundDetails>() - .property("refund_amount", codecForAmountString()) - .property("refund_fee", codecForAmountString()) - .property("coin_pub", codecForString()) - .property("rtransaction_id", codecForNumber()) - .property("exchange_http_status", codecForNumber()) - .property("exchange_code", codecOptional(codecForNumber())) - .property("exchange_reply", codecOptional(codecForAny())) - .property("exchange_sig", codecOptional(codecForString())) - .property("exchange_pub", codecOptional(codecForString())) - .build("MerchantRefundPermission"); - -export const codecForMerchantRefundResponse = (): Codec< - MerchantRefundResponse -> => - buildCodecForObject<MerchantRefundResponse>() - .property("merchant_pub", codecForString()) - .property("h_contract_terms", codecForString()) - .property("refunds", codecForList(codecForMerchantRefundPermission())) - .build("MerchantRefundResponse"); - -export const codecForBlindSigWrapper = (): Codec<BlindSigWrapper> => - buildCodecForObject<BlindSigWrapper>() - .property("blind_sig", codecForString()) - .build("BlindSigWrapper"); - -export const codecForTipResponse = (): Codec<TipResponse> => - buildCodecForObject<TipResponse>() - .property("blind_sigs", codecForList(codecForBlindSigWrapper())) - .build("TipResponse"); - -export const codecForRecoup = (): Codec<Recoup> => - buildCodecForObject<Recoup>() - .property("h_denom_pub", codecForString()) - .build("Recoup"); - -export const codecForExchangeSigningKey = (): Codec<ExchangeSignKeyJson> => - buildCodecForObject<ExchangeSignKeyJson>() - .property("key", codecForString()) - .property("master_sig", codecForString()) - .property("stamp_end", codecForTimestamp) - .property("stamp_start", codecForTimestamp) - .property("stamp_expire", codecForTimestamp) - .build("ExchangeSignKeyJson"); - -export const codecForExchangeKeysJson = (): Codec<ExchangeKeysJson> => - buildCodecForObject<ExchangeKeysJson>() - .property("denoms", codecForList(codecForDenomination())) - .property("master_public_key", codecForString()) - .property("auditors", codecForList(codecForAuditor())) - .property("list_issue_date", codecForTimestamp) - .property("recoup", codecOptional(codecForList(codecForRecoup()))) - .property("signkeys", codecForList(codecForExchangeSigningKey())) - .property("version", codecForString()) - .property("reserve_closing_delay", codecForDuration) - .build("KeysJson"); - -export const codecForWireFeesJson = (): Codec<WireFeesJson> => - buildCodecForObject<WireFeesJson>() - .property("wire_fee", codecForString()) - .property("closing_fee", codecForString()) - .property("sig", codecForString()) - .property("start_date", codecForTimestamp) - .property("end_date", codecForTimestamp) - .build("WireFeesJson"); - -export const codecForAccountInfo = (): Codec<AccountInfo> => - buildCodecForObject<AccountInfo>() - .property("payto_uri", codecForString()) - .property("master_sig", codecForString()) - .build("AccountInfo"); - -export const codecForExchangeWireJson = (): Codec<ExchangeWireJson> => - buildCodecForObject<ExchangeWireJson>() - .property("accounts", codecForList(codecForAccountInfo())) - .property("fees", codecForMap(codecForList(codecForWireFeesJson()))) - .build("ExchangeWireJson"); - -export const codecForProposal = (): Codec<Proposal> => - buildCodecForObject<Proposal>() - .property("contract_terms", codecForAny()) - .property("sig", codecForString()) - .build("Proposal"); - -export const codecForCheckPaymentResponse = (): Codec<CheckPaymentResponse> => - buildCodecForObject<CheckPaymentResponse>() - .property("order_status", codecForString()) - .property("refunded", codecOptional(codecForBoolean())) - .property("refunded_amount", codecOptional(codecForString())) - .property("contract_terms", codecOptional(codecForAny())) - .property("taler_pay_uri", codecOptional(codecForString())) - .property("contract_url", codecOptional(codecForString())) - .build("CheckPaymentResponse"); - -export const codecForWithdrawOperationStatusResponse = (): Codec< - WithdrawOperationStatusResponse -> => - buildCodecForObject<WithdrawOperationStatusResponse>() - .property("selection_done", codecForBoolean()) - .property("transfer_done", codecForBoolean()) - .property("aborted", codecForBoolean()) - .property("amount", codecForString()) - .property("sender_wire", codecOptional(codecForString())) - .property("suggested_exchange", codecOptional(codecForString())) - .property("confirm_transfer_url", codecOptional(codecForString())) - .property("wire_types", codecForList(codecForString())) - .build("WithdrawOperationStatusResponse"); - -export const codecForTipPickupGetResponse = (): Codec<TipPickupGetResponse> => - buildCodecForObject<TipPickupGetResponse>() - .property("tip_amount", codecForString()) - .property("exchange_url", codecForString()) - .property("expiration", codecForTimestamp) - .build("TipPickupGetResponse"); - -export const codecForRecoupConfirmation = (): Codec<RecoupConfirmation> => - buildCodecForObject<RecoupConfirmation>() - .property("reserve_pub", codecOptional(codecForString())) - .property("old_coin_pub", codecOptional(codecForString())) - .build("RecoupConfirmation"); - -export const codecForWithdrawResponse = (): Codec<WithdrawResponse> => - buildCodecForObject<WithdrawResponse>() - .property("ev_sig", codecForString()) - .build("WithdrawResponse"); - -export const codecForMerchantPayResponse = (): Codec<MerchantPayResponse> => - buildCodecForObject<MerchantPayResponse>() - .property("sig", codecForString()) - .build("MerchantPayResponse"); - -export const codecForExchangeMeltResponse = (): Codec<ExchangeMeltResponse> => - buildCodecForObject<ExchangeMeltResponse>() - .property("exchange_pub", codecForString()) - .property("exchange_sig", codecForString()) - .property("noreveal_index", codecForNumber()) - .property("refresh_base_url", codecOptional(codecForString())) - .build("ExchangeMeltResponse"); - -export const codecForExchangeRevealItem = (): Codec<ExchangeRevealItem> => - buildCodecForObject<ExchangeRevealItem>() - .property("ev_sig", codecForString()) - .build("ExchangeRevealItem"); - -export const codecForExchangeRevealResponse = (): Codec< - ExchangeRevealResponse -> => - buildCodecForObject<ExchangeRevealResponse>() - .property("ev_sigs", codecForList(codecForExchangeRevealItem())) - .build("ExchangeRevealResponse"); - -export const codecForMerchantCoinRefundSuccessStatus = (): Codec< - MerchantCoinRefundSuccessStatus -> => - buildCodecForObject<MerchantCoinRefundSuccessStatus>() - .property("type", codecForConstString("success")) - .property("coin_pub", codecForString()) - .property("exchange_status", codecForConstNumber(200)) - .property("exchange_sig", codecForString()) - .property("rtransaction_id", codecForNumber()) - .property("refund_amount", codecForString()) - .property("exchange_pub", codecForString()) - .property("execution_time", codecForTimestamp) - .build("MerchantCoinRefundSuccessStatus"); - -export const codecForMerchantCoinRefundFailureStatus = (): Codec< - MerchantCoinRefundFailureStatus -> => - buildCodecForObject<MerchantCoinRefundFailureStatus>() - .property("type", codecForConstString("failure")) - .property("coin_pub", codecForString()) - .property("exchange_status", codecForNumber()) - .property("rtransaction_id", codecForNumber()) - .property("refund_amount", codecForString()) - .property("exchange_code", codecOptional(codecForNumber())) - .property("exchange_reply", codecOptional(codecForAny())) - .property("execution_time", codecForTimestamp) - .build("MerchantCoinRefundFailureStatus"); - -export const codecForMerchantCoinRefundStatus = (): Codec< - MerchantCoinRefundStatus -> => - buildCodecForUnion<MerchantCoinRefundStatus>() - .discriminateOn("type") - .alternative("success", codecForMerchantCoinRefundSuccessStatus()) - .alternative("failure", codecForMerchantCoinRefundFailureStatus()) - .build("MerchantCoinRefundStatus"); - -export const codecForMerchantOrderStatusPaid = (): Codec< - MerchantOrderStatusPaid -> => - buildCodecForObject<MerchantOrderStatusPaid>() - .property("refund_amount", codecForString()) - .property("refunded", codecForBoolean()) - .build("MerchantOrderStatusPaid"); - -export const codecForMerchantOrderRefundPickupResponse = (): Codec< - MerchantOrderRefundResponse -> => - buildCodecForObject<MerchantOrderRefundResponse>() - .property("merchant_pub", codecForString()) - .property("refund_amount", codecForString()) - .property("refunds", codecForList(codecForMerchantCoinRefundStatus())) - .build("MerchantOrderRefundPickupResponse"); - -export const codecForMerchantOrderStatusUnpaid = (): Codec< - MerchantOrderStatusUnpaid -> => - buildCodecForObject<MerchantOrderStatusUnpaid>() - .property("taler_pay_uri", codecForString()) - .property("already_paid_order_id", codecOptional(codecForString())) - .build("MerchantOrderStatusUnpaid"); - -export interface AbortRequest { - // hash of the order's contract terms (this is used to authenticate the - // wallet/customer in case $ORDER_ID is guessable). - h_contract: string; - - // List of coins the wallet would like to see refunds for. - // (Should be limited to the coins for which the original - // payment succeeded, as far as the wallet knows.) - coins: AbortingCoin[]; -} - -export interface AbortingCoin { - // Public key of a coin for which the wallet is requesting an abort-related refund. - coin_pub: EddsaPublicKeyString; - - // The amount to be refunded (matches the original contribution) - contribution: AmountString; - - // URL of the exchange this coin was withdrawn from. - exchange_url: string; -} - -export interface AbortResponse { - // List of refund responses about the coins that the wallet - // requested an abort for. In the same order as the 'coins' - // from the original request. - // The rtransaction_id is implied to be 0. - refunds: MerchantAbortPayRefundStatus[]; -} - -export const codecForAbortResponse = (): Codec<AbortResponse> => - buildCodecForObject<AbortResponse>() - .property("refunds", codecForList(codecForMerchantAbortPayRefundStatus())) - .build("AbortResponse"); - -export type MerchantAbortPayRefundStatus = - | MerchantAbortPayRefundSuccessStatus - | MerchantAbortPayRefundFailureStatus; - -// Details about why a refund failed. -export interface MerchantAbortPayRefundFailureStatus { - // Used as tag for the sum type RefundStatus sum type. - type: "failure"; - - // HTTP status of the exchange request, must NOT be 200. - exchange_status: number; - - // Taler error code from the exchange reply, if available. - exchange_code?: number; - - // If available, HTTP reply from the exchange. - exchange_reply?: unknown; -} - -// Additional details needed to verify the refund confirmation signature -// (h_contract_terms and merchant_pub) are already known -// to the wallet and thus not included. -export interface MerchantAbortPayRefundSuccessStatus { - // Used as tag for the sum type MerchantCoinRefundStatus sum type. - type: "success"; - - // HTTP status of the exchange request, 200 (integer) required for refund confirmations. - exchange_status: 200; - - // the EdDSA :ref:signature (binary-only) with purpose - // TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND using a current signing key of the - // exchange affirming the successful refund - exchange_sig: string; - - // public EdDSA key of the exchange that was used to generate the signature. - // Should match one of the exchange's signing keys from /keys. It is given - // explicitly as the client might otherwise be confused by clock skew as to - // which signing key was used. - exchange_pub: string; -} - -export const codecForMerchantAbortPayRefundSuccessStatus = (): Codec< - MerchantAbortPayRefundSuccessStatus -> => - buildCodecForObject<MerchantAbortPayRefundSuccessStatus>() - .property("exchange_pub", codecForString()) - .property("exchange_sig", codecForString()) - .property("exchange_status", codecForConstNumber(200)) - .property("type", codecForConstString("success")) - .build("MerchantAbortPayRefundSuccessStatus"); - -export const codecForMerchantAbortPayRefundFailureStatus = (): Codec< - MerchantAbortPayRefundFailureStatus -> => - buildCodecForObject<MerchantAbortPayRefundFailureStatus>() - .property("exchange_code", codecForNumber()) - .property("exchange_reply", codecForAny()) - .property("exchange_status", codecForNumber()) - .property("type", codecForConstString("failure")) - .build("MerchantAbortPayRefundFailureStatus"); - -export const codecForMerchantAbortPayRefundStatus = (): Codec< - MerchantAbortPayRefundStatus -> => - buildCodecForUnion<MerchantAbortPayRefundStatus>() - .discriminateOn("type") - .alternative("success", codecForMerchantAbortPayRefundSuccessStatus()) - .alternative("failure", codecForMerchantAbortPayRefundFailureStatus()) - .build("MerchantAbortPayRefundStatus"); - -export interface TalerConfigResponse { - name: string; - version: string; - currency?: string; -} - -export const codecForTalerConfigResponse = (): Codec<TalerConfigResponse> => - buildCodecForObject<TalerConfigResponse>() - .property("name", codecForString()) - .property("version", codecForString()) - .property("currency", codecOptional(codecForString())) - .build("TalerConfigResponse"); diff --git a/packages/taler-wallet-core/src/types/transactionsTypes.ts b/packages/taler-wallet-core/src/types/transactionsTypes.ts deleted file mode 100644 index 81dc78039..000000000 --- a/packages/taler-wallet-core/src/types/transactionsTypes.ts +++ /dev/null @@ -1,364 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2019 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - 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/> - */ - -/** - * Type and schema definitions for the wallet's transaction list. - * - * @author Florian Dold - * @author Torsten Grote - */ - -/** - * Imports. - */ -import { Timestamp } from "../util/time"; -import { - AmountString, - Product, - InternationalizedString, - MerchantInfo, - codecForInternationalizedString, - codecForMerchantInfo, - codecForProduct, -} from "./talerTypes"; -import { - Codec, - buildCodecForObject, - codecOptional, - codecForString, - codecForList, - codecForAny, -} from "../util/codec"; -import { TalerErrorDetails } from "./walletTypes"; - -export interface TransactionsRequest { - /** - * return only transactions in the given currency - */ - currency?: string; - - /** - * if present, results will be limited to transactions related to the given search string - */ - search?: string; -} - -export interface TransactionsResponse { - // a list of past and pending transactions sorted by pending, timestamp and transactionId. - // In case two events are both pending and have the same timestamp, - // they are sorted by the transactionId - // (lexically ascending and locale-independent comparison). - transactions: Transaction[]; -} - -export interface TransactionCommon { - // opaque unique ID for the transaction, used as a starting point for paginating queries - // and for invoking actions on the transaction (e.g. deleting/hiding it from the history) - transactionId: string; - - // the type of the transaction; different types might provide additional information - type: TransactionType; - - // main timestamp of the transaction - timestamp: Timestamp; - - // true if the transaction is still pending, false otherwise - // If a transaction is not longer pending, its timestamp will be updated, - // but its transactionId will remain unchanged - pending: boolean; - - // Raw amount of the transaction (exclusive of fees or other extra costs) - amountRaw: AmountString; - - // Amount added or removed from the wallet's balance (including all fees and other costs) - amountEffective: AmountString; - - error?: TalerErrorDetails; -} - -export type Transaction = - | TransactionWithdrawal - | TransactionPayment - | TransactionRefund - | TransactionTip - | TransactionRefresh - | TransactionDeposit; - -export enum TransactionType { - Withdrawal = "withdrawal", - Payment = "payment", - Refund = "refund", - Refresh = "refresh", - Tip = "tip", - Deposit = "deposit", -} - -export enum WithdrawalType { - TalerBankIntegrationApi = "taler-bank-integration-api", - ManualTransfer = "manual-transfer", -} - -export type WithdrawalDetails = - | WithdrawalDetailsForManualTransfer - | WithdrawalDetailsForTalerBankIntegrationApi; - -interface WithdrawalDetailsForManualTransfer { - type: WithdrawalType.ManualTransfer; - - /** - * Payto URIs that the exchange supports. - * - * Already contains the amount and message. - */ - exchangePaytoUris: string[]; -} - -interface WithdrawalDetailsForTalerBankIntegrationApi { - type: WithdrawalType.TalerBankIntegrationApi; - - /** - * Set to true if the bank has confirmed the withdrawal, false if not. - * An unconfirmed withdrawal usually requires user-input and should be highlighted in the UI. - * See also bankConfirmationUrl below. - */ - confirmed: boolean; - - /** - * If the withdrawal is unconfirmed, this can include a URL for user - * initiated confirmation. - */ - bankConfirmationUrl?: string; -} - -// This should only be used for actual withdrawals -// and not for tips that have their own transactions type. -interface TransactionWithdrawal extends TransactionCommon { - type: TransactionType.Withdrawal; - - /** - * Exchange of the withdrawal. - */ - exchangeBaseUrl: string; - - /** - * Amount that got subtracted from the reserve balance. - */ - amountRaw: AmountString; - - /** - * Amount that actually was (or will be) added to the wallet's balance. - */ - amountEffective: AmountString; - - withdrawalDetails: WithdrawalDetails; -} - -export enum PaymentStatus { - /** - * Explicitly aborted after timeout / failure - */ - Aborted = "aborted", - - /** - * Payment failed, wallet will auto-retry. - * User should be given the option to retry now / abort. - */ - Failed = "failed", - - /** - * Paid successfully - */ - Paid = "paid", - - /** - * User accepted, payment is processing. - */ - Accepted = "accepted", -} - -export interface TransactionPayment extends TransactionCommon { - type: TransactionType.Payment; - - /** - * Additional information about the payment. - */ - info: OrderShortInfo; - - /** - * Wallet-internal end-to-end identifier for the payment. - */ - proposalId: string; - - /** - * How far did the wallet get with processing the payment? - */ - status: PaymentStatus; - - /** - * Amount that must be paid for the contract - */ - amountRaw: AmountString; - - /** - * Amount that was paid, including deposit, wire and refresh fees. - */ - amountEffective: AmountString; -} - -export interface OrderShortInfo { - /** - * Order ID, uniquely identifies the order within a merchant instance - */ - orderId: string; - - /** - * Hash of the contract terms. - */ - contractTermsHash: string; - - /** - * More information about the merchant - */ - merchant: MerchantInfo; - - /** - * Summary of the order, given by the merchant - */ - summary: string; - - /** - * Map from IETF BCP 47 language tags to localized summaries - */ - summary_i18n?: InternationalizedString; - - /** - * List of products that are part of the order - */ - products: Product[] | undefined; - - /** - * URL of the fulfillment, given by the merchant - */ - fulfillmentUrl?: string; - - /** - * Plain text message that should be shown to the user - * when the payment is complete. - */ - fulfillmentMessage?: string; - - /** - * Translations of fulfillmentMessage. - */ - fulfillmentMessage_i18n?: InternationalizedString; -} - -interface TransactionRefund extends TransactionCommon { - type: TransactionType.Refund; - - // ID for the transaction that is refunded - refundedTransactionId: string; - - // Additional information about the refunded payment - info: OrderShortInfo; - - // Amount that has been refunded by the merchant - amountRaw: AmountString; - - // Amount will be added to the wallet's balance after fees and refreshing - amountEffective: AmountString; -} - -interface TransactionTip extends TransactionCommon { - type: TransactionType.Tip; - - // Raw amount of the tip, without extra fees that apply - amountRaw: AmountString; - - // Amount will be (or was) added to the wallet's balance after fees and refreshing - amountEffective: AmountString; - - merchantBaseUrl: string; -} - -// A transaction shown for refreshes that are not associated to other transactions -// such as a refresh necessary before coin expiration. -// It should only be returned by the API if the effective amount is different from zero. -interface TransactionRefresh extends TransactionCommon { - type: TransactionType.Refresh; - - // Exchange that the coins are refreshed with - exchangeBaseUrl: string; - - // Raw amount that is refreshed - amountRaw: AmountString; - - // Amount that will be paid as fees for the refresh - amountEffective: AmountString; -} - -/** - * Deposit transaction, which effectively sends - * money from this wallet somewhere else. - */ -interface TransactionDeposit extends TransactionCommon { - type: TransactionType.Deposit; - - depositGroupId: string; - - /** - * Target for the deposit. - */ - targetPaytoUri: string; - - /** - * Raw amount that is being deposited - */ - amountRaw: AmountString; - - /** - * Effective amount that is being deposited - */ - amountEffective: AmountString; -} - -export const codecForTransactionsRequest = (): Codec<TransactionsRequest> => - buildCodecForObject<TransactionsRequest>() - .property("currency", codecOptional(codecForString())) - .property("search", codecOptional(codecForString())) - .build("TransactionsRequest"); - -// FIXME: do full validation here! -export const codecForTransactionsResponse = (): Codec<TransactionsResponse> => - buildCodecForObject<TransactionsResponse>() - .property("transactions", codecForList(codecForAny())) - .build("TransactionsResponse"); - -export const codecForOrderShortInfo = (): Codec<OrderShortInfo> => - buildCodecForObject<OrderShortInfo>() - .property("contractTermsHash", codecForString()) - .property("fulfillmentMessage", codecOptional(codecForString())) - .property( - "fulfillmentMessage_i18n", - codecOptional(codecForInternationalizedString()), - ) - .property("fulfillmentUrl", codecOptional(codecForString())) - .property("merchant", codecForMerchantInfo()) - .property("orderId", codecForString()) - .property("products", codecOptional(codecForList(codecForProduct()))) - .property("summary", codecForString()) - .property("summary_i18n", codecOptional(codecForInternationalizedString())) - .build("OrderShortInfo"); diff --git a/packages/taler-wallet-core/src/types/types-test.ts b/packages/taler-wallet-core/src/types/types-test.ts deleted file mode 100644 index 19c9b5aa6..000000000 --- a/packages/taler-wallet-core/src/types/types-test.ts +++ /dev/null @@ -1,93 +0,0 @@ -/* - This file is part of TALER - (C) 2017 Inria and GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -import test from "ava"; -import { codecForContractTerms } from "./talerTypes"; - -test("contract terms validation", (t) => { - const c = { - nonce: "123123123", - h_wire: "123", - amount: "EUR:1.5", - auditors: [], - exchanges: [{ master_pub: "foo", url: "foo" }], - fulfillment_url: "foo", - max_fee: "EUR:1.5", - merchant_pub: "12345", - merchant: { name: "Foo" }, - order_id: "test_order", - pay_deadline: { t_ms: 42 }, - wire_transfer_deadline: { t_ms: 42 }, - merchant_base_url: "https://example.com/pay", - products: [], - refund_deadline: { t_ms: 42 }, - summary: "hello", - timestamp: { t_ms: 42 }, - wire_method: "test", - }; - - codecForContractTerms().decode(c); - - const c1 = JSON.parse(JSON.stringify(c)); - c1.pay_deadline = "foo"; - - try { - codecForContractTerms().decode(c1); - } catch (e) { - t.pass(); - return; - } - - t.fail(); -}); - -test("contract terms validation (locations)", (t) => { - const c = { - nonce: "123123123", - h_wire: "123", - amount: "EUR:1.5", - auditors: [], - exchanges: [{ master_pub: "foo", url: "foo" }], - fulfillment_url: "foo", - max_fee: "EUR:1.5", - merchant_pub: "12345", - merchant: { - name: "Foo", - address: { - country: "DE", - }, - }, - order_id: "test_order", - pay_deadline: { t_ms: 42 }, - wire_transfer_deadline: { t_ms: 42 }, - merchant_base_url: "https://example.com/pay", - products: [], - refund_deadline: { t_ms: 42 }, - summary: "hello", - timestamp: { t_ms: 42 }, - wire_method: "test", - delivery_location: { - country: "FR", - town: "Rennes", - }, - }; - - const r = codecForContractTerms().decode(c); - - t.assert(r.merchant.address?.country === "DE"); - t.assert(r.delivery_location?.country === "FR"); - t.assert(r.delivery_location?.town === "Rennes"); -}); diff --git a/packages/taler-wallet-core/src/types/walletTypes.ts b/packages/taler-wallet-core/src/types/walletTypes.ts deleted file mode 100644 index 9ecca059b..000000000 --- a/packages/taler-wallet-core/src/types/walletTypes.ts +++ /dev/null @@ -1,1026 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2015-2020 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * Types used by clients of the wallet. - * - * These types are defined in a separate file make tree shaking easier, since - * some components use these types (via RPC) but do not depend on the wallet - * code directly. - * - * @author Florian Dold <dold@taler.net> - */ - -/** - * Imports. - */ -import { - AmountJson, - codecForAmountJson, - codecForAmountString, -} from "../util/amounts"; -import * as LibtoolVersion from "../util/libtoolVersion"; -import { - ExchangeRecord, - ExchangeWireInfo, - DenominationSelectionInfo, -} from "./dbTypes"; -import { Timestamp, codecForTimestamp } from "../util/time"; -import { - buildCodecForObject, - codecForString, - codecOptional, - Codec, - codecForList, - codecForBoolean, - codecForConstString, - codecForAny, - buildCodecForUnion, -} from "../util/codec"; -import { - AmountString, - codecForContractTerms, - ContractTerms, -} from "./talerTypes"; -import { OrderShortInfo, codecForOrderShortInfo } from "./transactionsTypes"; -import { BackupRecovery } from "../operations/backup"; - -/** - * Response for the create reserve request to the wallet. - */ -export class CreateReserveResponse { - /** - * Exchange URL where the bank should create the reserve. - * The URL is canonicalized in the response. - */ - exchange: string; - - /** - * Reserve public key of the newly created reserve. - */ - reservePub: string; -} - -/** - * Information about what will happen when creating a reserve. - * - * Sent to the wallet frontend to be rendered and shown to the user. - */ -export interface ExchangeWithdrawDetails { - /** - * Exchange that the reserve will be created at. - */ - exchangeInfo: ExchangeRecord; - - /** - * Filtered wire info to send to the bank. - */ - exchangeWireAccounts: string[]; - - /** - * Selected denominations for withdraw. - */ - selectedDenoms: DenominationSelectionInfo; - - /** - * Fees for withdraw. - */ - withdrawFee: AmountJson; - - /** - * Remaining balance that is too small to be withdrawn. - */ - overhead: AmountJson; - - /** - * Wire fees from the exchange. - */ - wireFees: ExchangeWireInfo; - - /** - * Does the wallet know about an auditor for - * the exchange that the reserve. - */ - isAudited: boolean; - - /** - * Did the user already accept the current terms of service for the exchange? - */ - termsOfServiceAccepted: boolean; - - /** - * The exchange is trusted directly. - */ - isTrusted: boolean; - - /** - * The earliest deposit expiration of the selected coins. - */ - earliestDepositExpiration: Timestamp; - - /** - * Number of currently offered denominations. - */ - numOfferedDenoms: number; - - /** - * Public keys of trusted auditors for the currency we're withdrawing. - */ - trustedAuditorPubs: string[]; - - /** - * Result of checking the wallet's version - * against the exchange's version. - * - * Older exchanges don't return version information. - */ - versionMatch: LibtoolVersion.VersionMatchResult | undefined; - - /** - * Libtool-style version string for the exchange or "unknown" - * for older exchanges. - */ - exchangeVersion: string; - - /** - * Libtool-style version string for the wallet. - */ - walletVersion: string; -} - -export interface Balance { - available: AmountString; - pendingIncoming: AmountString; - pendingOutgoing: AmountString; - - // Does the balance for this currency have a pending - // transaction? - hasPendingTransactions: boolean; - - // Is there a pending transaction that would affect the balance - // and requires user input? - requiresUserInput: boolean; -} - -export interface BalancesResponse { - balances: Balance[]; -} - -export const codecForBalance = (): Codec<Balance> => - buildCodecForObject<Balance>() - .property("available", codecForString()) - .property("hasPendingTransactions", codecForBoolean()) - .property("pendingIncoming", codecForString()) - .property("pendingOutgoing", codecForString()) - .property("requiresUserInput", codecForBoolean()) - .build("Balance"); - -export const codecForBalancesResponse = (): Codec<BalancesResponse> => - buildCodecForObject<BalancesResponse>() - .property("balances", codecForList(codecForBalance())) - .build("BalancesResponse"); - -/** - * For terseness. - */ -export function mkAmount( - value: number, - fraction: number, - currency: string, -): AmountJson { - return { value, fraction, currency }; -} - -export enum ConfirmPayResultType { - Done = "done", - Pending = "pending", -} - -/** - * Result for confirmPay - */ -export interface ConfirmPayResultDone { - type: ConfirmPayResultType.Done; - contractTerms: ContractTerms; -} - -export interface ConfirmPayResultPending { - type: ConfirmPayResultType.Pending; - - lastError: TalerErrorDetails; -} - -export type ConfirmPayResult = ConfirmPayResultDone | ConfirmPayResultPending; - -export const codecForConfirmPayResultPending = (): Codec<ConfirmPayResultPending> => - buildCodecForObject<ConfirmPayResultPending>() - .property("lastError", codecForAny()) - .property("type", codecForConstString(ConfirmPayResultType.Pending)) - .build("ConfirmPayResultPending"); - -export const codecForConfirmPayResultDone = (): Codec<ConfirmPayResultDone> => - buildCodecForObject<ConfirmPayResultDone>() - .property("type", codecForConstString(ConfirmPayResultType.Done)) - .property("contractTerms", codecForContractTerms()) - .build("ConfirmPayResultDone"); - -export const codecForConfirmPayResult = (): Codec<ConfirmPayResult> => - buildCodecForUnion<ConfirmPayResult>() - .discriminateOn("type") - .alternative( - ConfirmPayResultType.Pending, - codecForConfirmPayResultPending(), - ) - .alternative(ConfirmPayResultType.Done, codecForConfirmPayResultDone()) - .build("ConfirmPayResult"); - -/** - * Information about all sender wire details known to the wallet, - * as well as exchanges that accept these wire types. - */ -export interface SenderWireInfos { - /** - * Mapping from exchange base url to list of accepted - * wire types. - */ - exchangeWireTypes: { [exchangeBaseUrl: string]: string[] }; - - /** - * Sender wire information stored in the wallet. - */ - senderWires: string[]; -} - -/** - * Request to create a reserve. - */ -export interface CreateReserveRequest { - /** - * The initial amount for the reserve. - */ - amount: AmountJson; - - /** - * Exchange URL where the bank should create the reserve. - */ - exchange: string; - - /** - * Payto URI that identifies the exchange's account that the funds - * for this reserve go into. - */ - exchangePaytoUri?: string; - - /** - * Wire details (as a payto URI) for the bank account that sent the funds to - * the exchange. - */ - senderWire?: string; - - /** - * URL to fetch the withdraw status from the bank. - */ - bankWithdrawStatusUrl?: string; -} - -export const codecForCreateReserveRequest = (): Codec<CreateReserveRequest> => - buildCodecForObject<CreateReserveRequest>() - .property("amount", codecForAmountJson()) - .property("exchange", codecForString()) - .property("exchangePaytoUri", codecForString()) - .property("senderWire", codecOptional(codecForString())) - .property("bankWithdrawStatusUrl", codecOptional(codecForString())) - .build("CreateReserveRequest"); - -/** - * Request to mark a reserve as confirmed. - */ -export interface ConfirmReserveRequest { - /** - * Public key of then reserve that should be marked - * as confirmed. - */ - reservePub: string; -} - -export const codecForConfirmReserveRequest = (): Codec<ConfirmReserveRequest> => - buildCodecForObject<ConfirmReserveRequest>() - .property("reservePub", codecForString()) - .build("ConfirmReserveRequest"); - -/** - * Wire coins to the user's own bank account. - */ -export class ReturnCoinsRequest { - /** - * The amount to wire. - */ - amount: AmountJson; - - /** - * The exchange to take the coins from. - */ - exchange: string; - - /** - * Wire details for the bank account of the customer that will - * receive the funds. - */ - senderWire?: string; - - /** - * Verify that a value matches the schema of this class and convert it into a - * member. - */ - static checked: (obj: any) => ReturnCoinsRequest; -} - -export interface PrepareTipResult { - /** - * Unique ID for the tip assigned by the wallet. - * Typically different from the merchant-generated tip ID. - */ - walletTipId: string; - - /** - * Has the tip already been accepted? - */ - accepted: boolean; - - /** - * Amount that the merchant gave. - */ - tipAmountRaw: AmountString; - - /** - * Amount that arrived at the wallet. - * Might be lower than the raw amount due to fees. - */ - tipAmountEffective: AmountString; - - /** - * Base URL of the merchant backend giving then tip. - */ - merchantBaseUrl: string; - - /** - * Base URL of the exchange that is used to withdraw the tip. - * Determined by the merchant, the wallet/user has no choice here. - */ - exchangeBaseUrl: string; - - /** - * Time when the tip will expire. After it expired, it can't be picked - * up anymore. - */ - expirationTimestamp: Timestamp; -} - -export const codecForPrepareTipResult = (): Codec<PrepareTipResult> => - buildCodecForObject<PrepareTipResult>() - .property("accepted", codecForBoolean()) - .property("tipAmountRaw", codecForAmountString()) - .property("tipAmountEffective", codecForAmountString()) - .property("exchangeBaseUrl", codecForString()) - .property("merchantBaseUrl", codecForString()) - .property("expirationTimestamp", codecForTimestamp) - .property("walletTipId", codecForString()) - .build("PrepareTipResult"); - -export interface BenchmarkResult { - time: { [s: string]: number }; - repetitions: number; -} - -export enum PreparePayResultType { - PaymentPossible = "payment-possible", - InsufficientBalance = "insufficient-balance", - AlreadyConfirmed = "already-confirmed", -} - -export const codecForPreparePayResultPaymentPossible = (): Codec<PreparePayResultPaymentPossible> => - buildCodecForObject<PreparePayResultPaymentPossible>() - .property("amountEffective", codecForAmountString()) - .property("amountRaw", codecForAmountString()) - .property("contractTerms", codecForContractTerms()) - .property("proposalId", codecForString()) - .property( - "status", - codecForConstString(PreparePayResultType.PaymentPossible), - ) - .build("PreparePayResultPaymentPossible"); - -export const codecForPreparePayResultInsufficientBalance = (): Codec<PreparePayResultInsufficientBalance> => - buildCodecForObject<PreparePayResultInsufficientBalance>() - .property("amountRaw", codecForAmountString()) - .property("contractTerms", codecForAny()) - .property("proposalId", codecForString()) - .property( - "status", - codecForConstString(PreparePayResultType.InsufficientBalance), - ) - .build("PreparePayResultInsufficientBalance"); - -export const codecForPreparePayResultAlreadyConfirmed = (): Codec<PreparePayResultAlreadyConfirmed> => - buildCodecForObject<PreparePayResultAlreadyConfirmed>() - .property( - "status", - codecForConstString(PreparePayResultType.AlreadyConfirmed), - ) - .property("amountEffective", codecForAmountString()) - .property("amountRaw", codecForAmountString()) - .property("paid", codecForBoolean()) - .property("contractTerms", codecForAny()) - .property("contractTermsHash", codecForString()) - .property("proposalId", codecForString()) - .build("PreparePayResultAlreadyConfirmed"); - -export const codecForPreparePayResult = (): Codec<PreparePayResult> => - buildCodecForUnion<PreparePayResult>() - .discriminateOn("status") - .alternative( - PreparePayResultType.AlreadyConfirmed, - codecForPreparePayResultAlreadyConfirmed(), - ) - .alternative( - PreparePayResultType.InsufficientBalance, - codecForPreparePayResultInsufficientBalance(), - ) - .alternative( - PreparePayResultType.PaymentPossible, - codecForPreparePayResultPaymentPossible(), - ) - .build("PreparePayResult"); - -export type PreparePayResult = - | PreparePayResultInsufficientBalance - | PreparePayResultAlreadyConfirmed - | PreparePayResultPaymentPossible; - -export interface PreparePayResultPaymentPossible { - status: PreparePayResultType.PaymentPossible; - proposalId: string; - contractTerms: ContractTerms; - amountRaw: string; - amountEffective: string; -} - -export interface PreparePayResultInsufficientBalance { - status: PreparePayResultType.InsufficientBalance; - proposalId: string; - contractTerms: ContractTerms; - amountRaw: string; -} - -export interface PreparePayResultAlreadyConfirmed { - status: PreparePayResultType.AlreadyConfirmed; - contractTerms: ContractTerms; - paid: boolean; - amountRaw: string; - amountEffective: string; - contractTermsHash: string; - proposalId: string; -} - -export interface BankWithdrawDetails { - selectionDone: boolean; - transferDone: boolean; - amount: AmountJson; - senderWire?: string; - suggestedExchange?: string; - confirmTransferUrl?: string; - wireTypes: string[]; - extractedStatusUrl: string; -} - -export interface AcceptWithdrawalResponse { - reservePub: string; - confirmTransferUrl?: string; -} - -/** - * Details about a purchase, including refund status. - */ -export interface PurchaseDetails { - contractTerms: Record<string, undefined>; - hasRefund: boolean; - totalRefundAmount: AmountJson; - totalRefundAndRefreshFees: AmountJson; -} - -export interface WalletDiagnostics { - walletManifestVersion: string; - walletManifestDisplayVersion: string; - errors: string[]; - firefoxIdbProblem: boolean; - dbOutdated: boolean; -} - -export interface TalerErrorDetails { - code: number; - hint: string; - message: string; - details: unknown; -} - -export interface PlanchetCreationResult { - coinPub: string; - coinPriv: string; - reservePub: string; - denomPubHash: string; - denomPub: string; - blindingKey: string; - withdrawSig: string; - coinEv: string; - coinValue: AmountJson; - coinEvHash: string; -} - -export interface PlanchetCreationRequest { - secretSeed: string; - coinIndex: number; - value: AmountJson; - feeWithdraw: AmountJson; - denomPub: string; - reservePub: string; - reservePriv: string; -} - -/** - * Reasons for why a coin is being refreshed. - */ -export enum RefreshReason { - Manual = "manual", - Pay = "pay", - Refund = "refund", - AbortPay = "abort-pay", - Recoup = "recoup", - BackupRestored = "backup-restored", - Scheduled = "scheduled", -} - -/** - * Wrapper for coin public keys. - */ -export interface CoinPublicKey { - readonly coinPub: string; -} - -/** - * Wrapper for refresh group IDs. - */ -export interface RefreshGroupId { - readonly refreshGroupId: string; -} - -/** - * Private data required to make a deposit permission. - */ -export interface DepositInfo { - exchangeBaseUrl: string; - contractTermsHash: string; - coinPub: string; - coinPriv: string; - spendAmount: AmountJson; - timestamp: Timestamp; - refundDeadline: Timestamp; - merchantPub: string; - feeDeposit: AmountJson; - wireInfoHash: string; - denomPubHash: string; - denomSig: string; -} - -export interface ExchangesListRespose { - exchanges: ExchangeListItem[]; -} - -export interface ExchangeListItem { - exchangeBaseUrl: string; - currency: string; - paytoUris: string[]; -} - -export const codecForExchangeListItem = (): Codec<ExchangeListItem> => - buildCodecForObject<ExchangeListItem>() - .property("currency", codecForString()) - .property("exchangeBaseUrl", codecForString()) - .property("paytoUris", codecForList(codecForString())) - .build("ExchangeListItem"); - -export const codecForExchangesListResponse = (): Codec<ExchangesListRespose> => - buildCodecForObject<ExchangesListRespose>() - .property("exchanges", codecForList(codecForExchangeListItem())) - .build("ExchangesListRespose"); - -export interface AcceptManualWithdrawalResult { - /** - * Payto URIs that can be used to fund the withdrawal. - */ - exchangePaytoUris: string[]; - - /** - * Public key of the newly created reserve. - */ - reservePub: string; -} - -export interface ManualWithdrawalDetails { - /** - * Did the user accept the current version of the exchange's - * terms of service? - */ - tosAccepted: boolean; - - /** - * Amount that the user will transfer to the exchange. - */ - amountRaw: AmountString; - - /** - * Amount that will be added to the user's wallet balance. - */ - amountEffective: AmountString; - - /** - * Ways to pay the exchange. - */ - paytoUris: string[]; -} - -export interface GetExchangeTosResult { - /** - * Markdown version of the current ToS. - */ - tos: string; - - /** - * Version tag of the current ToS. - */ - currentEtag: string; - - /** - * Version tag of the last ToS that the user has accepted, - * if any. - */ - acceptedEtag: string | undefined; -} - -export interface TestPayArgs { - merchantBaseUrl: string; - merchantAuthToken?: string; - amount: string; - summary: string; -} - -export const codecForTestPayArgs = (): Codec<TestPayArgs> => - buildCodecForObject<TestPayArgs>() - .property("merchantBaseUrl", codecForString()) - .property("merchantAuthToken", codecOptional(codecForString())) - .property("amount", codecForString()) - .property("summary", codecForString()) - .build("TestPayArgs"); - -export interface IntegrationTestArgs { - exchangeBaseUrl: string; - bankBaseUrl: string; - merchantBaseUrl: string; - merchantAuthToken?: string; - amountToWithdraw: string; - amountToSpend: string; -} - -export const codecForIntegrationTestArgs = (): Codec<IntegrationTestArgs> => - buildCodecForObject<IntegrationTestArgs>() - .property("exchangeBaseUrl", codecForString()) - .property("bankBaseUrl", codecForString()) - .property("merchantBaseUrl", codecForString()) - .property("merchantAuthToken", codecOptional(codecForString())) - .property("amountToSpend", codecForAmountString()) - .property("amountToWithdraw", codecForAmountString()) - .build("IntegrationTestArgs"); - -export interface AddExchangeRequest { - exchangeBaseUrl: string; -} - -export const codecForAddExchangeRequest = (): Codec<AddExchangeRequest> => - buildCodecForObject<AddExchangeRequest>() - .property("exchangeBaseUrl", codecForString()) - .build("AddExchangeRequest"); - -export interface ForceExchangeUpdateRequest { - exchangeBaseUrl: string; -} - -export const codecForForceExchangeUpdateRequest = (): Codec<AddExchangeRequest> => - buildCodecForObject<AddExchangeRequest>() - .property("exchangeBaseUrl", codecForString()) - .build("AddExchangeRequest"); - -export interface GetExchangeTosRequest { - exchangeBaseUrl: string; -} - -export const codecForGetExchangeTosRequest = (): Codec<GetExchangeTosRequest> => - buildCodecForObject<GetExchangeTosRequest>() - .property("exchangeBaseUrl", codecForString()) - .build("GetExchangeTosRequest"); - -export interface AcceptManualWithdrawalRequest { - exchangeBaseUrl: string; - amount: string; -} - -export const codecForAcceptManualWithdrawalRequet = (): Codec<AcceptManualWithdrawalRequest> => - buildCodecForObject<AcceptManualWithdrawalRequest>() - .property("exchangeBaseUrl", codecForString()) - .property("amount", codecForString()) - .build("AcceptManualWithdrawalRequest"); - -export interface GetWithdrawalDetailsForAmountRequest { - exchangeBaseUrl: string; - amount: string; -} - -export interface AcceptBankIntegratedWithdrawalRequest { - talerWithdrawUri: string; - exchangeBaseUrl: string; -} - -export const codecForAcceptBankIntegratedWithdrawalRequest = (): Codec<AcceptBankIntegratedWithdrawalRequest> => - buildCodecForObject<AcceptBankIntegratedWithdrawalRequest>() - .property("exchangeBaseUrl", codecForString()) - .property("talerWithdrawUri", codecForString()) - .build("AcceptBankIntegratedWithdrawalRequest"); - -export const codecForGetWithdrawalDetailsForAmountRequest = (): Codec<GetWithdrawalDetailsForAmountRequest> => - buildCodecForObject<GetWithdrawalDetailsForAmountRequest>() - .property("exchangeBaseUrl", codecForString()) - .property("amount", codecForString()) - .build("GetWithdrawalDetailsForAmountRequest"); - -export interface AcceptExchangeTosRequest { - exchangeBaseUrl: string; - etag: string; -} - -export const codecForAcceptExchangeTosRequest = (): Codec<AcceptExchangeTosRequest> => - buildCodecForObject<AcceptExchangeTosRequest>() - .property("exchangeBaseUrl", codecForString()) - .property("etag", codecForString()) - .build("AcceptExchangeTosRequest"); - -export interface ApplyRefundRequest { - talerRefundUri: string; -} - -export const codecForApplyRefundRequest = (): Codec<ApplyRefundRequest> => - buildCodecForObject<ApplyRefundRequest>() - .property("talerRefundUri", codecForString()) - .build("ApplyRefundRequest"); - -export interface GetWithdrawalDetailsForUriRequest { - talerWithdrawUri: string; -} - -export const codecForGetWithdrawalDetailsForUri = (): Codec<GetWithdrawalDetailsForUriRequest> => - buildCodecForObject<GetWithdrawalDetailsForUriRequest>() - .property("talerWithdrawUri", codecForString()) - .build("GetWithdrawalDetailsForUriRequest"); - -export interface AbortProposalRequest { - proposalId: string; -} - -export const codecForAbortProposalRequest = (): Codec<AbortProposalRequest> => - buildCodecForObject<AbortProposalRequest>() - .property("proposalId", codecForString()) - .build("AbortProposalRequest"); - -export interface PreparePayRequest { - talerPayUri: string; -} - -export const codecForPreparePayRequest = (): Codec<PreparePayRequest> => - buildCodecForObject<PreparePayRequest>() - .property("talerPayUri", codecForString()) - .build("PreparePay"); - -export interface ConfirmPayRequest { - proposalId: string; - sessionId?: string; -} - -export const codecForConfirmPayRequest = (): Codec<ConfirmPayRequest> => - buildCodecForObject<ConfirmPayRequest>() - .property("proposalId", codecForString()) - .property("sessionId", codecOptional(codecForString())) - .build("ConfirmPay"); - -export type CoreApiResponse = CoreApiResponseSuccess | CoreApiResponseError; - -export type CoreApiEnvelope = CoreApiResponse | CoreApiNotification; - -export interface CoreApiNotification { - type: "notification"; - payload: unknown; -} - -export interface CoreApiResponseSuccess { - // To distinguish the message from notifications - type: "response"; - operation: string; - id: string; - result: unknown; -} - -export interface CoreApiResponseError { - // To distinguish the message from notifications - type: "error"; - operation: string; - id: string; - error: TalerErrorDetails; -} - -export interface WithdrawTestBalanceRequest { - amount: string; - bankBaseUrl: string; - exchangeBaseUrl: string; -} - -export const withdrawTestBalanceDefaults = { - amount: "TESTKUDOS:10", - bankBaseUrl: "https://bank.test.taler.net/", - exchangeBaseUrl: "https://exchange.test.taler.net/", -}; - -/** - * Request to the crypto worker to make a sync signature. - */ -export interface MakeSyncSignatureRequest { - accountPriv: string; - oldHash: string | undefined; - newHash: string; -} - -/** - * Strategy for loading recovery information. - */ -export enum RecoveryMergeStrategy { - /** - * Keep the local wallet root key, import and take over providers. - */ - Ours = "ours", - - /** - * Migrate to the wallet root key from the recovery information. - */ - Theirs = "theirs", -} - -/** - * Load recovery information into the wallet. - */ -export interface RecoveryLoadRequest { - recovery: BackupRecovery; - strategy?: RecoveryMergeStrategy; -} - -export const codecForWithdrawTestBalance = (): Codec<WithdrawTestBalanceRequest> => - buildCodecForObject<WithdrawTestBalanceRequest>() - .property("amount", codecForString()) - .property("bankBaseUrl", codecForString()) - .property("exchangeBaseUrl", codecForString()) - .build("WithdrawTestBalanceRequest"); - -export interface ApplyRefundResponse { - contractTermsHash: string; - - proposalId: string; - - amountEffectivePaid: AmountString; - - amountRefundGranted: AmountString; - - amountRefundGone: AmountString; - - pendingAtExchange: boolean; - - info: OrderShortInfo; -} - -export const codecForApplyRefundResponse = (): Codec<ApplyRefundResponse> => - buildCodecForObject<ApplyRefundResponse>() - .property("amountEffectivePaid", codecForAmountString()) - .property("amountRefundGone", codecForAmountString()) - .property("amountRefundGranted", codecForAmountString()) - .property("contractTermsHash", codecForString()) - .property("pendingAtExchange", codecForBoolean()) - .property("proposalId", codecForString()) - .property("info", codecForOrderShortInfo()) - .build("ApplyRefundResponse"); - -export interface SetCoinSuspendedRequest { - coinPub: string; - suspended: boolean; -} - -export const codecForSetCoinSuspendedRequest = (): Codec<SetCoinSuspendedRequest> => - buildCodecForObject<SetCoinSuspendedRequest>() - .property("coinPub", codecForString()) - .property("suspended", codecForBoolean()) - .build("SetCoinSuspendedRequest"); - -export interface ForceRefreshRequest { - coinPubList: string[]; -} - -export const codecForForceRefreshRequest = (): Codec<ForceRefreshRequest> => - buildCodecForObject<ForceRefreshRequest>() - .property("coinPubList", codecForList(codecForString())) - .build("ForceRefreshRequest"); - -export interface PrepareTipRequest { - talerTipUri: string; -} - -export const codecForPrepareTipRequest = (): Codec<PrepareTipRequest> => - buildCodecForObject<PrepareTipRequest>() - .property("talerTipUri", codecForString()) - .build("PrepareTipRequest"); - -export interface AcceptTipRequest { - walletTipId: string; -} - -export const codecForAcceptTipRequest = (): Codec<AcceptTipRequest> => - buildCodecForObject<AcceptTipRequest>() - .property("walletTipId", codecForString()) - .build("AcceptTipRequest"); - -export interface AbortPayWithRefundRequest { - proposalId: string; -} - -export const codecForAbortPayWithRefundRequest = (): Codec<AbortPayWithRefundRequest> => - buildCodecForObject<AbortPayWithRefundRequest>() - .property("proposalId", codecForString()) - .build("AbortPayWithRefundRequest"); - -export interface CreateDepositGroupRequest { - depositPaytoUri: string; - amount: string; -} - -export const codecForCreateDepositGroupRequest = (): Codec<CreateDepositGroupRequest> => - buildCodecForObject<CreateDepositGroupRequest>() - .property("amount", codecForAmountString()) - .property("depositPaytoUri", codecForString()) - .build("CreateDepositGroupRequest"); - -export interface CreateDepositGroupResponse { - depositGroupId: string; -} - -export interface TrackDepositGroupRequest { - depositGroupId: string; -} - -export interface TrackDepositGroupResponse { - responses: { - status: number; - body: any; - }[]; -} - -export const codecForTrackDepositGroupRequest = (): Codec<TrackDepositGroupRequest> => - buildCodecForObject<TrackDepositGroupRequest>() - .property("depositGroupId", codecForAmountString()) - .build("TrackDepositGroupRequest"); - -export interface WithdrawUriInfoResponse { - amount: AmountString; - defaultExchangeBaseUrl?: string; - possibleExchanges: ExchangeListItem[]; -} - -export const codecForWithdrawUriInfoResponse = (): Codec<WithdrawUriInfoResponse> => - buildCodecForObject<WithdrawUriInfoResponse>() - .property("amount", codecForAmountString()) - .property("defaultExchangeBaseUrl", codecOptional(codecForString())) - .property("possibleExchanges", codecForList(codecForExchangeListItem())) - .build("WithdrawUriInfoResponse"); |