/*
 This file is part of GNU Taler
 (C) 2021 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 high-level interface to wallet-core.
 *
 * Documentation is auto-generated from this file.
 */

/**
 * Imports.
 */
import {
  AbortTransactionRequest,
  AcceptBankIntegratedWithdrawalRequest,
  AcceptExchangeTosRequest,
  AcceptManualWithdrawalRequest,
  AcceptManualWithdrawalResult,
  AcceptPeerPullPaymentResponse,
  AcceptPeerPushPaymentResponse,
  AcceptWithdrawalResponse,
  AddBankAccountRequest,
  AddBankAccountResponse,
  AddContactRequest,
  AddExchangeRequest,
  AddExchangeResponse,
  AddGlobalCurrencyAuditorRequest,
  AddGlobalCurrencyExchangeRequest,
  AddMailboxMessageRequest,
  AmountResponse,
  ApplyDevExperimentRequest,
  BackupRecovery,
  BalancesResponse,
  CanonicalizeBaseUrlRequest,
  CanonicalizeBaseUrlResponse,
  CheckDepositRequest,
  CheckDepositResponse,
  CheckPayTemplateReponse,
  CheckPayTemplateRequest,
  CheckPeerPullCreditRequest,
  CheckPeerPullCreditResponse,
  CheckPeerPushDebitOkResponse,
  CheckPeerPushDebitRequest,
  CheckPeerPushDebitResponse,
  CoinDumpJson,
  CompleteBaseUrlRequest,
  CompleteBaseUrlResult,
  ConfirmPayRequest,
  ConfirmPayResult,
  ConfirmPeerPullDebitRequest,
  ConfirmPeerPushCreditRequest,
  ConfirmWithdrawalRequest,
  ContactListResponse,
  ConvertAmountRequest,
  ConvertIbanAccountFieldToPaytoRequest,
  ConvertIbanAccountFieldToPaytoResponse,
  ConvertIbanPaytoToAccountFieldRequest,
  ConvertIbanPaytoToAccountFieldResponse,
  CreateDepositGroupRequest,
  CreateDepositGroupResponse,
  CreateStoredBackupResponse,
  DeleteContactRequest,
  DeleteDiscountRequest,
  DeleteExchangeRequest,
  DeleteMailboxMessageRequest,
  DeleteStoredBackupRequest,
  DeleteSubscriptionRequest,
  DeleteTransactionRequest,
  EmptyObject,
  ExchangeDetailedResponse,
  ExchangesListResponse,
  ExportDbToFileRequest,
  ExportDbToFileResponse,
  FailTransactionRequest,
  ForceRefreshRequest,
  ForgetBankAccountRequest,
  GetActiveTasksResponse,
  GetBalanceDetailRequest,
  GetBankAccountByIdRequest,
  GetBankAccountByIdResponse,
  GetBankingChoicesForPaytoRequest,
  GetBankingChoicesForPaytoResponse,
  GetChoicesForPaymentRequest,
  GetChoicesForPaymentResult,
  GetCurrencySpecificationRequest,
  GetCurrencySpecificationResponse,
  GetDepositWireTypesForCurrencyRequest,
  GetDepositWireTypesForCurrencyResponse,
  GetDepositWireTypesRequest,
  GetDepositWireTypesResponse,
  GetDonauResponse,
  GetDonauStatementsRequest,
  GetDonauStatementsResponse,
  GetExchangeDetailedInfoRequest,
  GetExchangeEntryByUrlRequest,
  GetExchangeEntryByUrlResponse,
  GetExchangeResourcesRequest,
  GetExchangeResourcesResponse,
  GetExchangeTosRequest,
  GetExchangeTosResult,
  GetMaxDepositAmountRequest,
  GetMaxDepositAmountResponse,
  GetMaxPeerPushDebitAmountRequest,
  GetMaxPeerPushDebitAmountResponse,
  GetQrCodesForPaytoRequest,
  GetQrCodesForPaytoResponse,
  GetTransactionsV2Request,
  GetWithdrawalDetailsForAmountRequest,
  GetWithdrawalDetailsForUriRequest,
  HintNetworkAvailabilityRequest,
  ImportDbFromFileRequest,
  ImportDbRequest,
  InitRequest,
  InitResponse,
  InitiatePeerPullCreditRequest,
  InitiatePeerPullCreditResponse,
  InitiatePeerPushDebitRequest,
  InitiatePeerPushDebitResponse,
  IntegrationTestArgs,
  IntegrationTestV2Args,
  ListAssociatedRefreshesRequest,
  ListAssociatedRefreshesResponse,
  ListBankAccountsRequest,
  ListBankAccountsResponse,
  ListDiscountsRequest,
  ListDiscountsResponse,
  ListExchangesRequest,
  ListGlobalCurrencyAuditorsResponse,
  ListGlobalCurrencyExchangesResponse,
  ListSubscriptionsRequest,
  ListSubscriptionsResponse,
  MailboxConfiguration,
  MailboxMessageRecord,
  MailboxMessagesResponse,
  PrepareBankIntegratedWithdrawalRequest,
  PrepareBankIntegratedWithdrawalResponse,
  PreparePayRequest,
  PreparePayResult,
  PreparePayTemplateRequest,
  PreparePeerPullDebitRequest,
  PreparePeerPullDebitResponse,
  PreparePeerPushCreditRequest,
  PreparePeerPushCreditResponse,
  PrepareRefundRequest,
  PrepareWithdrawExchangeRequest,
  PrepareWithdrawExchangeResponse,
  RecoverStoredBackupRequest,
  RecoveryLoadRequest,
  RemoveGlobalCurrencyAuditorRequest,
  RemoveGlobalCurrencyExchangeRequest,
  RetryTransactionRequest,
  RunFixupRequest,
  SendTalerUriMailboxMessageRequest,
  SetCoinSuspendedRequest,
  SetDonauRequest,
  SetWalletDeviceIdRequest,
  SharePaymentRequest,
  SharePaymentResult,
  StartExchangeWalletKycRequest,
  StartRefundQueryForUriResponse,
  StartRefundQueryRequest,
  StoredBackupList,
  TestPayArgs,
  TestPayResult,
  TestingGetDenomStatsRequest,
  TestingGetDenomStatsResponse,
  TestingGetReserveHistoryRequest,
  TestingPlanMigrateExchangeBaseUrlRequest,
  TestingSetTimetravelRequest,
  TestingWaitExchangeStateRequest,
  TestingWaitTransactionRequest,
  TestingWaitWalletKycRequest,
  Transaction,
  TransactionByIdRequest,
  TransactionsRequest,
  TransactionsResponse,
  TxIdResponse,
  UpdateExchangeEntryRequest,
  UserAttentionByIdRequest,
  UserAttentionsCountResponse,
  UserAttentionsRequest,
  UserAttentionsResponse,
  ValidateIbanRequest,
  ValidateIbanResponse,
  WalletCoreVersion,
  WithdrawTestBalanceRequest,
  WithdrawUriInfoResponse,
  WithdrawalDetailsForAmount,
} from "@gnu-taler/taler-util";
import {
  AddBackupProviderRequest,
  AddBackupProviderResponse,
  BackupInfo,
  RemoveBackupProviderRequest,
  RunBackupCycleRequest,
} from "./backup/index.js";
import { PaymentBalanceDetails } from "./balance.js";
import { WithdrawTestBalanceResult } from "./testing.js";

export enum WalletApiOperation {
  InitWallet = "initWallet",
  SetWalletRunConfig = "setWalletRunConfig",
  WithdrawTestkudos = "withdrawTestkudos",
  WithdrawTestBalance = "withdrawTestBalance",
  PreparePayForUri = "preparePayForUri",
  SharePayment = "sharePayment",
  CheckPayForTemplate = "checkPayForTemplate",
  PreparePayForTemplate = "preparePayForTemplate",
  RunIntegrationTest = "runIntegrationTest",
  RunIntegrationTestV2 = "runIntegrationTestV2",
  TestCrypto = "testCrypto",
  TestPay = "testPay",
  AddExchange = "addExchange",
  GetTransactions = "getTransactions",
  GetTransactionsV2 = "getTransactionsV2",
  GetTransactionById = "getTransactionById",
  TestingGetSampleTransactions = "testingGetSampleTransactions",
  ListExchanges = "listExchanges",
  GetExchangeEntryByUrl = "getExchangeEntryByUrl",
  ListBankAccounts = "listBankAccounts",
  GetBankAccountById = "getBankAccountById",
  AddBankAccount = "addBankAccount",
  ForgetBankAccount = "forgetBankAccount",
  GetWithdrawalDetailsForAmount = "getWithdrawalDetailsForAmount",
  AcceptManualWithdrawal = "acceptManualWithdrawal",
  GetBalances = "getBalances",
  GetBalanceDetail = "getBalanceDetail",
  ConvertDepositAmount = "convertDepositAmount",
  GetMaxDepositAmount = "getMaxDepositAmount",
  GetMaxPeerPushDebitAmount = "getMaxPeerPushDebitAmount",
  GetUserAttentionRequests = "getUserAttentionRequests",
  GetUserAttentionUnreadCount = "getUserAttentionUnreadCount",
  MarkAttentionRequestAsRead = "markAttentionRequestAsRead",
  GetActiveTasks = "getActiveTasks",
  SetExchangeTosAccepted = "setExchangeTosAccepted",
  SetExchangeTosForgotten = "setExchangeTosForgotten",
  StartRefundQueryForUri = "startRefundQueryForUri",
  StartRefundQuery = "startRefundQuery",
  PrepareBankIntegratedWithdrawal = "prepareBankIntegratedWithdrawal",
  ConfirmWithdrawal = "confirmWithdrawal",
  AcceptBankIntegratedWithdrawal = "acceptBankIntegratedWithdrawal",
  GetExchangeTos = "getExchangeTos",
  GetExchangeDetailedInfo = "getExchangeDetailedInfo",
  AddContact = "addContact",
  DeleteContact = "deleteContact",
  GetContacts = "getContacts",
  GetMailbox = "getMailbox",
  InitializeMailbox = "initializeMailbox",
  GetMailboxMessages = "getMailboxMessage",
  AddMailboxMessage = "addMailboxMessage",
  DeleteMailboxMessage = "deleteMailboxMessage",
  SendTalerUriMailboxMessage = "sendTalerUriMailboxMessage",
  RefreshMailbox = "refreshMailbox",
  RetryPendingNow = "retryPendingNow",
  AbortTransaction = "abortTransaction",
  FailTransaction = "failTransaction",
  SuspendTransaction = "suspendTransaction",
  ResumeTransaction = "resumeTransaction",
  DeleteTransaction = "deleteTransaction",
  RetryTransaction = "retryTransaction",
  GetChoicesForPayment = "getChoicesForPayment",
  ConfirmPay = "confirmPay",
  DumpCoins = "dumpCoins",
  SetCoinSuspended = "setCoinSuspended",
  ForceRefresh = "forceRefresh",
  CheckDeposit = "checkDeposit",
  GetVersion = "getVersion",
  GenerateDepositGroupTxId = "generateDepositGroupTxId",
  CreateDepositGroup = "createDepositGroup",
  ImportDb = "importDb",
  ExportDb = "exportDb",
  ExportDbToFile = "exportDbToFile",
  ImportDbFromFile = "importDbFromFile",
  PreparePeerPushCredit = "preparePeerPushCredit",
  CheckPeerPushDebit = "checkPeerPushDebit",
  CheckPeerPushDebitV2 = "checkPeerPushDebitV2",
  InitiatePeerPushDebit = "initiatePeerPushDebit",
  ConfirmPeerPushCredit = "confirmPeerPushCredit",
  CheckPeerPullCredit = "checkPeerPullCredit",
  InitiatePeerPullCredit = "initiatePeerPullCredit",
  PreparePeerPullDebit = "preparePeerPullDebit",
  ConfirmPeerPullDebit = "confirmPeerPullDebit",
  ClearDb = "clearDb",
  Recycle = "recycle",
  ApplyDevExperiment = "applyDevExperiment",
  ValidateIban = "validateIban",
  GetCurrencySpecification = "getCurrencySpecification",
  UpdateExchangeEntry = "updateExchangeEntry",
  PrepareWithdrawExchange = "prepareWithdrawExchange",
  GetExchangeResources = "getExchangeResources",
  CompleteExchangeBaseUrl = "completeExchangeBaseUrl",
  DeleteExchange = "deleteExchange",
  ListGlobalCurrencyExchanges = "listGlobalCurrencyExchanges",
  ListGlobalCurrencyAuditors = "listGlobalCurrencyAuditors",
  AddGlobalCurrencyExchange = "addGlobalCurrencyExchange",
  RemoveGlobalCurrencyExchange = "removeGlobalCurrencyExchange",
  AddGlobalCurrencyAuditor = "addGlobalCurrencyAuditor",
  RemoveGlobalCurrencyAuditor = "removeGlobalCurrencyAuditor",
  ListAssociatedRefreshes = "listAssociatedRefreshes",
  Shutdown = "shutdown",
  CanonicalizeBaseUrl = "canonicalizeBaseUrl",
  GetDepositWireTypes = "getDepositWireTypes",
  GetDepositWireTypesForCurrency = "getDepositWireTypesForCurrency",
  GetQrCodesForPayto = "getQrCodesForPayto",
  StartExchangeWalletKyc = "startExchangeWalletKyc",
  GetBankingChoicesForPayto = "getBankingChoicesForPayto",
  ConvertIbanAccountFieldToPayto = "convertIbanAccountFieldToPayto",
  ConvertIbanPaytoToAccountField = "convertIbanPaytoToAccountField",

  // Tokens and token families
  ListDiscounts = "listDiscounts",
  DeleteDiscount = "deleteDiscount",
  ListSubscriptions = "listSubscriptions",
  DeleteSubscription = "deleteSubscription",

  // Donau
  SetDonau = "setDonau",
  GetDonau = "getDonau",
  GetDonauStatements = "getDonauStatements",

  // Stored backups

  ListStoredBackups = "listStoredBackups",
  CreateStoredBackup = "createStoredBackup",
  DeleteStoredBackup = "deleteStoredBackup",
  RecoverStoredBackup = "recoverStoredBackup",

  // legacy backup functionality

  SetWalletDeviceId = "setWalletDeviceId",
  ExportBackup = "exportBackup",
  AddBackupProvider = "addBackupProvider",
  RemoveBackupProvider = "removeBackupProvider",
  RunBackupCycle = "runBackupCycle",
  ExportBackupRecovery = "exportBackupRecovery",
  ImportBackupRecovery = "importBackupRecovery",
  GetBackupInfo = "getBackupInfo",

  // Testing

  TestingWaitTransactionsFinal = "testingWaitTransactionsFinal",
  TestingWaitRefreshesFinal = "testingWaitRefreshesFinal",
  TestingWaitTransactionState = "testingWaitTransactionState",
  TestingWaitExchangeState = "testingWaitExchangeState",
  TestingWaitTasksDone = "testingWaitTasksDone",
  TestingGetDbStats = "testingGetDbStats",
  TestingSetTimetravel = "testingSetTimetravel",
  TestingGetDenomStats = "testingGetDenomStats",
  TestingPing = "testingPing",
  TestingGetReserveHistory = "testingGetReserveHistory",
  TestingResetAllRetries = "testingResetAllRetries",
  TestingWaitExchangeWalletKyc = "testingWaitWalletKyc",
  TestingPlanMigrateExchangeBaseUrl = "testingPlanMigrateExchangeBaseUrl",
  TestingRunFixup = "testingRunFixup",

  // Hints

  HintNetworkAvailability = "hintNetworkAvailability",
  HintApplicationResumed = "hintApplicationResumed",

  /**
   * @deprecated (2025-05-07)
   *   Use {@link WalletApiOperation.PrepareBankIntegratedWithdrawal} instead.
   */
  GetWithdrawalDetailsForUri = "getWithdrawalDetailsForUri",
}

// group: Initialization

/**
 * Initialize wallet-core.
 *
 * Must be the first request made to wallet-core.
 */
export type InitWalletOp = {
  op: WalletApiOperation.InitWallet;
  request: InitRequest;
  response: InitResponse;
};

export type ShutdownOp = {
  op: WalletApiOperation.Shutdown;
  request: EmptyObject;
  response: EmptyObject;
};

/**
 * Give wallet-core a kick and restart all pending tasks.
 * Useful when the host application gets suspended and resumed,
 * and active network requests might have stalled.
 */
export type HintApplicationResumedOp = {
  op: WalletApiOperation.HintApplicationResumed;
  request: EmptyObject;
  response: EmptyObject;
};

/**
 * Change the configuration of wallet-core.
 *
 * Currently an alias for the initWallet request.
 */
export type SetWalletRunConfigOp = {
  op: WalletApiOperation.SetWalletRunConfig;
  request: InitRequest;
  response: InitResponse;
};

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

export type HintNetworkAvailabilityOp = {
  op: WalletApiOperation.HintNetworkAvailability;
  request: HintNetworkAvailabilityRequest;
  response: EmptyObject;
};

// group: Donau

/**
 * Set the donation authority for this wallet.
 */
export type SetDonauOp = {
  op: WalletApiOperation.SetDonau;
  request: SetDonauRequest;
  response: EmptyObject;
};

/**
 * Get the currently configured donation authority for this
 * wallet.
 */
export type GetDonauOp = {
  op: WalletApiOperation.GetDonau;
  request: EmptyObject;
  response: GetDonauResponse;
};

/**
 * Get a list of donation statements
 * for this wallet.
 * Both donation statements for the currently configured
 * donation authority as well as past configurations (if they exist)
 * are returned.
 */
export type GetDonauStatementsOp = {
  op: WalletApiOperation.GetDonauStatements;
  request: GetDonauStatementsRequest;
  response: GetDonauStatementsResponse;
};

// group: Contacts

/**
 * add contact.
 */
export type AddContactOp = {
  op: WalletApiOperation.AddContact;
  request: AddContactRequest;
  response: EmptyObject;
};

/**
 * delete contact.
 */
export type DeleteContactOp = {
  op: WalletApiOperation.DeleteContact;
  request: DeleteContactRequest;
  response: EmptyObject;
};

/**
 * Get contacts.
 */
export type GetContactsOp = {
  op: WalletApiOperation.GetContacts;
  request: EmptyObject;
  response: ContactListResponse;
};

// group: Mailbox

/**
 * Refresh mailbox Op.
 */
export type RefreshMailboxOp = {
  op: WalletApiOperation.RefreshMailbox;
  request: MailboxConfiguration;
  response: MailboxMessageRecord[];
};

/**
 * Initialize messages mailbox Op.
 */
export type InitializeMailboxOp = {
  op: WalletApiOperation.InitializeMailbox;
  request: string;
  response: MailboxConfiguration;
};

/**
 * Get messages mailbox Op.
 */
export type GetMailboxOp = {
  op: WalletApiOperation.GetMailbox;
  request: string;
  response: MailboxConfiguration | undefined;
};

/**
 * Get Messages Op.
 */
export type GetMailboxMessagesOp = {
  op: WalletApiOperation.GetMailboxMessages;
  request: EmptyObject;
  response: MailboxMessagesResponse;
};

/**
 * delete message.
 */
export type DeleteMailboxMessageOp = {
  op: WalletApiOperation.DeleteMailboxMessage;
  request: DeleteMailboxMessageRequest;
  response: EmptyObject;
};

/**
 * add message.
 */
export type AddMailboxMessageOp = {
  op: WalletApiOperation.AddMailboxMessage;
  request: AddMailboxMessageRequest;
  response: EmptyObject;
};

/**
 * send message.
 */
export type SendTalerUriMailboxMessageOp = {
  op: WalletApiOperation.SendTalerUriMailboxMessage;
  request: SendTalerUriMailboxMessageRequest;
  response: EmptyObject;
};

// group: Basic Wallet Information

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

export type GetBalancesDetailOp = {
  op: WalletApiOperation.GetBalanceDetail;
  request: GetBalanceDetailRequest;
  response: PaymentBalanceDetails;
};

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

export type GetMaxDepositAmountOp = {
  op: WalletApiOperation.GetMaxDepositAmount;
  request: GetMaxDepositAmountRequest;
  response: GetMaxDepositAmountResponse;
};

export type GetMaxPeerPushDebitAmountOp = {
  op: WalletApiOperation.GetMaxPeerPushDebitAmount;
  request: GetMaxPeerPushDebitAmountRequest;
  response: GetMaxPeerPushDebitAmountResponse;
};

// group: Managing Transactions

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

export type GetTransactionsV2Op = {
  op: WalletApiOperation.GetTransactionsV2;
  request: GetTransactionsV2Request;
  response: TransactionsResponse;
};

/**
 * List refresh transactions associated with another transaction.
 */
export type ListAssociatedRefreshesOp = {
  op: WalletApiOperation.ListAssociatedRefreshes;
  request: ListAssociatedRefreshesRequest;
  response: ListAssociatedRefreshesResponse;
};

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

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

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

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

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

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

/**
 * 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;
};

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

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

// group: Withdrawals

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

/**
 * Get details for withdrawing via a particular taler:// URI.
 *
 * @deprecated Use {@link PrepareBankIntegratedWithdrawalOp} instead
 */
export type GetWithdrawalDetailsForUriOp = {
  op: WalletApiOperation.GetWithdrawalDetailsForUri;
  request: GetWithdrawalDetailsForUriRequest;
  response: WithdrawUriInfoResponse;
};

/**
 * Prepare a bank-integrated withdrawal operation.
 */
export type PrepareBankIntegratedWithdrawalOp = {
  op: WalletApiOperation.PrepareBankIntegratedWithdrawal;
  request: PrepareBankIntegratedWithdrawalRequest;
  response: PrepareBankIntegratedWithdrawalResponse;
};

/**
 * Confirm a withdrawal transaction.
 */
export type ConfirmWithdrawalOp = {
  op: WalletApiOperation.ConfirmWithdrawal;
  request: ConfirmWithdrawalRequest;
  response: AcceptWithdrawalResponse;
};

/**
 * Accept a bank-integrated withdrawal.
 *
 * @deprecated in favor of prepare/confirm withdrawal.
 */
export type AcceptBankIntegratedWithdrawalOp = {
  op: WalletApiOperation.AcceptBankIntegratedWithdrawal;
  request: AcceptBankIntegratedWithdrawalRequest;
  response: AcceptWithdrawalResponse;
};

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

// group: Merchant Payments

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

/**
 * Get a list of contract v1 choices for a given payment tx
 * in dialog(confirm) state, as well as additional information
 * on whether they can be used to pay the order or not, depending
 * on the funds available on the wallet, or whether a specific
 * choice should be paid automatically without user confirmation,
 * based on user configuration or the type of payment requested.
 *
 * This request will fail if contract choices are not yet
 * available, in which case the `choicesAvailable' field of the tx
 * will be undefined or set to false.
 */
export type GetChoicesForPaymentOp = {
  op: WalletApiOperation.GetChoicesForPayment;
  request: GetChoicesForPaymentRequest;
  response: GetChoicesForPaymentResult;
};

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

export type CheckPayForTemplateOp = {
  op: WalletApiOperation.CheckPayForTemplate;
  request: CheckPayTemplateRequest;
  response: CheckPayTemplateReponse;
};

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

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

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

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

// group: Token family management

/**
 * List discount tokens stored in the wallet. Listed tokens
 * will be grouped based on token family details.
 */
export type ListDiscountsOp = {
  op: WalletApiOperation.ListDiscounts;
  request: ListDiscountsRequest;
  response: ListDiscountsResponse;
};

export type DeleteDiscountOp = {
  op: WalletApiOperation.DeleteDiscount;
  request: DeleteDiscountRequest;
  response: EmptyObject;
};

/**
 * List subscription tokens stored in the wallet. Listed tokens
 * will be grouped based on token family details.
 */
export type ListSubscriptionsOp = {
  op: WalletApiOperation.ListSubscriptions;
  request: ListSubscriptionsRequest;
  response: ListSubscriptionsResponse;
};

export type DeleteSubscriptionOp = {
  op: WalletApiOperation.DeleteSubscription;
  request: DeleteSubscriptionRequest;
  response: EmptyObject;
};

// group: Global Currency management

export type ListGlobalCurrencyAuditorsOp = {
  op: WalletApiOperation.ListGlobalCurrencyAuditors;
  request: EmptyObject;
  response: ListGlobalCurrencyAuditorsResponse;
};

export type ListGlobalCurrencyExchangesOp = {
  op: WalletApiOperation.ListGlobalCurrencyExchanges;
  request: EmptyObject;
  response: ListGlobalCurrencyExchangesResponse;
};

export type AddGlobalCurrencyExchangeOp = {
  op: WalletApiOperation.AddGlobalCurrencyExchange;
  request: AddGlobalCurrencyExchangeRequest;
  response: EmptyObject;
};

export type AddGlobalCurrencyAuditorOp = {
  op: WalletApiOperation.AddGlobalCurrencyAuditor;
  request: AddGlobalCurrencyAuditorRequest;
  response: EmptyObject;
};

export type RemoveGlobalCurrencyExchangeOp = {
  op: WalletApiOperation.RemoveGlobalCurrencyExchange;
  request: RemoveGlobalCurrencyExchangeRequest;
  response: EmptyObject;
};

export type RemoveGlobalCurrencyAuditorOp = {
  op: WalletApiOperation.RemoveGlobalCurrencyAuditor;
  request: RemoveGlobalCurrencyAuditorRequest;
  response: EmptyObject;
};

// group: Exchange Management

/**
 * Force a refresh on coins where it would not
 * be necessary.
 */
export type CompleteExchangeBaseUrlOp = {
  op: WalletApiOperation.CompleteExchangeBaseUrl;
  request: CompleteBaseUrlRequest;
  response: CompleteBaseUrlResult;
};

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

export type StartExchangeWalletKycOp = {
  op: WalletApiOperation.StartExchangeWalletKyc;
  request: StartExchangeWalletKycRequest;
  response: EmptyObject;
};

export type TestingWaitExchangeWalletKycOp = {
  op: WalletApiOperation.TestingWaitExchangeWalletKyc;
  request: TestingWaitWalletKycRequest;
  response: EmptyObject;
};

/**
 * Enable migration from an old exchange base URL to a new
 * exchange base URL.
 *
 * The actual migration is only applied once the exchange
 * returns the new base URL.
 */
export type TestingPlanMigrateExchangeBaseUrlOp = {
  op: WalletApiOperation.TestingPlanMigrateExchangeBaseUrl;
  request: TestingPlanMigrateExchangeBaseUrlRequest;
  response: EmptyObject;
};

/**
 * Prepare for withdrawing via a taler://withdraw-exchange URI.
 */
export type PrepareWithdrawExchangeOp = {
  op: WalletApiOperation.PrepareWithdrawExchange;
  request: PrepareWithdrawExchangeRequest;
  response: PrepareWithdrawExchangeResponse;
};

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

/**
 * Update an exchange entry.
 */
export type UpdateExchangeEntryOp = {
  op: WalletApiOperation.UpdateExchangeEntry;
  request: UpdateExchangeEntryRequest;
  response: EmptyObject;
};

export type ListBankAccountsOp = {
  op: WalletApiOperation.ListBankAccounts;
  request: ListBankAccountsRequest;
  response: ListBankAccountsResponse;
};

export type GetBankAccountByIdOp = {
  op: WalletApiOperation.GetBankAccountById;
  request: GetBankAccountByIdRequest;
  response: GetBankAccountByIdResponse;
};

export type AddBankAccountsOp = {
  op: WalletApiOperation.AddBankAccount;
  request: AddBankAccountRequest;
  response: AddBankAccountResponse;
};

export type ForgetBankAccountsOp = {
  op: WalletApiOperation.ForgetBankAccount;
  request: ForgetBankAccountRequest;
  response: EmptyObject;
};

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

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

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

export type GetDepositWireTypesOp = {
  op: WalletApiOperation.GetDepositWireTypes;
  request: GetDepositWireTypesRequest;
  response: GetDepositWireTypesResponse;
};

/**
 * Get wire types that can be used for a deposit operation
 * with the provided currency.
 *
 * @deprecated Use getDepositWireTypes instead
 */
export type GetDepositWireTypesForCurrencyOp = {
  op: WalletApiOperation.GetDepositWireTypesForCurrency;
  request: GetDepositWireTypesForCurrencyRequest;
  response: GetDepositWireTypesForCurrencyResponse;
};

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

/**
 * Get the current terms of a service of an exchange.
 */
export type GetExchangeEntryByUrlOp = {
  op: WalletApiOperation.GetExchangeEntryByUrl;
  request: GetExchangeEntryByUrlRequest;
  response: GetExchangeEntryByUrlResponse;
};

/**
 * Get resources associated with an exchange.
 */
export type GetExchangeResourcesOp = {
  op: WalletApiOperation.GetExchangeResources;
  request: GetExchangeResourcesRequest;
  response: GetExchangeResourcesResponse;
};

/**
 * Get resources associated with an exchange.
 */
export type DeleteExchangeOp = {
  op: WalletApiOperation.GetExchangeResources;
  request: DeleteExchangeRequest;
  response: EmptyObject;
};

export type GetCurrencySpecificationOp = {
  op: WalletApiOperation.GetCurrencySpecification;
  request: GetCurrencySpecificationRequest;
  response: GetCurrencySpecificationResponse;
};

// group: Deposits

/**
 * 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;
};

/**
 * 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;
};

export type CheckDepositOp = {
  op: WalletApiOperation.CheckDeposit;
  request: CheckDepositRequest;
  response: CheckDepositResponse;
};

// group: Backups

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

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

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

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

/**
 * Export the database to a file.
 *
 * The target directory must already exist.
 */
export type ExportDbToFileOp = {
  op: WalletApiOperation.ExportDbToFile;
  request: ExportDbToFileRequest;
  response: ExportDbToFileResponse;
};

/**
 * Export the database from a file.
 *
 * CAUTION: Overrides existing data.
 */
export type ImportDbFromFileOp = {
  op: WalletApiOperation.ImportDbFromFile;
  request: ImportDbFromFileRequest;
  response: EmptyObject;
};

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

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

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

/**
 * 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;
};

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

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

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

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

// group: Peer Payments

/**
 * 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: CheckPeerPushDebitOkResponse;
};

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

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

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

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

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

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

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

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

// group: Data Validation and Conversion

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

export type CanonicalizeBaseUrlOp = {
  op: WalletApiOperation.CanonicalizeBaseUrl;
  request: CanonicalizeBaseUrlRequest;
  response: CanonicalizeBaseUrlResponse;
};

export type GetQrCodesForPaytoOp = {
  op: WalletApiOperation.GetQrCodesForPayto;
  request: GetQrCodesForPaytoRequest;
  response: GetQrCodesForPaytoResponse;
};

export type ConvertIbanAccountFieldToPaytoOp = {
  op: WalletApiOperation.ConvertIbanAccountFieldToPayto;
  request: ConvertIbanAccountFieldToPaytoRequest;
  response: ConvertIbanAccountFieldToPaytoResponse;
};

export type ConvertIbanPaytoToAccountFieldOp = {
  op: WalletApiOperation.ConvertIbanPaytoToAccountField;
  request: ConvertIbanPaytoToAccountFieldRequest;
  response: ConvertIbanPaytoToAccountFieldResponse;
};

export type GetBankingChoicesForPaytoOp = {
  op: WalletApiOperation.GetBankingChoicesForPayto;
  request: GetBankingChoicesForPaytoRequest;
  response: GetBankingChoicesForPaytoResponse;
};

// group: Database Management

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

export type ImportDbOp = {
  op: WalletApiOperation.ImportDb;
  request: ImportDbRequest;
  response: EmptyObject;
};

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

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

// group: Testing and Debugging

/**
 * 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;
};

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

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

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

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

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

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

/**
 * Get wallet-internal pending tasks.
 */
export type GetUserAttentionRequests = {
  op: WalletApiOperation.GetUserAttentionRequests;
  request: UserAttentionsRequest;
  response: UserAttentionsResponse;
};

/**
 * Get wallet-internal pending tasks.
 */
export type MarkAttentionRequestAsRead = {
  op: WalletApiOperation.MarkAttentionRequestAsRead;
  request: UserAttentionByIdRequest;
  response: EmptyObject;
};

/**
 * Get wallet-internal pending tasks.
 */
export type GetUserAttentionsUnreadCount = {
  op: WalletApiOperation.GetUserAttentionUnreadCount;
  request: UserAttentionsRequest;
  response: UserAttentionsCountResponse;
};

export type GetActiveTasksOp = {
  op: WalletApiOperation.GetActiveTasks;
  request: EmptyObject;
  response: GetActiveTasksResponse;
};

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

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

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

/**
 * Wait until all transactions are in a final state.
 */
export type TestingWaitTransactionsFinalOp = {
  op: WalletApiOperation.TestingWaitTransactionsFinal;
  request: EmptyObject;
  response: EmptyObject;
};

/**
 * Wait until all transactions are in a final state.
 */
export type TestingWaitTasksDoneOp = {
  op: WalletApiOperation.TestingWaitTasksDone;
  request: EmptyObject;
  response: EmptyObject;
};

/**
 * Wait until all refresh transactions are in a final state.
 */
export type TestingWaitRefreshesFinalOp = {
  op: WalletApiOperation.TestingWaitRefreshesFinal;
  request: EmptyObject;
  response: EmptyObject;
};

/**
 * Wait until a transaction is in a particular state.
 */
export type TestingWaitTransactionStateOp = {
  op: WalletApiOperation.TestingWaitTransactionState;
  request: TestingWaitTransactionRequest;
  response: EmptyObject;
};

/**
 * Wait until an exchange entry is in a particular state.
 */
export type TestingWaitExchangeStateOp = {
  op: WalletApiOperation.TestingWaitTransactionState;
  request: TestingWaitExchangeStateRequest;
  response: EmptyObject;
};

export type TestingPingOp = {
  op: WalletApiOperation.TestingPing;
  request: EmptyObject;
  response: EmptyObject;
};

export type TestingGetReserveHistoryOp = {
  op: WalletApiOperation.TestingGetReserveHistory;
  request: TestingGetReserveHistoryRequest;
  response: any;
};

/**
 * Reset all task/transaction retries,
 * resulting in immediate re-try of all operations.
 */
export type TestingResetAllRetriesOp = {
  op: WalletApiOperation.TestingResetAllRetries;
  request: EmptyObject;
  response: EmptyObject;
};

/**
 * Get stats about an exchange denomination.
 */
export type TestingGetDenomStatsOp = {
  op: WalletApiOperation.TestingGetDenomStats;
  request: TestingGetDenomStatsRequest;
  response: TestingGetDenomStatsResponse;
};

export type TestingRunFixupOp = {
  op: WalletApiOperation.TestingRunFixup;
  request: RunFixupRequest;
  response: EmptyObject;
};

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

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

export type WalletOperations = {
  [WalletApiOperation.InitWallet]: InitWalletOp;
  [WalletApiOperation.SetWalletRunConfig]: SetWalletRunConfigOp;
  [WalletApiOperation.GetVersion]: GetVersionOp;
  [WalletApiOperation.PreparePayForUri]: PreparePayForUriOp;
  [WalletApiOperation.SharePayment]: SharePaymentOp;
  [WalletApiOperation.CheckPayForTemplate]: CheckPayForTemplateOp;
  [WalletApiOperation.PreparePayForTemplate]: PreparePayForTemplateOp;
  [WalletApiOperation.WithdrawTestkudos]: WithdrawTestkudosOp;
  [WalletApiOperation.GetChoicesForPayment]: GetChoicesForPaymentOp;
  [WalletApiOperation.ConfirmPay]: ConfirmPayOp;
  [WalletApiOperation.AbortTransaction]: AbortTransactionOp;
  [WalletApiOperation.FailTransaction]: FailTransactionOp;
  [WalletApiOperation.SuspendTransaction]: SuspendTransactionOp;
  [WalletApiOperation.ResumeTransaction]: ResumeTransactionOp;
  [WalletApiOperation.GetBalances]: GetBalancesOp;
  [WalletApiOperation.ConvertDepositAmount]: ConvertDepositAmountOp;
  [WalletApiOperation.GetMaxDepositAmount]: GetMaxDepositAmountOp;
  [WalletApiOperation.GetMaxPeerPushDebitAmount]: GetMaxPeerPushDebitAmountOp;
  [WalletApiOperation.GetBalanceDetail]: GetBalancesDetailOp;
  [WalletApiOperation.GetTransactions]: GetTransactionsOp;
  [WalletApiOperation.GetTransactionsV2]: GetTransactionsV2Op;
  [WalletApiOperation.TestingGetSampleTransactions]: TestingGetSampleTransactionsOp;
  [WalletApiOperation.GetTransactionById]: GetTransactionByIdOp;
  [WalletApiOperation.RetryPendingNow]: RetryPendingNowOp;
  [WalletApiOperation.GetActiveTasks]: GetActiveTasksOp;
  [WalletApiOperation.GetUserAttentionRequests]: GetUserAttentionRequests;
  [WalletApiOperation.GetUserAttentionUnreadCount]: GetUserAttentionsUnreadCount;
  [WalletApiOperation.MarkAttentionRequestAsRead]: MarkAttentionRequestAsRead;
  [WalletApiOperation.DumpCoins]: DumpCoinsOp;
  [WalletApiOperation.SetCoinSuspended]: SetCoinSuspendedOp;
  [WalletApiOperation.ForceRefresh]: ForceRefreshOp;
  [WalletApiOperation.DeleteTransaction]: DeleteTransactionOp;
  [WalletApiOperation.RetryTransaction]: RetryTransactionOp;
  [WalletApiOperation.StartRefundQueryForUri]: StartRefundQueryForUriOp;
  [WalletApiOperation.StartRefundQuery]: StartRefundQueryOp;
  [WalletApiOperation.GetWithdrawalDetailsForAmount]: GetWithdrawalDetailsForAmountOp;
  [WalletApiOperation.GetWithdrawalDetailsForUri]: GetWithdrawalDetailsForUriOp;
  [WalletApiOperation.AcceptBankIntegratedWithdrawal]: AcceptBankIntegratedWithdrawalOp;
  [WalletApiOperation.AcceptManualWithdrawal]: AcceptManualWithdrawalOp;
  [WalletApiOperation.ListExchanges]: ListExchangesOp;
  [WalletApiOperation.AddExchange]: AddExchangeOp;
  [WalletApiOperation.ListBankAccounts]: ListBankAccountsOp;
  [WalletApiOperation.AddBankAccount]: AddBankAccountsOp;
  [WalletApiOperation.ForgetBankAccount]: ForgetBankAccountsOp;
  [WalletApiOperation.GetBankAccountById]: GetBankAccountByIdOp;
  [WalletApiOperation.SetExchangeTosAccepted]: SetExchangeTosAcceptedOp;
  [WalletApiOperation.SetExchangeTosForgotten]: SetExchangeTosForgottenOp;
  [WalletApiOperation.GetExchangeTos]: GetExchangeTosOp;
  [WalletApiOperation.GetExchangeDetailedInfo]: GetExchangeDetailedInfoOp;
  [WalletApiOperation.GetExchangeEntryByUrl]: GetExchangeEntryByUrlOp;
  [WalletApiOperation.CheckDeposit]: CheckDepositOp;
  [WalletApiOperation.GenerateDepositGroupTxId]: GenerateDepositGroupTxIdOp;
  [WalletApiOperation.CreateDepositGroup]: CreateDepositGroupOp;
  [WalletApiOperation.SetWalletDeviceId]: SetWalletDeviceIdOp;
  [WalletApiOperation.ExportBackupRecovery]: ExportBackupRecoveryOp;
  [WalletApiOperation.ImportBackupRecovery]: ImportBackupRecoveryOp;
  [WalletApiOperation.RunBackupCycle]: RunBackupCycleOp;
  [WalletApiOperation.ExportBackup]: ExportBackupOp;
  [WalletApiOperation.ExportDbToFile]: ExportDbToFileOp;
  [WalletApiOperation.ImportDbFromFile]: ImportDbFromFileOp;
  [WalletApiOperation.AddBackupProvider]: AddBackupProviderOp;
  [WalletApiOperation.RemoveBackupProvider]: RemoveBackupProviderOp;
  [WalletApiOperation.GetBackupInfo]: GetBackupInfoOp;
  [WalletApiOperation.RunIntegrationTest]: RunIntegrationTestOp;
  [WalletApiOperation.RunIntegrationTestV2]: RunIntegrationTestV2Op;
  [WalletApiOperation.TestCrypto]: TestCryptoOp;
  [WalletApiOperation.WithdrawTestBalance]: WithdrawTestBalanceOp;
  [WalletApiOperation.TestPay]: TestPayOp;
  [WalletApiOperation.ExportDb]: ExportDbOp;
  [WalletApiOperation.ImportDb]: ImportDbOp;
  [WalletApiOperation.CheckPeerPushDebit]: CheckPeerPushDebitOp;
  [WalletApiOperation.CheckPeerPushDebitV2]: CheckPeerPushDebitV2Op;
  [WalletApiOperation.InitiatePeerPushDebit]: InitiatePeerPushDebitOp;
  [WalletApiOperation.PreparePeerPushCredit]: PreparePeerPushCreditOp;
  [WalletApiOperation.ConfirmPeerPushCredit]: ConfirmPeerPushCreditOp;
  [WalletApiOperation.CheckPeerPullCredit]: CheckPeerPullCreditOp;
  [WalletApiOperation.InitiatePeerPullCredit]: InitiatePeerPullCreditOp;
  [WalletApiOperation.PreparePeerPullDebit]: PreparePeerPullDebitOp;
  [WalletApiOperation.ConfirmPeerPullDebit]: ConfirmPeerPullDebitOp;
  [WalletApiOperation.ClearDb]: ClearDbOp;
  [WalletApiOperation.Recycle]: RecycleOp;
  [WalletApiOperation.ApplyDevExperiment]: ApplyDevExperimentOp;
  [WalletApiOperation.ValidateIban]: ValidateIbanOp;
  [WalletApiOperation.TestingWaitTransactionsFinal]: TestingWaitTransactionsFinalOp;
  [WalletApiOperation.TestingWaitRefreshesFinal]: TestingWaitRefreshesFinalOp;
  [WalletApiOperation.TestingSetTimetravel]: TestingSetTimetravelOp;
  [WalletApiOperation.TestingGetDbStats]: TestingGetDbStats;
  [WalletApiOperation.TestingWaitTransactionState]: TestingWaitTransactionStateOp;
  [WalletApiOperation.TestingWaitExchangeState]: TestingWaitExchangeStateOp;
  [WalletApiOperation.TestingWaitTasksDone]: TestingWaitTasksDoneOp;
  [WalletApiOperation.GetCurrencySpecification]: GetCurrencySpecificationOp;
  [WalletApiOperation.CreateStoredBackup]: CreateStoredBackupsOp;
  [WalletApiOperation.ListStoredBackups]: ListStoredBackupsOp;
  [WalletApiOperation.DeleteStoredBackup]: DeleteStoredBackupOp;
  [WalletApiOperation.RecoverStoredBackup]: RecoverStoredBackupsOp;
  [WalletApiOperation.UpdateExchangeEntry]: UpdateExchangeEntryOp;
  [WalletApiOperation.PrepareWithdrawExchange]: PrepareWithdrawExchangeOp;
  [WalletApiOperation.DeleteExchange]: DeleteExchangeOp;
  [WalletApiOperation.GetExchangeResources]: GetExchangeResourcesOp;
  [WalletApiOperation.ListGlobalCurrencyAuditors]: ListGlobalCurrencyAuditorsOp;
  [WalletApiOperation.ListGlobalCurrencyExchanges]: ListGlobalCurrencyExchangesOp;
  [WalletApiOperation.AddGlobalCurrencyAuditor]: AddGlobalCurrencyAuditorOp;
  [WalletApiOperation.RemoveGlobalCurrencyAuditor]: RemoveGlobalCurrencyAuditorOp;
  [WalletApiOperation.AddGlobalCurrencyExchange]: AddGlobalCurrencyExchangeOp;
  [WalletApiOperation.RemoveGlobalCurrencyExchange]: RemoveGlobalCurrencyExchangeOp;
  [WalletApiOperation.ListAssociatedRefreshes]: ListAssociatedRefreshesOp;
  [WalletApiOperation.TestingGetDenomStats]: TestingGetDenomStatsOp;
  [WalletApiOperation.TestingRunFixup]: TestingRunFixupOp;
  [WalletApiOperation.TestingPing]: TestingPingOp;
  [WalletApiOperation.Shutdown]: ShutdownOp;
  [WalletApiOperation.PrepareBankIntegratedWithdrawal]: PrepareBankIntegratedWithdrawalOp;
  [WalletApiOperation.ConfirmWithdrawal]: ConfirmWithdrawalOp;
  [WalletApiOperation.CanonicalizeBaseUrl]: CanonicalizeBaseUrlOp;
  [WalletApiOperation.TestingGetReserveHistory]: TestingGetReserveHistoryOp;
  [WalletApiOperation.TestingResetAllRetries]: TestingResetAllRetriesOp;
  [WalletApiOperation.HintNetworkAvailability]: HintNetworkAvailabilityOp;
  [WalletApiOperation.GetDepositWireTypes]: GetDepositWireTypesOp;
  [WalletApiOperation.GetDepositWireTypesForCurrency]: GetDepositWireTypesForCurrencyOp;
  [WalletApiOperation.GetQrCodesForPayto]: GetQrCodesForPaytoOp;
  [WalletApiOperation.GetBankingChoicesForPayto]: GetBankingChoicesForPaytoOp;
  [WalletApiOperation.ListDiscounts]: ListDiscountsOp;
  [WalletApiOperation.DeleteDiscount]: DeleteDiscountOp;
  [WalletApiOperation.ListSubscriptions]: ListSubscriptionsOp;
  [WalletApiOperation.DeleteSubscription]: DeleteSubscriptionOp;
  [WalletApiOperation.StartExchangeWalletKyc]: StartExchangeWalletKycOp;
  [WalletApiOperation.TestingWaitExchangeWalletKyc]: TestingWaitExchangeWalletKycOp;
  [WalletApiOperation.TestingPlanMigrateExchangeBaseUrl]: TestingPlanMigrateExchangeBaseUrlOp;
  [WalletApiOperation.HintApplicationResumed]: HintApplicationResumedOp;
  [WalletApiOperation.CompleteExchangeBaseUrl]: CompleteExchangeBaseUrlOp;
  [WalletApiOperation.SetDonau]: SetDonauOp;
  [WalletApiOperation.GetDonau]: GetDonauOp;
  [WalletApiOperation.GetDonauStatements]: GetDonauStatementsOp;
  [WalletApiOperation.AddContact]: AddContactOp;
  [WalletApiOperation.DeleteContact]: DeleteContactOp;
  [WalletApiOperation.GetContacts]: GetContactsOp;
  [WalletApiOperation.GetMailboxMessages]: GetMailboxMessagesOp;
  [WalletApiOperation.DeleteMailboxMessage]: DeleteMailboxMessageOp;
  [WalletApiOperation.AddMailboxMessage]: AddMailboxMessageOp;
  [WalletApiOperation.GetMailbox]: GetMailboxOp;
  [WalletApiOperation.InitializeMailbox]: InitializeMailboxOp;
  [WalletApiOperation.RefreshMailbox]: RefreshMailboxOp;
  [WalletApiOperation.SendTalerUriMailboxMessage]: SendTalerUriMailboxMessageOp;
  [WalletApiOperation.ConvertIbanAccountFieldToPayto]: ConvertIbanAccountFieldToPaytoOp;
  [WalletApiOperation.ConvertIbanPaytoToAccountField]: ConvertIbanPaytoToAccountFieldOp;
};

export type WalletCoreRequestType<
  Op extends WalletApiOperation & keyof WalletOperations,
> = WalletOperations[Op] extends { request: infer T } ? T : never;

export type WalletCoreResponseType<
  Op extends WalletApiOperation & keyof WalletOperations,
> = WalletOperations[Op] extends { response: infer T } ? T : never;

export type WalletCoreOpKeys = WalletApiOperation & keyof WalletOperations;

export interface WalletCoreApiClient {
  call<Op extends keyof WalletOperations>(
    operation: Op,
    payload: WalletCoreRequestType<Op>,
  ): Promise<WalletCoreResponseType<Op>>;
}
