Contents

1.5. Wallet-Core API Documentation

This file is auto-generated from wallet-core.

1.5.1. Overview

1.5.1.1. Unknown Group

1.5.1.2. Basic Wallet Information

1.5.1.3. Managing Transactions

1.5.1.4. Withdrawals

1.5.1.5. Merchant Payments

1.5.1.6. Rewards

1.5.1.7. Exchange Management

1.5.1.8. Deposits

1.5.1.9. Backups

1.5.1.10. Peer Payments

1.5.1.11. Data Validation

1.5.1.12. Database Management

1.5.1.13. Testing and Debugging

1.5.2. Operation Reference

1.5.2.1. InitWalletOp

/**
 * Initialize wallet-core.
 *
 * Must be the request before any other operations.
 */
export type InitWalletOp = {
  op: WalletApiOperation.InitWallet;
  request: InitRequest;
  response: InitResponse;
};
// InitWallet = "initWallet"

export interface InitRequest {
  skipDefaults?: boolean;
}

export interface InitResponse {
  versionInfo: WalletCoreVersion;
}

1.5.2.2. GetVersionOp

export type GetVersionOp = {
  op: WalletApiOperation.GetVersion;
  request: EmptyObject;
  response: WalletCoreVersion;
};
// GetVersion = "getVersion"

1.5.2.3. GetBalancesOp

/**
 * Get current wallet balance.
 */
export type GetBalancesOp = {
  op: WalletApiOperation.GetBalances;
  request: EmptyObject;
  response: BalancesResponse;
};
// GetBalances = "getBalances"

export interface BalancesResponse {
  balances: Balance[];
}

export interface Balance {
  scopeInfo: ScopeInfo;
  available: AmountString;
  pendingIncoming: AmountString;
  pendingOutgoing: AmountString;
  hasPendingTransactions: boolean;
  requiresUserInput: boolean;
}

1.5.2.4. GetBalancesDetailOp

export type GetBalancesDetailOp = {
  op: WalletApiOperation.GetBalanceDetail;
  request: GetBalanceDetailRequest;
  response: MerchantPaymentBalanceDetails;
};
// GetBalanceDetail = "getBalanceDetail"

export interface GetBalanceDetailRequest {
  currency: string;
}

export interface MerchantPaymentBalanceDetails {
  /**
   * Balance of type "available" (see balance.ts for definition).
   */
  balanceAvailable: AmountJson;
  /**
   * Balance of type "material" (see balance.ts for definition).
   */
  balanceMaterial: AmountJson;
  /**
   * Balance of type "age-acceptable" (see balance.ts for definition).
   */
  balanceAgeAcceptable: AmountJson;
  /**
   * Balance of type "merchant-acceptable" (see balance.ts for definition).
   */
  balanceMerchantAcceptable: AmountJson;
  /**
   * Balance of type "merchant-depositable" (see balance.ts for definition).
   */
  balanceMerchantDepositable: AmountJson;
}

/**
 * Non-negative financial amount.  Fractional values are expressed as multiples
 * of 1e-8.
 */
export interface AmountJson {
  /**
   * Value, must be an integer.
   */
  readonly value: number;
  /**
   * Fraction, must be an integer.  Represent 1/1e8 of a unit.
   */
  readonly fraction: number;
  /**
   * Currency of the amount.
   */
  readonly currency: string;
}

1.5.2.5. GetPlanForOperationOp

export type GetPlanForOperationOp = {
  op: WalletApiOperation.GetPlanForOperation;
  request: GetPlanForOperationRequest;
  response: GetPlanForOperationResponse;
};
// GetPlanForOperation = "getPlanForOperation"

export type GetPlanForOperationRequest =
  | GetPlanForWithdrawRequest
  | GetPlanForDepositRequest;

interface GetPlanForWithdrawRequest extends GetPlanForWalletInitiatedOperation {
  type: TransactionType.Withdrawal;
  exchangeUrl?: string;
}

interface GetPlanForWalletInitiatedOperation {
  instructedAmount: AmountString;
  mode: TransactionAmountMode;
}

interface GetPlanForDepositRequest extends GetPlanForWalletInitiatedOperation {
  type: TransactionType.Deposit;
  account: string;
}

export interface GetPlanForOperationResponse {
  effectiveAmount: AmountString;
  rawAmount: AmountString;
  counterPartyAmount?: AmountString;
  details: any;
}

1.5.2.6. ConvertDepositAmountOp

export type ConvertDepositAmountOp = {
  op: WalletApiOperation.ConvertDepositAmount;
  request: ConvertAmountRequest;
  response: AmountResponse;
};
// ConvertDepositAmount = "ConvertDepositAmount"

1.5.2.7. GetMaxDepositAmountOp

export type GetMaxDepositAmountOp = {
  op: WalletApiOperation.GetMaxDepositAmount;
  request: GetAmountRequest;
  response: AmountResponse;
};
// GetMaxDepositAmount = "GetMaxDepositAmount"

1.5.2.8. ConvertPeerPushAmountOp

export type ConvertPeerPushAmountOp = {
  op: WalletApiOperation.ConvertPeerPushAmount;
  request: ConvertAmountRequest;
  response: AmountResponse;
};
// ConvertPeerPushAmount = "ConvertPeerPushAmount"

1.5.2.9. GetMaxPeerPushAmountOp

export type GetMaxPeerPushAmountOp = {
  op: WalletApiOperation.GetMaxPeerPushAmount;
  request: GetAmountRequest;
  response: AmountResponse;
};
// GetMaxPeerPushAmount = "GetMaxPeerPushAmount"

1.5.2.10. ConvertWithdrawalAmountOp

export type ConvertWithdrawalAmountOp = {
  op: WalletApiOperation.ConvertWithdrawalAmount;
  request: ConvertAmountRequest;
  response: AmountResponse;
};
// ConvertWithdrawalAmount = "ConvertWithdrawalAmount"

1.5.2.11. GetTransactionsOp

/**
 * Get transactions.
 */
export type GetTransactionsOp = {
  op: WalletApiOperation.GetTransactions;
  request: TransactionsRequest;
  response: TransactionsResponse;
};
// GetTransactions = "getTransactions"

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;
  /**
   * If true, include all refreshes in the transactions list.
   */
  includeRefreshes?: boolean;
  filterByState?: TransactionStateFilter;
}

1.5.2.12. TestingGetSampleTransactionsOp

/**
 * Get sample transactions.
 */
export type TestingGetSampleTransactionsOp = {
  op: WalletApiOperation.TestingGetSampleTransactions;
  request: EmptyObject;
  response: TransactionsResponse;
};
// TestingGetSampleTransactions = "testingGetSampleTransactions"

1.5.2.13. GetTransactionByIdOp

export type GetTransactionByIdOp = {
  op: WalletApiOperation.GetTransactionById;
  request: TransactionByIdRequest;
  response: Transaction;
};
// GetTransactionById = "getTransactionById"

export interface TransactionByIdRequest {
  transactionId: string;
}

1.5.2.14. RetryPendingNowOp

export type RetryPendingNowOp = {
  op: WalletApiOperation.RetryPendingNow;
  request: EmptyObject;
  response: EmptyObject;
};
// RetryPendingNow = "retryPendingNow"

1.5.2.15. DeleteTransactionOp

/**
 * Delete a transaction locally in the wallet.
 */
export type DeleteTransactionOp = {
  op: WalletApiOperation.DeleteTransaction;
  request: DeleteTransactionRequest;
  response: EmptyObject;
};
// DeleteTransaction = "deleteTransaction"

export interface DeleteTransactionRequest {
  transactionId: TransactionIdStr;
}

1.5.2.16. RetryTransactionOp

/**
 * Immediately retry a transaction.
 */
export type RetryTransactionOp = {
  op: WalletApiOperation.RetryTransaction;
  request: RetryTransactionRequest;
  response: EmptyObject;
};
// RetryTransaction = "retryTransaction"

export interface RetryTransactionRequest {
  transactionId: TransactionIdStr;
}

1.5.2.17. AbortTransactionOp

/**
 * Abort a transaction
 *
 * For payment transactions, it puts the payment into an "aborting" state.
 */
export type AbortTransactionOp = {
  op: WalletApiOperation.AbortTransaction;
  request: AbortTransactionRequest;
  response: EmptyObject;
};
// AbortTransaction = "abortTransaction"

1.5.2.18. FailTransactionOp

/**
 * Cancel aborting a transaction
 *
 * For payment transactions, it puts the payment into an "aborting" state.
 */
export type FailTransactionOp = {
  op: WalletApiOperation.FailTransaction;
  request: FailTransactionRequest;
  response: EmptyObject;
};
// FailTransaction = "failTransaction"

export interface FailTransactionRequest {
  transactionId: TransactionIdStr;
}

1.5.2.19. SuspendTransactionOp

/**
 * Suspend a transaction
 */
export type SuspendTransactionOp = {
  op: WalletApiOperation.SuspendTransaction;
  request: AbortTransactionRequest;
  response: EmptyObject;
};
// SuspendTransaction = "suspendTransaction"

1.5.2.20. ResumeTransactionOp

/**
 * Resume a transaction
 */
export type ResumeTransactionOp = {
  op: WalletApiOperation.ResumeTransaction;
  request: AbortTransactionRequest;
  response: EmptyObject;
};
// ResumeTransaction = "resumeTransaction"

1.5.2.21. GetWithdrawalDetailsForAmountOp

/**
 * Get details for withdrawing a particular amount (manual withdrawal).
 */
export type GetWithdrawalDetailsForAmountOp = {
  op: WalletApiOperation.GetWithdrawalDetailsForAmount;
  request: GetWithdrawalDetailsForAmountRequest;
  response: ManualWithdrawalDetails;
};
// GetWithdrawalDetailsForAmount = "getWithdrawalDetailsForAmount"

export interface GetWithdrawalDetailsForAmountRequest {
  exchangeBaseUrl: string;
  amount: string;
  restrictAge?: number;
}

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;
  /**
   * Number of coins that would be used for withdrawal.
   *
   * The UIs should warn if this number is too high (roughly at >100).
   */
  numCoins: number;
  /**
   * Ways to pay the exchange.
   */
  paytoUris: string[];
  /**
   * If the exchange supports age-restricted coins it will return
   * the array of ages.
   */
  ageRestrictionOptions?: number[];
}

1.5.2.22. GetWithdrawalDetailsForUriOp

/**
 * Get details for withdrawing via a particular taler:// URI.
 */
export type GetWithdrawalDetailsForUriOp = {
  op: WalletApiOperation.GetWithdrawalDetailsForUri;
  request: GetWithdrawalDetailsForUriRequest;
  response: WithdrawUriInfoResponse;
};
// GetWithdrawalDetailsForUri = "getWithdrawalDetailsForUri"

export interface GetWithdrawalDetailsForUriRequest {
  talerWithdrawUri: string;
  restrictAge?: number;
}

export interface WithdrawUriInfoResponse {
  amount: AmountString;
  defaultExchangeBaseUrl?: string;
  possibleExchanges: ExchangeListItem[];
}

1.5.2.23. AcceptBankIntegratedWithdrawalOp

/**
 * Accept a bank-integrated withdrawal.
 */
export type AcceptBankIntegratedWithdrawalOp = {
  op: WalletApiOperation.AcceptBankIntegratedWithdrawal;
  request: AcceptBankIntegratedWithdrawalRequest;
  response: AcceptWithdrawalResponse;
};
// AcceptBankIntegratedWithdrawal = "acceptBankIntegratedWithdrawal"

export interface AcceptBankIntegratedWithdrawalRequest {
  talerWithdrawUri: string;
  exchangeBaseUrl: string;
  forcedDenomSel?: ForcedDenomSel;
  restrictAge?: number;
}

export interface AcceptWithdrawalResponse {
  reservePub: string;
  confirmTransferUrl?: string;
  transactionId: TransactionIdStr;
}

1.5.2.24. AcceptManualWithdrawalOp

/**
 * Create a manual withdrawal.
 */
export type AcceptManualWithdrawalOp = {
  op: WalletApiOperation.AcceptManualWithdrawal;
  request: AcceptManualWithdrawalRequest;
  response: AcceptManualWithdrawalResult;
};
// AcceptManualWithdrawal = "acceptManualWithdrawal"

export interface AcceptManualWithdrawalRequest {
  exchangeBaseUrl: string;
  amount: string;
  restrictAge?: number;
}

export interface AcceptManualWithdrawalResult {
  /**
   * Payto URIs that can be used to fund the withdrawal.
   */
  exchangePaytoUris: string[];
  /**
   * Public key of the newly created reserve.
   */
  reservePub: string;
  transactionId: TransactionIdStr;
}

1.5.2.25. PreparePayForUriOp

/**
 * Prepare to make a payment based on a taler://pay/ URI.
 */
export type PreparePayForUriOp = {
  op: WalletApiOperation.PreparePayForUri;
  request: PreparePayRequest;
  response: PreparePayResult;
};
// PreparePayForUri = "preparePayForUri"

export interface PreparePayRequest {
  talerPayUri: string;
}

1.5.2.26. SharePaymentOp

export type SharePaymentOp = {
  op: WalletApiOperation.SharePayment;
  request: SharePaymentRequest;
  response: SharePaymentResult;
};
// SharePayment = "sharePayment"

export interface SharePaymentRequest {
  merchantBaseUrl: string;
  orderId: string;
}

export interface SharePaymentResult {
  privatePayUri: string;
}

1.5.2.27. PreparePayForTemplateOp

/**
 * Prepare to make a payment based on a taler://pay-template/ URI.
 */
export type PreparePayForTemplateOp = {
  op: WalletApiOperation.PreparePayForTemplate;
  request: PreparePayTemplateRequest;
  response: PreparePayResult;
};
// PreparePayForTemplate = "preparePayForTemplate"

export interface PreparePayTemplateRequest {
  talerPayTemplateUri: string;
  templateParams: Record<string, string>;
}

1.5.2.28. GetContractTermsDetailsOp

export type GetContractTermsDetailsOp = {
  op: WalletApiOperation.GetContractTermsDetails;
  request: GetContractTermsDetailsRequest;
  response: WalletContractData;
};
// GetContractTermsDetails = "getContractTermsDetails"

export interface GetContractTermsDetailsRequest {
  proposalId: 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: AmountString;
  orderId: string;
  merchantBaseUrl: string;
  summary: string;
  autoRefund: TalerProtocolDuration | undefined;
  maxWireFee: AmountString;
  wireFeeAmortization: number;
  payDeadline: TalerProtocolTimestamp;
  refundDeadline: TalerProtocolTimestamp;
  allowedExchanges: AllowedExchangeInfo[];
  timestamp: TalerProtocolTimestamp;
  wireMethod: string;
  wireInfoHash: string;
  maxDepositFee: AmountString;
  minimumAge?: number;
  deliveryDate: TalerProtocolTimestamp | undefined;
  deliveryLocation: Location | undefined;
}

export interface AllowedExchangeInfo {
  exchangeBaseUrl: string;
  exchangePub: string;
}

1.5.2.29. ConfirmPayOp

/**
 * Confirm a payment that was previously prepared with
 * {@link PreparePayForUriOp}
 */
export type ConfirmPayOp = {
  op: WalletApiOperation.ConfirmPay;
  request: ConfirmPayRequest;
  response: ConfirmPayResult;
};
// ConfirmPay = "confirmPay"

export interface ConfirmPayRequest {
  /**
   * @deprecated use transactionId instead
   */
  proposalId?: string;
  transactionId?: string;
  sessionId?: string;
  forcedCoinSel?: ForcedCoinSel;
}

export type ConfirmPayResult = ConfirmPayResultDone | ConfirmPayResultPending;

/**
 * Result for confirmPay
 */
export interface ConfirmPayResultDone {
  type: ConfirmPayResultType.Done;
  contractTerms: MerchantContractTerms;
  transactionId: TransactionIdStr;
}

export interface ConfirmPayResultPending {
  type: ConfirmPayResultType.Pending;
  transactionId: TransactionIdStr;
  lastError: TalerErrorDetail | undefined;
}

1.5.2.30. StartRefundQueryForUriOp

/**
 * Check for a refund based on a taler://refund URI.
 */
export type StartRefundQueryForUriOp = {
  op: WalletApiOperation.StartRefundQueryForUri;
  request: PrepareRefundRequest;
  response: StartRefundQueryForUriResponse;
};
// StartRefundQueryForUri = "startRefundQueryForUri"

export interface PrepareRefundRequest {
  talerRefundUri: string;
}

export interface StartRefundQueryForUriResponse {
  transactionId: TransactionIdStr;
}

1.5.2.31. StartRefundQueryOp

export type StartRefundQueryOp = {
  op: WalletApiOperation.StartRefundQuery;
  request: StartRefundQueryRequest;
  response: EmptyObject;
};
// StartRefundQuery = "startRefundQuery"

export interface StartRefundQueryRequest {
  transactionId: TransactionIdStr;
}

1.5.2.32. PrepareTipOp

/**
 * Query and store information about a reward.
 */
export type PrepareTipOp = {
  op: WalletApiOperation.PrepareReward;
  request: PrepareRewardRequest;
  response: PrepareRewardResult;
};
// PrepareReward = "prepareReward"

export interface PrepareRewardRequest {
  talerRewardUri: string;
}

export interface PrepareTipResult {
  /**
   * Unique ID for the tip assigned by the wallet.
   * Typically different from the merchant-generated tip ID.
   *
   * @deprecated use transactionId instead
   */
  walletRewardId: string;
  /**
   * Tip transaction ID.
   */
  transactionId: string;
  /**
   * Has the tip already been accepted?
   */
  accepted: boolean;
  /**
   * Amount that the merchant gave.
   */
  rewardAmountRaw: AmountString;
  /**
   * Amount that arrived at the wallet.
   * Might be lower than the raw amount due to fees.
   */
  rewardAmountEffective: 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: TalerProtocolTimestamp;
}

1.5.2.33. AcceptTipOp

/**
 * Accept a reward.
 */
export type AcceptTipOp = {
  op: WalletApiOperation.AcceptReward;
  request: AcceptRewardRequest;
  response: AcceptTipResponse;
};
// AcceptReward = "acceptReward"

export interface AcceptRewardRequest {
  walletRewardId: string;
}

export interface AcceptTipResponse {
  transactionId: TransactionIdStr;
  next_url?: string;
}

1.5.2.34. ListExchangesOp

/**
 * List exchanges known to the wallet.
 */
export type ListExchangesOp = {
  op: WalletApiOperation.ListExchanges;
  request: EmptyObject;
  response: ExchangesListResponse;
};
// ListExchanges = "listExchanges"

export interface ExchangesListResponse {
  exchanges: ExchangeListItem[];
}

1.5.2.35. AddExchangeOp

/**
 * Add / force-update an exchange.
 */
export type AddExchangeOp = {
  op: WalletApiOperation.AddExchange;
  request: AddExchangeRequest;
  response: EmptyObject;
};
// AddExchange = "addExchange"

1.5.2.36. ListKnownBankAccountsOp

export type ListKnownBankAccountsOp = {
  op: WalletApiOperation.ListKnownBankAccounts;
  request: ListKnownBankAccountsRequest;
  response: KnownBankAccounts;
};
// ListKnownBankAccounts = "listKnownBankAccounts"

export interface ListKnownBankAccountsRequest {
  currency?: string;
}

export interface KnownBankAccounts {
  accounts: KnownBankAccountsInfo[];
}

export interface KnownBankAccountsInfo {
  uri: PaytoUri;
  kyc_completed: boolean;
  currency: string;
  alias: string;
}

export type PaytoUri =
  | PaytoUriUnknown
  | PaytoUriIBAN
  | PaytoUriTalerBank
  | PaytoUriBitcoin;

export interface PaytoUriUnknown extends PaytoUriGeneric {
  isKnown: false;
}

export interface PaytoUriGeneric {
  targetType: PaytoType | string;
  targetPath: string;
  params: {
    [name: string]: string;
  };
}

export type PaytoType = "iban" | "bitcoin" | "x-taler-bank";

export interface PaytoUriIBAN extends PaytoUriGeneric {
  isKnown: true;
  targetType: "iban";
  iban: string;
  bic?: string;
}

export interface PaytoUriTalerBank extends PaytoUriGeneric {
  isKnown: true;
  targetType: "x-taler-bank";
  host: string;
  account: string;
}

export interface PaytoUriBitcoin extends PaytoUriGeneric {
  isKnown: true;
  targetType: "bitcoin";
  segwitAddrs: Array<string>;
}

1.5.2.37. AddKnownBankAccountsOp

export type AddKnownBankAccountsOp = {
  op: WalletApiOperation.AddKnownBankAccounts;
  request: AddKnownBankAccountsRequest;
  response: EmptyObject;
};
// AddKnownBankAccounts = "addKnownBankAccounts"

export interface AddKnownBankAccountsRequest {
  payto: string;
  alias: string;
  currency: string;
}

1.5.2.38. ForgetKnownBankAccountsOp

export type ForgetKnownBankAccountsOp = {
  op: WalletApiOperation.ForgetKnownBankAccounts;
  request: ForgetKnownBankAccountsRequest;
  response: EmptyObject;
};
// ForgetKnownBankAccounts = "forgetKnownBankAccounts"

export interface ForgetKnownBankAccountsRequest {
  payto: string;
}

1.5.2.39. SetExchangeTosAcceptedOp

/**
 * Accept a particular version of the exchange terms of service.
 */
export type SetExchangeTosAcceptedOp = {
  op: WalletApiOperation.SetExchangeTosAccepted;
  request: AcceptExchangeTosRequest;
  response: EmptyObject;
};
// SetExchangeTosAccepted = "setExchangeTosAccepted"

export interface AcceptExchangeTosRequest {
  exchangeBaseUrl: string;
  etag: string | undefined;
}

1.5.2.40. GetExchangeTosOp

/**
 * Get the current terms of a service of an exchange.
 */
export type GetExchangeTosOp = {
  op: WalletApiOperation.GetExchangeTos;
  request: GetExchangeTosRequest;
  response: GetExchangeTosResult;
};
// GetExchangeTos = "getExchangeTos"

export interface GetExchangeTosRequest {
  exchangeBaseUrl: string;
  acceptedFormat?: string[];
}

export interface GetExchangeTosResult {
  /**
   * Markdown version of the current ToS.
   */
  content: 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;
  /**
   * Accepted content type
   */
  contentType: string;
  tosStatus: ExchangeTosStatus;
}

1.5.2.41. GetExchangeDetailedInfoOp

/**
 * Get the current terms of a service of an exchange.
 */
export type GetExchangeDetailedInfoOp = {
  op: WalletApiOperation.GetExchangeDetailedInfo;
  request: AddExchangeRequest;
  response: ExchangeDetailedResponse;
};
// GetExchangeDetailedInfo = "getExchangeDetailedInfo"

export interface ExchangeDetailedResponse {
  exchange: ExchangeFullDetails;
}

export interface ExchangeFullDetails {
  exchangeBaseUrl: string;
  currency: string;
  paytoUris: string[];
  tos: ExchangeTosStatusDetails;
  auditors: ExchangeAuditor[];
  wireInfo: WireInfo;
  denomFees: DenomOperationMap<FeeDescription[]>;
  transferFees: Record<string, FeeDescription[]>;
  globalFees: FeeDescription[];
}

export interface ExchangeTosStatusDetails {
  acceptedVersion?: string;
  currentVersion?: string;
  contentType?: string;
  content?: string;
}

export interface WireInfo {
  feesForType: WireFeeMap;
  accounts: ExchangeAccount[];
}

/**
 * Information about one of the exchange's bank accounts.
 */
export interface ExchangeAccount {
  payto_uri: string;
  master_sig: string;
}

export interface FeeDescription {
  group: string;
  from: AbsoluteTime;
  until: AbsoluteTime;
  fee?: AmountString;
}

1.5.2.42. ListCurrenciesOp

/**
 * List currencies known to the wallet.
 */
export type ListCurrenciesOp = {
  op: WalletApiOperation.ListCurrencies;
  request: EmptyObject;
  response: WalletCurrencyInfo;
};
// ListCurrencies = "listCurrencies"

export interface WalletCurrencyInfo {
  trustedAuditors: {
    currency: string;
    auditorPub: string;
    auditorBaseUrl: string;
  }[];
  trustedExchanges: {
    currency: string;
    exchangeMasterPub: string;
    exchangeBaseUrl: string;
  }[];
}

1.5.2.43. GetScopedCurrencyInfoOp

export type GetScopedCurrencyInfoOp = {
  op: WalletApiOperation.GetScopedCurrencyInfo;
  request: GetCurrencyInfoRequest;
  response: GetCurrencyInfoResponse;
};
// GetScopedCurrencyInfo = "getScopedCurrencyInfo"

export interface GetCurrencyInfoRequest {
  scope: ScopeInfo;
}

export interface GetCurrencyInfoResponse {
  decimalSeparator: string;
  numFractionalDigits: number;
  numTinyDigits: number;
  /**
   * Is the currency name leading or trailing?
   */
  isCurrencyNameLeading: boolean;
}

1.5.2.44. GenerateDepositGroupTxIdOp

/**
 * Generate a fresh transaction ID for a deposit group.
 *
 * The resulting transaction ID can be specified when creating
 * a deposit group, so that the client can already start waiting for notifications
 * on that specific deposit group before the GreateDepositGroup request returns.
 */
export type GenerateDepositGroupTxIdOp = {
  op: WalletApiOperation.GenerateDepositGroupTxId;
  request: EmptyObject;
  response: TxIdResponse;
};
// GenerateDepositGroupTxId = "generateDepositGroupTxId"

export interface TxIdResponse {
  transactionId: TransactionIdStr;
}

1.5.2.45. CreateDepositGroupOp

/**
 * Create a new deposit group.
 *
 * Deposit groups are used to deposit multiple coins to a bank
 * account, usually the wallet user's own bank account.
 */
export type CreateDepositGroupOp = {
  op: WalletApiOperation.CreateDepositGroup;
  request: CreateDepositGroupRequest;
  response: CreateDepositGroupResponse;
};
// CreateDepositGroup = "createDepositGroup"

export interface CreateDepositGroupRequest {
  /**
   * Pre-allocated transaction ID.
   * Allows clients to easily handle notifications
   * that occur while the operation has been created but
   * before the creation request has returned.
   */
  transactionId?: string;
  depositPaytoUri: string;
  amount: AmountString;
}

export interface CreateDepositGroupResponse {
  depositGroupId: string;
  transactionId: TransactionIdStr;
}

1.5.2.46. PrepareDepositOp

export type PrepareDepositOp = {
  op: WalletApiOperation.PrepareDeposit;
  request: PrepareDepositRequest;
  response: PrepareDepositResponse;
};
// PrepareDeposit = "prepareDeposit"

export interface PrepareDepositRequest {
  depositPaytoUri: string;
  amount: AmountString;
}

export interface PrepareDepositResponse {
  totalDepositCost: AmountString;
  effectiveDepositAmount: AmountString;
  fees: DepositGroupFees;
}

export interface DepositGroupFees {
  coin: AmountString;
  wire: AmountString;
  refresh: AmountString;
}

1.5.2.47. ExportBackupRecoveryOp

/**
 * Export the recovery information for the wallet.
 */
export type ExportBackupRecoveryOp = {
  op: WalletApiOperation.ExportBackupRecovery;
  request: EmptyObject;
  response: BackupRecovery;
};
// ExportBackupRecovery = "exportBackupRecovery"

1.5.2.48. ImportBackupRecoveryOp

/**
 * Import recovery information into the wallet.
 */
export type ImportBackupRecoveryOp = {
  op: WalletApiOperation.ImportBackupRecovery;
  request: RecoveryLoadRequest;
  response: EmptyObject;
};
// ImportBackupRecovery = "importBackupRecovery"

/**
 * Load recovery information into the wallet.
 */
export interface RecoveryLoadRequest {
  recovery: BackupRecovery;
  strategy?: RecoveryMergeStrategy;
}

/**
 * Strategy for loading recovery information.
 */
export declare 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",
}

1.5.2.49. RunBackupCycleOp

/**
 * Manually make and upload a backup.
 */
export type RunBackupCycleOp = {
  op: WalletApiOperation.RunBackupCycle;
  request: RunBackupCycleRequest;
  response: EmptyObject;
};
// RunBackupCycle = "runBackupCycle"

export interface RunBackupCycleRequest {
  /**
   * List of providers to backup or empty for all known providers.
   */
  providers?: Array<string>;
}

1.5.2.50. ExportBackupOp

export type ExportBackupOp = {
  op: WalletApiOperation.ExportBackup;
  request: EmptyObject;
  response: EmptyObject;
};
// ExportBackup = "exportBackup"

1.5.2.51. AddBackupProviderOp

/**
 * Add a new backup provider.
 */
export type AddBackupProviderOp = {
  op: WalletApiOperation.AddBackupProvider;
  request: AddBackupProviderRequest;
  response: AddBackupProviderResponse;
};
// AddBackupProvider = "addBackupProvider"

export interface AddBackupProviderRequest {
  backupProviderBaseUrl: string;
  name: string;
  /**
   * Activate the provider.  Should only be done after
   * the user has reviewed the provider.
   */
  activate?: boolean;
}

export type AddBackupProviderResponse =
  | AddBackupProviderOk
  | AddBackupProviderPaymentRequired;

interface AddBackupProviderOk {
  status: "ok";
}

interface AddBackupProviderPaymentRequired {
  status: "payment-required";
  talerUri?: string;
}

1.5.2.52. RemoveBackupProviderOp

export type RemoveBackupProviderOp = {
  op: WalletApiOperation.RemoveBackupProvider;
  request: RemoveBackupProviderRequest;
  response: EmptyObject;
};
// RemoveBackupProvider = "removeBackupProvider"

export interface RemoveBackupProviderRequest {
  provider: string;
}

1.5.2.53. GetBackupInfoOp

/**
 * Get some useful stats about the backup state.
 */
export type GetBackupInfoOp = {
  op: WalletApiOperation.GetBackupInfo;
  request: EmptyObject;
  response: BackupInfo;
};
// GetBackupInfo = "getBackupInfo"

export interface BackupInfo {
  walletRootPub: string;
  deviceId: string;
  providers: ProviderInfo[];
}

/**
 * Information about one provider.
 *
 * We don't store the account key here,
 * as that's derived from the wallet root key.
 */
export interface ProviderInfo {
  active: boolean;
  syncProviderBaseUrl: string;
  name: string;
  terms?: BackupProviderTerms;
  /**
   * Last communication issue with the provider.
   */
  lastError?: TalerErrorDetail;
  lastSuccessfulBackupTimestamp?: TalerPreciseTimestamp;
  lastAttemptedBackupTimestamp?: TalerPreciseTimestamp;
  paymentProposalIds: string[];
  backupProblem?: BackupProblem;
  paymentStatus: ProviderPaymentStatus;
}

export interface BackupProviderTerms {
  supportedProtocolVersion: string;
  annualFee: AmountString;
  storageLimitInMegabytes: number;
}

export type BackupProblem =
  | BackupUnreadableProblem
  | BackupConflictingDeviceProblem;

export interface BackupUnreadableProblem {
  type: "backup-unreadable";
}

export interface BackupConflictingDeviceProblem {
  type: "backup-conflicting-device";
  otherDeviceId: string;
  myDeviceId: string;
  backupTimestamp: AbsoluteTime;
}

export type ProviderPaymentStatus =
  | ProviderPaymentTermsChanged
  | ProviderPaymentPaid
  | ProviderPaymentInsufficientBalance
  | ProviderPaymentUnpaid
  | ProviderPaymentPending;

export interface ProviderPaymentTermsChanged {
  type: ProviderPaymentType.TermsChanged;
  paidUntil: AbsoluteTime;
  oldTerms: BackupProviderTerms;
  newTerms: BackupProviderTerms;
}

export interface ProviderPaymentPaid {
  type: ProviderPaymentType.Paid;
  paidUntil: AbsoluteTime;
}

export interface ProviderPaymentInsufficientBalance {
  type: ProviderPaymentType.InsufficientBalance;
  amount: AmountString;
}

export interface ProviderPaymentUnpaid {
  type: ProviderPaymentType.Unpaid;
}

export interface ProviderPaymentPending {
  type: ProviderPaymentType.Pending;
  talerUri?: string;
}

1.5.2.54. SetWalletDeviceIdOp

/**
 * Set the internal device ID of the wallet, used to
 * identify whether a different/new wallet is accessing
 * the backup of another wallet.
 */
export type SetWalletDeviceIdOp = {
  op: WalletApiOperation.SetWalletDeviceId;
  request: SetWalletDeviceIdRequest;
  response: EmptyObject;
};
// SetWalletDeviceId = "setWalletDeviceId"

export interface SetWalletDeviceIdRequest {
  /**
   * New wallet device ID to set.
   */
  walletDeviceId: string;
}

1.5.2.55. ListStoredBackupsOp

export type ListStoredBackupsOp = {
  op: WalletApiOperation.ListStoredBackups;
  request: EmptyObject;
  response: StoredBackupList;
};
// ListStoredBackups = "listStoredBackups"

export interface StoredBackupList {
  storedBackups: {
    name: string;
  }[];
}

1.5.2.56. CreateStoredBackupsOp

export type CreateStoredBackupsOp = {
  op: WalletApiOperation.CreateStoredBackup;
  request: EmptyObject;
  response: CreateStoredBackupResponse;
};
// CreateStoredBackup = "createStoredBackup"

export interface CreateStoredBackupResponse {
  name: string;
}

1.5.2.57. RecoverStoredBackupsOp

export type RecoverStoredBackupsOp = {
  op: WalletApiOperation.RecoverStoredBackup;
  request: RecoverStoredBackupRequest;
  response: EmptyObject;
};
// RecoverStoredBackup = "recoverStoredBackup"

export interface RecoverStoredBackupRequest {
  name: string;
}

1.5.2.58. DeleteStoredBackupOp

export type DeleteStoredBackupOp = {
  op: WalletApiOperation.DeleteStoredBackup;
  request: DeleteStoredBackupRequest;
  response: EmptyObject;
};
// DeleteStoredBackup = "deleteStoredBackup"

export interface DeleteStoredBackupRequest {
  name: string;
}

1.5.2.59. CheckPeerPushDebitOp

/**
 * Check if initiating a peer push payment is possible
 * based on the funds in the wallet.
 */
export type CheckPeerPushDebitOp = {
  op: WalletApiOperation.CheckPeerPushDebit;
  request: CheckPeerPushDebitRequest;
  response: CheckPeerPushDebitResponse;
};
// CheckPeerPushDebit = "checkPeerPushDebit"

export interface CheckPeerPushDebitRequest {
  /**
   * Preferred exchange to use for the p2p payment.
   */
  exchangeBaseUrl?: string;
  /**
   * Instructed amount.
   *
   * FIXME: Allow specifying the instructed amount type.
   */
  amount: AmountString;
}

export interface CheckPeerPushDebitResponse {
  amountRaw: AmountString;
  amountEffective: AmountString;
}

1.5.2.60. InitiatePeerPushDebitOp

/**
 * Initiate an outgoing peer push payment.
 */
export type InitiatePeerPushDebitOp = {
  op: WalletApiOperation.InitiatePeerPushDebit;
  request: InitiatePeerPushDebitRequest;
  response: InitiatePeerPushDebitResponse;
};
// InitiatePeerPushDebit = "initiatePeerPushDebit"

export interface InitiatePeerPushDebitRequest {
  exchangeBaseUrl?: string;
  partialContractTerms: PeerContractTerms;
}

export interface InitiatePeerPushDebitResponse {
  exchangeBaseUrl: string;
  pursePub: string;
  mergePriv: string;
  contractPriv: string;
  talerUri: string;
  transactionId: TransactionIdStr;
}

1.5.2.61. PreparePeerPushCreditOp

/**
 * Check an incoming peer push payment.
 */
export type PreparePeerPushCreditOp = {
  op: WalletApiOperation.PreparePeerPushCredit;
  request: PreparePeerPushCreditRequest;
  response: PreparePeerPushCreditResponse;
};
// PreparePeerPushCredit = "preparePeerPushCredit"

export interface PreparePeerPushCreditRequest {
  talerUri: string;
}

export interface PreparePeerPushCreditResponse {
  contractTerms: PeerContractTerms;
  /**
   * @deprecated
   */
  amount: AmountString;
  amountRaw: AmountString;
  amountEffective: AmountString;
  peerPushPaymentIncomingId: string;
  transactionId: string;
}

1.5.2.62. ConfirmPeerPushCreditOp

/**
 * Accept an incoming peer push payment.
 */
export type ConfirmPeerPushCreditOp = {
  op: WalletApiOperation.ConfirmPeerPushCredit;
  request: ConfirmPeerPushCreditRequest;
  response: EmptyObject;
};
// ConfirmPeerPushCredit = "confirmPeerPushCredit"

export interface ConfirmPeerPushCreditRequest {
  /**
   * Transparent identifier of the incoming peer push payment.
   *
   * @deprecated specify transactionId instead!
   */
  peerPushPaymentIncomingId?: string;
  transactionId?: string;
}

1.5.2.63. CheckPeerPullCreditOp

/**
 * Check fees for an outgoing peer pull payment.
 */
export type CheckPeerPullCreditOp = {
  op: WalletApiOperation.CheckPeerPullCredit;
  request: CheckPeerPullCreditRequest;
  response: CheckPeerPullCreditResponse;
};
// CheckPeerPullCredit = "checkPeerPullCredit"

export interface CheckPeerPullCreditRequest {
  exchangeBaseUrl?: string;
  amount: AmountString;
}

export interface CheckPeerPullCreditResponse {
  exchangeBaseUrl: string;
  amountRaw: AmountString;
  amountEffective: AmountString;
  /**
   * Number of coins that will be used,
   * can be used by the UI to warn if excessively large.
   */
  numCoins: number;
}

1.5.2.64. InitiatePeerPullCreditOp

/**
 * Initiate an outgoing peer pull payment.
 */
export type InitiatePeerPullCreditOp = {
  op: WalletApiOperation.InitiatePeerPullCredit;
  request: InitiatePeerPullCreditRequest;
  response: InitiatePeerPullCreditResponse;
};
// InitiatePeerPullCredit = "initiatePeerPullCredit"

export interface InitiatePeerPullCreditRequest {
  exchangeBaseUrl?: string;
  partialContractTerms: PeerContractTerms;
}

export interface InitiatePeerPullCreditResponse {
  /**
   * Taler URI for the other party to make the payment
   * that was requested.
   *
   * @deprecated since it's not necessarily valid yet until the tx is in the right state
   */
  talerUri: string;
  transactionId: TransactionIdStr;
}

1.5.2.65. PreparePeerPullDebitOp

/**
 * Prepare for an incoming peer pull payment.
 */
export type PreparePeerPullDebitOp = {
  op: WalletApiOperation.PreparePeerPullDebit;
  request: PreparePeerPullDebitRequest;
  response: PreparePeerPullDebitResponse;
};
// PreparePeerPullDebit = "preparePeerPullDebit"

export interface PreparePeerPullDebitRequest {
  talerUri: string;
}

export interface PreparePeerPullDebitResponse {
  contractTerms: PeerContractTerms;
  /**
   * @deprecated Redundant field with bad name, will be removed soon.
   */
  amount: AmountString;
  amountRaw: AmountString;
  amountEffective: AmountString;
  peerPullPaymentIncomingId: string;
  transactionId: string;
}

1.5.2.66. ConfirmPeerPullDebitOp

/**
 * Accept an incoming peer pull payment (i.e. pay the other party).
 */
export type ConfirmPeerPullDebitOp = {
  op: WalletApiOperation.ConfirmPeerPullDebit;
  request: ConfirmPeerPullDebitRequest;
  response: EmptyObject;
};
// ConfirmPeerPullDebit = "confirmPeerPullDebit"

export interface ConfirmPeerPullDebitRequest {
  /**
   * Transparent identifier of the incoming peer pull payment.
   *
   * @deprecated use transactionId instead
   */
  peerPullPaymentIncomingId?: string;
  transactionId?: string;
}

1.5.2.67. ValidateIbanOp

export type ValidateIbanOp = {
  op: WalletApiOperation.ValidateIban;
  request: ValidateIbanRequest;
  response: ValidateIbanResponse;
};
// ValidateIban = "validateIban"

export interface ValidateIbanRequest {
  iban: string;
}

export interface ValidateIbanResponse {
  valid: boolean;
}

1.5.2.68. ExportDbOp

/**
 * Export the wallet database's contents to JSON.
 */
export type ExportDbOp = {
  op: WalletApiOperation.ExportDb;
  request: EmptyObject;
  response: any;
};
// ExportDb = "exportDb"

1.5.2.69. ImportDbOp

export type ImportDbOp = {
  op: WalletApiOperation.ImportDb;
  request: any;
  response: any;
};
// ImportDb = "importDb"

1.5.2.70. ClearDbOp

/**
 * Dangerously clear the whole wallet database.
 */
export type ClearDbOp = {
  op: WalletApiOperation.ClearDb;
  request: EmptyObject;
  response: EmptyObject;
};
// ClearDb = "clearDb"

1.5.2.71. RecycleOp

/**
 * Export a backup, clear the database and re-import it.
 */
export type RecycleOp = {
  op: WalletApiOperation.Recycle;
  request: EmptyObject;
  response: EmptyObject;
};
// Recycle = "recycle"

1.5.2.72. ApplyDevExperimentOp

/**
 * Apply a developer experiment to the current wallet state.
 *
 * This allows UI developers / testers to play around without
 * an elaborate test environment.
 */
export type ApplyDevExperimentOp = {
  op: WalletApiOperation.ApplyDevExperiment;
  request: ApplyDevExperimentRequest;
  response: EmptyObject;
};
// ApplyDevExperiment = "applyDevExperiment"

export interface ApplyDevExperimentRequest {
  devExperimentUri: string;
}

1.5.2.73. RunIntegrationTestOp

/**
 * Run a simple integration test on a test deployment
 * of the exchange and merchant.
 */
export type RunIntegrationTestOp = {
  op: WalletApiOperation.RunIntegrationTest;
  request: IntegrationTestArgs;
  response: EmptyObject;
};
// RunIntegrationTest = "runIntegrationTest"

1.5.2.74. RunIntegrationTestV2Op

/**
 * Run a simple integration test on a test deployment
 * of the exchange and merchant.
 */
export type RunIntegrationTestV2Op = {
  op: WalletApiOperation.RunIntegrationTestV2;
  request: IntegrationTestArgs;
  response: EmptyObject;
};
// RunIntegrationTestV2 = "runIntegrationTestV2"

1.5.2.75. TestCryptoOp

/**
 * Test crypto worker.
 */
export type TestCryptoOp = {
  op: WalletApiOperation.TestCrypto;
  request: EmptyObject;
  response: any;
};
// TestCrypto = "testCrypto"

1.5.2.76. WithdrawTestBalanceOp

/**
 * Make withdrawal on a test deployment of the exchange
 * and merchant.
 */
export type WithdrawTestBalanceOp = {
  op: WalletApiOperation.WithdrawTestBalance;
  request: WithdrawTestBalanceRequest;
  response: EmptyObject;
};
// WithdrawTestBalance = "withdrawTestBalance"

export interface WithdrawTestBalanceRequest {
  amount: string;
  /**
   * Bank access API base URL.
   */
  bankAccessApiBaseUrl: string;
  exchangeBaseUrl: string;
  forcedDenomSel?: ForcedDenomSel;
}

1.5.2.77. WithdrawTestkudosOp

/**
 * Make a withdrawal of testkudos on test.taler.net.
 */
export type WithdrawTestkudosOp = {
  op: WalletApiOperation.WithdrawTestkudos;
  request: EmptyObject;
  response: EmptyObject;
};
// WithdrawTestkudos = "withdrawTestkudos"

1.5.2.78. TestPayOp

/**
 * Make a test payment using a test deployment of
 * the exchange and merchant.
 */
export type TestPayOp = {
  op: WalletApiOperation.TestPay;
  request: TestPayArgs;
  response: TestPayResult;
};
// TestPay = "testPay"

export interface TestPayArgs {
  merchantBaseUrl: string;
  merchantAuthToken?: string;
  amount: string;
  summary: string;
  forcedCoinSel?: ForcedCoinSel;
}

export interface TestPayResult {
  payCoinSelection: PayCoinSelection;
}

/**
 * Result of selecting coins, contains the exchange, and selected
 * coins with their denomination.
 */
export interface PayCoinSelection {
  /**
   * Amount requested by the merchant.
   */
  paymentAmount: AmountString;
  /**
   * Public keys of the coins that were selected.
   */
  coinPubs: string[];
  /**
   * Amount that each coin contributes.
   */
  coinContributions: AmountString[];
  /**
   * How much of the wire fees is the customer paying?
   */
  customerWireFees: AmountString;
  /**
   * How much of the deposit fees is the customer paying?
   */
  customerDepositFees: AmountString;
}

1.5.2.79. WithdrawFakebankOp

/**
 * Make a withdrawal from a fakebank, i.e.
 * a bank where test users can be registered freely
 * and testing APIs are available.
 */
export type WithdrawFakebankOp = {
  op: WalletApiOperation.WithdrawFakebank;
  request: WithdrawFakebankRequest;
  response: EmptyObject;
};
// WithdrawFakebank = "withdrawFakebank"

export interface WithdrawFakebankRequest {
  amount: AmountString;
  exchange: string;
  bank: string;
}

1.5.2.80. GetPendingTasksOp

/**
 * Get wallet-internal pending tasks.
 */
export type GetPendingTasksOp = {
  op: WalletApiOperation.GetPendingOperations;
  request: EmptyObject;
  response: PendingTasksResponse;
};
// GetPendingOperations = "getPendingOperations"

/**
 * Response returned from the pending operations API.
 */
export interface PendingOperationsResponse {
  /**
   * List of pending operations.
   */
  pendingOperations: PendingTaskInfo[];
}

/**
 * Information about a pending operation.
 */
export type PendingTaskInfo = PendingTaskInfoCommon &
  (
    | PendingExchangeUpdateTask
    | PendingExchangeCheckRefreshTask
    | PendingPurchaseTask
    | PendingRefreshTask
    | PendingTipPickupTask
    | PendingWithdrawTask
    | PendingRecoupTask
    | PendingDepositTask
    | PendingBackupTask
    | PendingPeerPushInitiationTask
    | PendingPeerPullInitiationTask
    | PendingPeerPullDebitTask
    | PendingPeerPushCreditTask
  );

/**
 * Fields that are present in every pending operation.
 */
export interface PendingTaskInfoCommon {
  /**
   * Type of the pending operation.
   */
  type: PendingTaskType;
  /**
   * Unique identifier for the pending task.
   */
  id: TaskId;
  /**
   * Set to true if the operation indicates that something is really in progress,
   * as opposed to some regular scheduled operation that can be tried later.
   */
  givesLifeness: boolean;
  /**
   * Operation is active and waiting for a longpoll result.
   */
  isLongpolling: boolean;
  /**
   * Operation is waiting to be executed.
   */
  isDue: boolean;
  /**
   * Timestamp when the pending operation should be executed next.
   */
  timestampDue: AbsoluteTime;
  /**
   * Retry info.  Currently used to stop the wallet after any operation
   * exceeds a number of retries.
   */
  retryInfo?: RetryInfo;
}

export enum PendingTaskType {
  ExchangeUpdate = "exchange-update",
  ExchangeCheckRefresh = "exchange-check-refresh",
  Purchase = "purchase",
  Refresh = "refresh",
  Recoup = "recoup",
  RewardPickup = "reward-pickup",
  Withdraw = "withdraw",
  Deposit = "deposit",
  Backup = "backup",
  PeerPushDebit = "peer-push-debit",
  PeerPullCredit = "peer-pull-credit",
  PeerPushCredit = "peer-push-credit",
  PeerPullDebit = "peer-pull-debit",
}

export type TaskId = string & {
  [__taskId]: true;
};

export interface RetryInfo {
  firstTry: AbsoluteTime;
  nextRetry: AbsoluteTime;
  retryCounter: number;
}

export interface RetryPolicy {
  readonly backoffDelta: Duration;
  readonly backoffBase: number;
  readonly maxTimeout: Duration;
}

// Declare "static" methods in Error
interface ErrorConstructor {
  /** Create .stack property on a target object */
  captureStackTrace(targetObject: object, constructorOpt?: Function): void;
  /**
   * Optional override for formatting stack traces
   *
   * @see https://v8.dev/docs/stack-trace-api#customizing-stack-traces
   */
  prepareStackTrace?:
    | ((err: Error, stackTraces: NodeJS.CallSite[]) => any)
    | undefined;
  stackTraceLimit: number;
}

interface CallSite {
  /**
   * Value of "this"
   */
  getThis(): unknown;
  /**
   * Type of "this" as a string.
   * This is the name of the function stored in the constructor field of
   * "this", if available.  Otherwise the object's [[Class]] internal
   * property.
   */
  getTypeName(): string | null;
  /**
   * Current function
   */
  getFunction(): Function | undefined;
  /**
   * Name of the current function, typically its name property.
   * If a name property is not available an attempt will be made to try
   * to infer a name from the function's context.
   */
  getFunctionName(): string | null;
  /**
   * Name of the property [of "this" or one of its prototypes] that holds
   * the current function
   */
  getMethodName(): string | null;
  /**
   * Name of the script [if this function was defined in a script]
   */
  getFileName(): string | null;
  /**
   * Current line number [if this function was defined in a script]
   */
  getLineNumber(): number | null;
  /**
   * Current column number [if this function was defined in a script]
   */
  getColumnNumber(): number | null;
  /**
   * A call site object representing the location where eval was called
   * [if this function was created using a call to eval]
   */
  getEvalOrigin(): string | undefined;
  /**
   * Is this a toplevel invocation, that is, is "this" the global object?
   */
  isToplevel(): boolean;
  /**
   * Does this call take place in code defined by a call to eval?
   */
  isEval(): boolean;
  /**
   * Is this call in native V8 code?
   */
  isNative(): boolean;
  /**
   * Is this a constructor call?
   */
  isConstructor(): boolean;
}

/**
 * The wallet is currently updating information about an exchange.
 */
export interface PendingExchangeUpdateTask {
  type: PendingTaskType.ExchangeUpdate;
  exchangeBaseUrl: string;
  lastError: TalerErrorDetail | undefined;
}

/**
 * The wallet should check whether coins from this exchange
 * need to be auto-refreshed.
 */
export interface PendingExchangeCheckRefreshTask {
  type: PendingTaskType.ExchangeCheckRefresh;
  exchangeBaseUrl: string;
}

/**
 * A purchase needs to be processed (i.e. for download / payment / refund).
 */
export interface PendingPurchaseTask {
  type: PendingTaskType.Purchase;
  proposalId: string;
  retryInfo?: RetryInfo;
  /**
   * Status of the payment as string, used only for debugging.
   */
  statusStr: string;
  lastError: TalerErrorDetail | undefined;
}

/**
 * Status of an ongoing withdrawal operation.
 */
export interface PendingRefreshTask {
  type: PendingTaskType.Refresh;
  lastError?: TalerErrorDetail;
  refreshGroupId: string;
  finishedPerCoin: boolean[];
  retryInfo?: RetryInfo;
}

/**
 * The wallet is picking up a tip that the user has accepted.
 */
export interface PendingTipPickupTask {
  type: PendingTaskType.RewardPickup;
  tipId: string;
  merchantBaseUrl: string;
  merchantTipId: string;
}

/**
 * Status of an ongoing withdrawal operation.
 */
export interface PendingWithdrawTask {
  type: PendingTaskType.Withdraw;
  lastError: TalerErrorDetail | undefined;
  retryInfo?: RetryInfo;
  withdrawalGroupId: string;
}

export interface PendingRecoupTask {
  type: PendingTaskType.Recoup;
  recoupGroupId: string;
  retryInfo?: RetryInfo;
  lastError: TalerErrorDetail | undefined;
}

/**
 * Status of an ongoing deposit operation.
 */
export interface PendingDepositTask {
  type: PendingTaskType.Deposit;
  lastError: TalerErrorDetail | undefined;
  retryInfo: RetryInfo | undefined;
  depositGroupId: string;
}

export interface PendingBackupTask {
  type: PendingTaskType.Backup;
  backupProviderBaseUrl: string;
  lastError: TalerErrorDetail | undefined;
}

/**
 * The wallet wants to send a peer push payment.
 */
export interface PendingPeerPushInitiationTask {
  type: PendingTaskType.PeerPushDebit;
  pursePub: string;
}

/**
 * The wallet wants to send a peer pull payment.
 */
export interface PendingPeerPullInitiationTask {
  type: PendingTaskType.PeerPullCredit;
  pursePub: string;
}

/**
 * The wallet wants to send a peer pull payment.
 */
export interface PendingPeerPullDebitTask {
  type: PendingTaskType.PeerPullDebit;
  peerPullPaymentIncomingId: string;
}

/**
 */
export interface PendingPeerPushCreditTask {
  type: PendingTaskType.PeerPushCredit;
  peerPushPaymentIncomingId: string;
}

1.5.2.81. DumpCoinsOp

/**
 * Dump all coins of the wallet in a simple JSON format.
 */
export type DumpCoinsOp = {
  op: WalletApiOperation.DumpCoins;
  request: EmptyObject;
  response: CoinDumpJson;
};
// DumpCoins = "dumpCoins"

/**
 * 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: DenominationPubKey;
    /**
     * 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;
    /**
     * 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;
    coin_status: CoinStatus;
    spend_allocation:
      | {
          id: string;
          amount: string;
        }
      | undefined;
    /**
     * Information about the age restriction
     */
    ageCommitmentProof: AgeCommitmentProof | undefined;
  }>;
}

export type DenominationPubKey = RsaDenominationPubKey | CsDenominationPubKey;

export interface RsaDenominationPubKey {
  readonly cipher: DenomKeyType.Rsa;
  readonly rsa_public_key: string;
  readonly age_mask: number;
}

export interface CsDenominationPubKey {
  readonly cipher: DenomKeyType.ClauseSchnorr;
  readonly age_mask: number;
  readonly cs_public_key: string;
}

/**
 * Status of a coin.
 */
export declare enum CoinStatus {
  /**
   * Withdrawn and never shown to anybody.
   */
  Fresh = "fresh",
  /**
   * Fresh, but currently marked as "suspended", thus won't be used
   * for spending.  Used for testing.
   */
  FreshSuspended = "fresh-suspended",
  /**
   * A coin that has been spent and refreshed.
   */
  Dormant = "dormant",
}

export interface AgeCommitmentProof {
  commitment: AgeCommitment;
  proof: AgeProof;
}

export interface AgeCommitment {
  mask: number;
  /**
   * Public keys, one for each age group specified in the age mask.
   */
  publicKeys: Edx25519PublicKeyEnc[];
}

export type Edx25519PublicKeyEnc = FlavorP<string, "Edx25519PublicKeyEnc", 32>;

export type FlavorP<T, FlavorT extends string, S extends number> = T & {
  _flavor?: `taler.${FlavorT}`;
  _size?: S;
};

export interface AgeProof {
  /**
   * Private keys.  Typically smaller than the number of public keys,
   * because we drop private keys from age groups that are restricted.
   */
  privateKeys: Edx25519PrivateKeyEnc[];
}

export type Edx25519PrivateKeyEnc = FlavorP<
  string,
  "Edx25519PrivateKeyEnc",
  64
>;

1.5.2.82. TestingSetTimetravelOp

/**
 * Add an offset to the wallet's internal time.
 */
export type TestingSetTimetravelOp = {
  op: WalletApiOperation.TestingSetTimetravel;
  request: TestingSetTimetravelRequest;
  response: EmptyObject;
};
// TestingSetTimetravel = "testingSetTimetravel"

export interface TestingSetTimetravelRequest {
  offsetMs: number;
}

1.5.2.83. SetCoinSuspendedOp

/**
 * Set a coin as (un-)suspended.
 * Suspended coins won't be used for payments.
 */
export type SetCoinSuspendedOp = {
  op: WalletApiOperation.SetCoinSuspended;
  request: SetCoinSuspendedRequest;
  response: EmptyObject;
};
// SetCoinSuspended = "setCoinSuspended"

export interface SetCoinSuspendedRequest {
  coinPub: string;
  suspended: boolean;
}

1.5.2.84. ForceRefreshOp

/**
 * Force a refresh on coins where it would not
 * be necessary.
 */
export type ForceRefreshOp = {
  op: WalletApiOperation.ForceRefresh;
  request: ForceRefreshRequest;
  response: EmptyObject;
};
// ForceRefresh = "forceRefresh"

export interface ForceRefreshRequest {
  coinPubList: string[];
}

1.5.3. Common Declarations

export interface WalletCoreVersion {
  /**
   * @deprecated
   */
  hash: string | undefined;
  version: string;
  exchange: string;
  merchant: string;
  bank: string;
  /**
   * @deprecated will be removed
   */
  devMode: boolean;
}

export type ScopeInfo = ScopeInfoGlobal | ScopeInfoExchange | ScopeInfoAuditor;

/**
 * How the amount should be interpreted in a transaction
 * Effective = how the balance is change
 * Raw = effective amount without fee
 *
 * Depending on the transaction, raw can be higher than effective
 */
export declare enum TransactionAmountMode {
  Effective = "effective",
  Raw = "raw",
}

export interface ConvertAmountRequest {
  amount: AmountString;
  type: TransactionAmountMode;
}

export interface AmountResponse {
  effectiveAmount: AmountString;
  rawAmount: AmountString;
}

export interface GetAmountRequest {
  currency: string;
}

export interface TransactionsResponse {
  transactions: Transaction[];
}

export type Transaction =
  | TransactionWithdrawal
  | TransactionPayment
  | TransactionRefund
  | TransactionReward
  | TransactionRefresh
  | TransactionDeposit
  | TransactionPeerPullCredit
  | TransactionPeerPullDebit
  | TransactionPeerPushCredit
  | TransactionPeerPushDebit
  | TransactionInternalWithdrawal;

/**
 * A withdrawal transaction (either bank-integrated or manual).
 */
export 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 interface TransactionCommon {
  transactionId: TransactionIdStr;
  type: TransactionType;
  timestamp: TalerPreciseTimestamp;
  /**
   * Transaction state, as per DD37.
   */
  txState: TransactionState;
  /**
   * Possible transitions based on the current state.
   */
  txActions: TransactionAction[];
  /**
   * 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?: TalerErrorDetail;
  /**
   * If the transaction minor state is in KycRequired this field is going to
   * have the location where the user need to go to complete KYC information.
   */
  kycUrl?: string;
}

export type TransactionIdStr = `txn:${string}:${string}` & {
  [__txId]: true;
};

export declare enum TransactionType {
  Withdrawal = "withdrawal",
  InternalWithdrawal = "internal-withdrawal",
  Payment = "payment",
  Refund = "refund",
  Refresh = "refresh",
  Reward = "reward",
  Deposit = "deposit",
  PeerPushDebit = "peer-push-debit",
  PeerPushCredit = "peer-push-credit",
  PeerPullDebit = "peer-pull-debit",
  PeerPullCredit = "peer-pull-credit",
}

export interface TalerPreciseTimestamp {
  /**
   * Seconds (as integer) since epoch.
   */
  readonly t_s: number | "never";
  /**
   * Optional microsecond offset (non-negative integer).
   */
  readonly off_us?: number;
  readonly _flavor?: typeof flavor_TalerPreciseTimestamp;
}

export interface TalerProtocolTimestamp {
  /**
   * Seconds (as integer) since epoch.
   */
  readonly t_s: number | "never";
  readonly _flavor?: typeof flavor_TalerProtocolTimestamp;
}

export interface TransactionState {
  major: TransactionMajorState;
  minor?: TransactionMinorState;
}

export declare enum TransactionMajorState {
  None = "none",
  Pending = "pending",
  Done = "done",
  Aborting = "aborting",
  Aborted = "aborted",
  Suspended = "suspended",
  Dialog = "dialog",
  SuspendedAborting = "suspended-aborting",
  Failed = "failed",
  Expired = "expired",
  Deleted = "deleted",
}

export declare enum TransactionMinorState {
  Unknown = "unknown",
  Deposit = "deposit",
  KycRequired = "kyc",
  AmlRequired = "aml",
  MergeKycRequired = "merge-kyc",
  Track = "track",
  SubmitPayment = "submit-payment",
  RebindSession = "rebind-session",
  Refresh = "refresh",
  Pickup = "pickup",
  AutoRefund = "auto-refund",
  User = "user",
  Bank = "bank",
  Exchange = "exchange",
  ClaimProposal = "claim-proposal",
  CheckRefund = "check-refund",
  CreatePurse = "create-purse",
  DeletePurse = "delete-purse",
  Ready = "ready",
  Merge = "merge",
  Repurchase = "repurchase",
  BankRegisterReserve = "bank-register-reserve",
  BankConfirmTransfer = "bank-confirm-transfer",
  WithdrawCoins = "withdraw-coins",
  ExchangeWaitReserve = "exchange-wait-reserve",
  AbortingBank = "aborting-bank",
  Aborting = "aborting",
  Refused = "refused",
  Withdraw = "withdraw",
  MerchantOrderProposed = "merchant-order-proposed",
  Proposed = "proposed",
  RefundAvailable = "refund-available",
  AcceptRefund = "accept-refund",
}

export declare enum TransactionAction {
  Delete = "delete",
  Suspend = "suspend",
  Resume = "resume",
  Abort = "abort",
  Fail = "fail",
  Retry = "retry",
}

export interface TalerErrorDetail {
  code: TalerErrorCode;
  when?: AbsoluteTime;
  hint?: string;
  [x: string]: unknown;
}

export interface AbsoluteTime {
  /**
   * Timestamp in milliseconds.
   */
  readonly t_ms: number | "never";
  readonly _flavor?: typeof flavor_AbsoluteTime;
  [opaque_AbsoluteTime]: true;
}

export interface Duration {
  /**
   * Duration in milliseconds.
   */
  readonly d_ms: number | "forever";
}

export interface TalerProtocolDuration {
  readonly d_us: number | "forever";
}

export type WithdrawalDetails =
  | WithdrawalDetailsForManualTransfer
  | WithdrawalDetailsForTalerBankIntegrationApi;

interface WithdrawalDetailsForManualTransfer {
  type: WithdrawalType.ManualTransfer;
  /**
   * Payto URIs that the exchange supports.
   *
   * Already contains the amount and message.
   */
  exchangePaytoUris: string[];
  reservePub: string;
  /**
   * Is the reserve ready for withdrawal?
   */
  reserveIsReady: boolean;
}

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;
  reservePub: string;
  /**
   * Is the reserve ready for withdrawal?
   */
  reserveIsReady: boolean;
}

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;
  /**
   * Amount that must be paid for the contract
   */
  amountRaw: AmountString;
  /**
   * Amount that was paid, including deposit, wire and refresh fees.
   */
  amountEffective: AmountString;
  /**
   * Amount that has been refunded by the merchant
   */
  totalRefundRaw: AmountString;
  /**
   * Amount will be added to the wallet's balance after fees and refreshing
   */
  totalRefundEffective: AmountString;
  /**
   * Amount pending to be picked up
   */
  refundPending: AmountString | undefined;
  /**
   * Reference to applied refunds
   */
  refunds: RefundInfoShort[];
  /**
   * Is the wallet currently checking for a refund?
   */
  refundQueryActive: boolean;
  /**
   * Does this purchase has an pos validation
   */
  posConfirmation: string | undefined;
}

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;
  /**
   * Time indicating when the order should be delivered.
   * May be overwritten by individual products.
   */
  delivery_date?: TalerProtocolTimestamp;
  /**
   * Delivery location for (all!) products.
   */
  delivery_location?: Location;
  /**
   * 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;
}

export interface MerchantInfo {
  name: string;
  jurisdiction?: Location;
  address?: Location;
  logo?: string;
  website?: string;
  email?: string;
}

export interface Location {
  country?: string;
  country_subdivision?: string;
  district?: string;
  town?: string;
  town_location?: string;
  post_code?: string;
  street?: string;
  building_name?: string;
  building_number?: string;
  address_lines?: string[];
}

export interface InternationalizedString {
  [lang_tag: string]: string;
}

export interface Product {
  product_id?: string;
  description: string;
  description_i18n?: {
    [lang_tag: string]: string;
  };
  quantity?: number;
  unit?: string;
  price?: AmountString;
  image?: string;
  taxes?: Tax[];
  delivery_date?: TalerProtocolTimestamp;
}

export interface Tax {
  name: string;
  tax: AmountString;
}

export interface RefundInfoShort {
  transactionId: string;
  timestamp: TalerProtocolTimestamp;
  amountEffective: AmountString;
  amountRaw: AmountString;
}

export interface TransactionRefund extends TransactionCommon {
  type: TransactionType.Refund;
  amountRaw: AmountString;
  amountEffective: AmountString;
  refundedTransactionId: string;
  paymentInfo: RefundPaymentInfo | undefined;
}

/**
 * Summary information about the payment that we got a refund for.
 */
export interface RefundPaymentInfo {
  summary: string;
  summary_i18n?: InternationalizedString;
  /**
   * More information about the merchant
   */
  merchant: MerchantInfo;
}

export interface TransactionReward extends TransactionCommon {
  type: TransactionType.Reward;
  amountRaw: AmountString;
  /**
   * More information about the merchant
   */
  amountEffective: AmountString;
  merchantBaseUrl: string;
}

/**
 * A transaction shown for refreshes.
 * Only shown for (1) refreshes not associated with other transactions
 * and (2) refreshes in an error state.
 */
export interface TransactionRefresh extends TransactionCommon {
  type: TransactionType.Refresh;
  refreshReason: RefreshReason;
  /**
   * Transaction ID that caused this refresh.
   */
  originatingTransactionId?: string;
  /**
   * Always zero for refreshes
   */
  amountRaw: AmountString;
  /**
   * Fees, i.e. the effective, negative effect of the refresh
   * on the balance.
   *
   * Only applicable for stand-alone refreshes, and zero for
   * other refreshes where the transaction itself accounts for the
   * refresh fee.
   */
  amountEffective: AmountString;
  refreshInputAmount: AmountString;
  refreshOutputAmount: AmountString;
}

/**
 * Reasons for why a coin is being refreshed.
 */
export declare enum RefreshReason {
  Manual = "manual",
  PayMerchant = "pay-merchant",
  PayDeposit = "pay-deposit",
  PayPeerPush = "pay-peer-push",
  PayPeerPull = "pay-peer-pull",
  Refund = "refund",
  AbortPay = "abort-pay",
  AbortDeposit = "abort-deposit",
  AbortPeerPushDebit = "abort-peer-push-debit",
  Recoup = "recoup",
  BackupRestored = "backup-restored",
  Scheduled = "scheduled",
}

/**
 * Deposit transaction, which effectively sends
 * money from this wallet somewhere else.
 */
export 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;
  wireTransferDeadline: TalerProtocolTimestamp;
  wireTransferProgress: number;
  /**
   * Did all the deposit requests succeed?
   */
  deposited: boolean;
  trackingState: Array<{
    wireTransferId: string;
    timestampExecuted: TalerProtocolTimestamp;
    amountRaw: AmountString;
    wireFee: AmountString;
  }>;
}

/**
 * Credit because we were paid for a P2P invoice we created.
 */
export interface TransactionPeerPullCredit extends TransactionCommon {
  type: TransactionType.PeerPullCredit;
  info: PeerInfoShort;
  /**
   * Exchange used.
   */
  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;
  /**
   * URI to send to the other party.
   */
  talerUri: string;
}

export interface PeerInfoShort {
  expiration: TalerProtocolTimestamp | undefined;
  summary: string | undefined;
}

/**
 * Debit because we paid someone's invoice.
 */
export interface TransactionPeerPullDebit extends TransactionCommon {
  type: TransactionType.PeerPullDebit;
  info: PeerInfoShort;
  /**
   * Exchange used.
   */
  exchangeBaseUrl: string;
  amountRaw: AmountString;
  amountEffective: AmountString;
}

/**
 * We received money via a P2P payment.
 */
export interface TransactionPeerPushCredit extends TransactionCommon {
  type: TransactionType.PeerPushCredit;
  info: PeerInfoShort;
  /**
   * Exchange used.
   */
  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;
}

/**
 * We sent money via a P2P payment.
 */
export interface TransactionPeerPushDebit extends TransactionCommon {
  type: TransactionType.PeerPushDebit;
  info: PeerInfoShort;
  /**
   * Exchange used.
   */
  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;
  /**
   * URI to accept the payment.
   */
  talerUri: string;
}

/**
 * Internal withdrawal operation, only reported on request.
 *
 * Some transactions (peer-*-credit) internally do a withdrawal,
 * but only the peer-*-credit transaction is reported.
 *
 * The internal withdrawal transaction allows to access the details of
 * the underlying withdrawal for testing/debugging.
 *
 * It is usually not reported, so that amounts of transactions properly
 * add up, since the amountEffecive of the withdrawal is already reported
 * in the peer-*-credit transaction.
 */
export interface TransactionInternalWithdrawal extends TransactionCommon {
  type: TransactionType.InternalWithdrawal;
  /**
   * 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 interface AbortTransactionRequest {
  transactionId: TransactionIdStr;
}

export interface ExchangeListItem {
  exchangeBaseUrl: string;
  currency: string | undefined;
  paytoUris: string[];
  tosStatus: ExchangeTosStatus;
  exchangeEntryStatus: ExchangeEntryStatus;
  exchangeUpdateStatus: ExchangeUpdateStatus;
  ageRestrictionOptions: number[];
  /**
   * Information about the last error that occurred when trying
   * to update the exchange info.
   */
  lastUpdateErrorInfo?: OperationErrorInfo;
}

export declare enum ExchangeTosStatus {
  Pending = "pending",
  Proposed = "proposed",
  Accepted = "accepted",
}

export declare enum ExchangeEntryStatus {
  Preset = "preset",
  Ephemeral = "ephemeral",
  Used = "used",
}

export declare enum ExchangeUpdateStatus {
  Initial = "initial",
  InitialUpdate = "initial(update)",
  Suspended = "suspended",
  Failed = "failed",
  OutdatedUpdate = "outdated(update)",
  Ready = "ready",
  ReadyUpdate = "ready(update)",
}

export interface OperationErrorInfo {
  error: TalerErrorDetail;
}

export interface ForcedDenomSel {
  denoms: {
    value: AmountString;
    count: number;
  }[];
}

/**
 * Result of a prepare pay operation.
 */
export type PreparePayResult =
  | PreparePayResultInsufficientBalance
  | PreparePayResultAlreadyConfirmed
  | PreparePayResultPaymentPossible;

export interface PreparePayResultInsufficientBalance {
  status: PreparePayResultType.InsufficientBalance;
  transactionId: TransactionIdStr;
  /**
   * @deprecated use transactionId
   */
  proposalId: string;
  contractTerms: MerchantContractTerms;
  amountRaw: string;
  talerUri: string;
  balanceDetails: PayMerchantInsufficientBalanceDetails;
}

/**
 * Contract terms from a merchant.
 * FIXME: Add type field!
 */
export interface MerchantContractTerms {
  /**
   * Hash of the merchant's wire details.
   */
  h_wire: string;
  /**
   * Hash of the merchant's wire details.
   */
  auto_refund?: TalerProtocolDuration;
  /**
   * 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;
  /**
   * Deadline to pay for the contract.
   */
  pay_deadline: TalerProtocolTimestamp;
  /**
   * 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?: TalerProtocolTimestamp;
  /**
   * 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: TalerProtocolTimestamp;
  /**
   * Deadline for the wire transfer.
   */
  wire_transfer_deadline: TalerProtocolTimestamp;
  /**
   * Time when the contract was generated by the merchant.
   */
  timestamp: TalerProtocolTimestamp;
  /**
   * 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;
  /**
   * URL meant to share the shopping cart.
   */
  public_reorder_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;
  minimum_age?: number;
  /**
   * Extra data, interpreted by the mechant only.
   */
  extra?: any;
}

/**
 * Information about an exchange as stored inside a
 * merchant's contract terms.
 */
export interface ExchangeHandle {
  /**
   * Master public signing key of the exchange.
   */
  master_pub: string;
  /**
   * Base URL of the exchange.
   */
  url: string;
}

/**
 * Detailed reason for why the wallet's balance is insufficient.
 */
export interface PayMerchantInsufficientBalanceDetails {
  /**
   * Amount requested by the merchant.
   */
  amountRequested: AmountString;
  /**
   * Balance of type "available" (see balance.ts for definition).
   */
  balanceAvailable: AmountString;
  /**
   * Balance of type "material" (see balance.ts for definition).
   */
  balanceMaterial: AmountString;
  /**
   * Balance of type "age-acceptable" (see balance.ts for definition).
   */
  balanceAgeAcceptable: AmountString;
  /**
   * Balance of type "merchant-acceptable" (see balance.ts for definition).
   */
  balanceMerchantAcceptable: AmountString;
  /**
   * Balance of type "merchant-depositable" (see balance.ts for definition).
   */
  balanceMerchantDepositable: AmountString;
  /**
   * If the payment would succeed without fees
   * (i.e. balanceMerchantDepositable >= amountRequested),
   * this field contains an estimate of the amount that would additionally
   * be required to cover the fees.
   *
   * It is not possible to give an exact value here, since it depends
   * on the coin selection for the amount that would be additionally withdrawn.
   */
  feeGapEstimate: AmountString;
}

export interface PreparePayResultAlreadyConfirmed {
  status: PreparePayResultType.AlreadyConfirmed;
  transactionId: TransactionIdStr;
  contractTerms: MerchantContractTerms;
  paid: boolean;
  amountRaw: string;
  amountEffective: string | undefined;
  contractTermsHash: string;
  /**
   * @deprecated use transactionId
   */
  proposalId: string;
  talerUri: string;
}

/**
 * Payment is possible.
 */
export interface PreparePayResultPaymentPossible {
  status: PreparePayResultType.PaymentPossible;
  transactionId: TransactionIdStr;
  /**
   * @deprecated use transactionId instead
   */
  proposalId: string;
  contractTerms: MerchantContractTerms;
  contractTermsHash: string;
  amountRaw: string;
  amountEffective: string;
  talerUri: string;
}

/**
 * Forced coin selection for deposits/payments.
 */
export interface ForcedCoinSel {
  coins: {
    value: AmountString;
    contribution: AmountString;
  }[];
}

export interface AddExchangeRequest {
  exchangeBaseUrl: string;
  masterPub?: string;
  forceUpdate?: boolean;
}

export interface BackupRecovery {
  walletRootPriv: string;
  providers: {
    name: string;
    url: string;
  }[];
}

/**
 * Contract terms between two wallets (as opposed to a merchant and wallet).
 */
export interface PeerContractTerms {
  amount: AmountString;
  summary: string;
  purse_expiration: TalerProtocolTimestamp;
}

export interface IntegrationTestArgs {
  exchangeBaseUrl: string;
  bankAccessApiBaseUrl: string;
  merchantBaseUrl: string;
  merchantAuthToken?: string;
  amountToWithdraw: string;
  amountToSpend: string;
}