/*
 This file is part of GNU Taler
 (C) 2022 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 
 */
declare module "*.css" {
  const mapping: Record;
  export default mapping;
}
declare module "*.svg" {
  const content: any;
  export default content;
}
declare module "*.jpeg" {
  const content: any;
  export default content;
}
declare module "*.png" {
  const content: any;
  export default content;
}
/**********************************************
 * Type definitions for states and API calls. *
 *********************************************/
/**
 * Request body of POST /transactions.
 *
 * If the amount appears twice: both as a Payto parameter and
 * in the JSON dedicate field, the one on the Payto URI takes
 * precedence.
 */
interface TransactionRequestType {
  paytoUri: string;
  amount?: string; // with currency.
}
/**
 * Request body of /register.
 */
interface CredentialsRequestType {
  username?: string;
  password?: string;
  repeatPassword?: string;
}
/**
 * Request body of /register.
 */
// interface LoginRequestType {
//   username: string;
//   password: string;
// }
interface WireTransferRequestType {
  iban?: string;
  subject?: string;
  amount?: string;
}
type HashCode = string;
type EddsaPublicKey = string;
type EddsaSignature = string;
type WireTransferIdentifierRawP = string;
type RelativeTime = Duration;
type ImageDataUrl = string;
interface WithId {
  id: string;
}
interface Timestamp {
  // Milliseconds since epoch, or the special
  // value "forever" to represent an event that will
  // never happen.
  t_s: number | "never";
}
interface Duration {
  d_us: number | "forever";
}
interface WithId {
  id: string;
}
type Amount = string;
type UUID = string;
type Integer = number;
namespace SandboxBackend {
  export interface Config {
    // Name of this API, always "circuit".
    name: string;
    // API version in the form $n:$n:$n
    version: string;
    // Contains ratios and fees related to buying
    // and selling the circuit currency.
    ratios_and_fees: RatiosAndFees;
  }
  interface RatiosAndFees {
    // Exchange rate to buy the circuit currency from fiat.
    buy_at_ratio: number;
    // Exchange rate to sell the circuit currency for fiat.
    sell_at_ratio: number;
    // Fee to subtract after applying the buy ratio.
    buy_in_fee: number;
    // Fee to subtract after applying the sell ratio.
    sell_out_fee: number;
  }
  export interface SandboxError {
    error: SandboxErrorDetail;
  }
  interface SandboxErrorDetail {
    // String enum classifying the error.
    type: ErrorType;
    // Human-readable error description.
    description: string;
  }
  enum ErrorType {
    /**
     * This error can be related to a business operation,
     * a non-existent object requested by the client, or
     * even when the bank itself fails.
     */
    SandboxError = "sandbox-error",
    /**
     * It is the error type thrown by helper functions
     * from the Util library.  Those are used by both
     * Sandbox and Nexus, therefore the actual meaning
     * must be carried by the error 'message' field.
     */
    UtilError = "util-error",
  }
  namespace Access {
    interface PublicAccountsResponse {
      publicAccounts: PublicAccount[];
    }
    interface PublicAccount {
      iban: string;
      balance: string;
      // The account name _and_ the username of the
      // Sandbox customer that owns such a bank account.
      accountLabel: string;
    }
    interface BankAccountBalanceResponse {
      // Available balance on the account.
      balance: {
        amount: Amount;
        credit_debit_indicator: "credit" | "debit";
      };
      // payto://-URI of the account. (New)
      paytoUri: string;
    }
    interface BankAccountCreateWithdrawalRequest {
      // Amount to withdraw.
      amount: Amount;
    }
    interface BankAccountCreateWithdrawalResponse {
      // ID of the withdrawal, can be used to view/modify the withdrawal operation.
      withdrawal_id: string;
      // URI that can be passed to the wallet to initiate the withdrawal.
      taler_withdraw_uri: string;
    }
    interface BankAccountGetWithdrawalResponse {
      // Amount that will be withdrawn with this withdrawal operation.
      amount: Amount;
      // Was the withdrawal aborted?
      aborted: boolean;
      // Has the withdrawal been confirmed by the bank?
      // The wire transfer for a withdrawal is only executed once
      // both confirmation_done is true and selection_done is true.
      confirmation_done: boolean;
      // Did the wallet select reserve details?
      selection_done: boolean;
      // Reserve public key selected by the exchange,
      // only non-null if selection_done is true.
      selected_reserve_pub: string | null;
      // Exchange account selected by the wallet, or by the bank
      // (with the default exchange) in case the wallet did not provide one
      // through the Integration API.
      selected_exchange_account: string | null;
    }
    interface BankAccountTransactionsResponse {
      transactions: BankAccountTransactionInfo[];
    }
    interface BankAccountTransactionInfo {
      creditorIban: string;
      creditorBic: string; // Optional
      creditorName: string;
      debtorIban: string;
      debtorBic: string;
      debtorName: string;
      amount: number;
      currency: string;
      subject: string;
      // Transaction unique ID.  Matches
      // $transaction_id from the URI.
      uid: string;
      direction: "DBIT" | "CRDT";
      date: string; // milliseconds since the Unix epoch
    }
    interface CreateBankAccountTransactionCreate {
      // Address in the Payto format of the wire transfer receiver.
      // It needs at least the 'message' query string parameter.
      paytoUri: string;
      // Transaction amount (in the $currency:x.y format), optional.
      // However, when not given, its value must occupy the 'amount'
      // query string parameter of the 'payto' field.  In case it
      // is given in both places, the paytoUri's takes the precedence.
      amount?: string;
    }
    interface BankRegistrationRequest {
      username: string;
      password: string;
    }
  }
  namespace Circuit {
    interface CircuitAccountRequest {
      // Username
      username: string;
      // Password.
      password: string;
      // Addresses where to send the TAN.  If
      // this field is missing, then the cashout
      // won't succeed.
      contact_data: CircuitContactData;
      // Legal subject owning the account.
      name: string;
      // 'payto' address pointing the bank account
      // where to send payments, in case the user
      // wants to convert the local currency back
      // to fiat.
      cashout_address: string;
      // IBAN of this bank account, which is therefore
      // internal to the circuit.  Randomly generated,
      // when it is not given.
      internal_iban?: string;
    }
    interface CircuitContactData {
      // E-Mail address
      email?: string;
      // Phone number.
      phone?: string;
    }
    interface CircuitAccountReconfiguration {
      // Addresses where to send the TAN.
      contact_data: CircuitContactData;
      // 'payto' address pointing the bank account
      // where to send payments, in case the user
      // wants to convert the local currency back
      // to fiat.
      cashout_address: string;
    }
    interface AccountPasswordChange {
      // New password.
      new_password: string;
    }
    interface CircuitAccounts {
      customers: CircuitAccountMinimalData[];
    }
    interface CircuitAccountMinimalData {
      // Username
      username: string;
      // Legal subject owning the account.
      name: string;
    }
    interface CircuitAccountData {
      // Username
      username: string;
      // IBAN hosted at Libeufin Sandbox
      iban: string;
      contact_data: CircuitContactData;
      // Legal subject owning the account.
      name: string;
      // 'payto' address pointing the bank account
      // where to send cashouts.
      cashout_address: string;
    }
    enum TanChannel {
      SMS = "sms",
      EMAIL = "email",
      FILE = "file",
    }
    interface CashoutRequest {
      // Optional subject to associate to the
      // cashout operation.  This data will appear
      // as the incoming wire transfer subject in
      // the user's external bank account.
      subject?: string;
      // That is the plain amount that the user specified
      // to cashout.  Its $currency is the circuit currency.
      amount_debit: Amount;
      // That is the amount that will effectively be
      // transferred by the bank to the user's bank
      // account, that is external to the circuit.
      // It is expressed in the fiat currency and
      // is calculated after the cashout fee and the
      // exchange rate.  See the /cashout-rates call.
      amount_credit: Amount;
      // Which channel the TAN should be sent to.  If
      // this field is missing, it defaults to SMS.
      // The default choice prefers to change the communication
      // channel respect to the one used to issue this request.
      tan_channel?: TanChannel;
    }
    interface CashoutPending {
      // UUID identifying the operation being created
      // and now waiting for the TAN confirmation.
      uuid: string;
    }
    interface CashoutConfirm {
      // the TAN that confirms $cashoutId.
      tan: string;
    }
    interface Config {
      // Name of this API, always "circuit".
      name: string;
      // API version in the form $n:$n:$n
      version: string;
      // Contains ratios and fees related to buying
      // and selling the circuit currency.
      ratios_and_fees: RatiosAndFees;
    }
    interface RatiosAndFees {
      // Exchange rate to buy the circuit currency from fiat.
      buy_at_ratio: float;
      // Exchange rate to sell the circuit currency for fiat.
      sell_at_ratio: float;
      // Fee to subtract after applying the buy ratio.
      buy_in_fee: float;
      // Fee to subtract after applying the sell ratio.
      sell_out_fee: float;
    }
    interface Cashouts {
      // Every string represents a cash-out operation UUID.
      cashouts: string[];
    }
    interface CashoutStatusResponse {
      status: CashoutStatus;
      // Amount debited to the circuit bank account.
      amount_debit: Amount;
      // Amount credited to the external bank account.
      amount_credit: Amount;
      // Transaction subject.
      subject: string;
      // Circuit bank account that created the cash-out.
      account: string;
      // Time when the cash-out was created.
      creation_time: number; // milliseconds since the Unix epoch
      // Time when the cash-out was confirmed via its TAN.
      // Missing or null, when the operation wasn't confirmed yet.
      confirmation_time?: number | null; // milliseconds since the Unix epoch
    }
    enum CashoutStatus {
      // The payment was initiated after a valid
      // TAN was received by the bank.
      CONFIRMED = "confirmed",
      // The cashout was created and now waits
      // for the TAN by the author.
      PENDING = "pending",
    }
  }
}