import { ApiPromise } from "@polkadot/api";
import { H256 } from "@polkadot/types/interfaces";
import { Network } from "bitcoinjs-lib";
import Big from "big.js";
import { Bitcoin, BitcoinUnit, Currency, ExchangeRate, MonetaryAmount } from "@interlay/monetary-js";
import { InterbtcPrimitivesVaultId } from "@polkadot/types/lookup";
import { VaultsAPI } from "./vaults";
import { ElectrsAPI } from "../external";
import { TransactionAPI } from "./transaction";
import { OracleAPI } from "./oracle";
import { CollateralCurrency, CollateralUnit, Redeem, WrappedCurrency } from "../types";
/**
 * @category BTC Bridge
 */
export interface RedeemAPI {
    /**
     * @returns An array containing the redeem requests
     */
    list(): Promise<Redeem[]>;
    /**
     * Send a redeem request transaction
     * @param amount Wrapped token amount to redeem
     * @param btcAddressEnc Bitcoin address where the redeemed BTC should be sent
     * @param vaultId (optional) ID of the vault to redeem with.
     * @param atomic (optional) Whether the request should be handled atomically or not. Only makes a difference
     * if more than one vault is needed to fulfil it. Defaults to false.
     * @param retries (optional) Number of times to retry redeeming, if some of the requests fail. Defaults to 0.
     * @param availableVaults (optional) A list of all vaults usable for redeem. If not provided, will fetch from the parachain.
     * @returns An array of type {redeemId, redeemRequest} if the requests succeeded. The function throws an error otherwise.
     */
    request(amount: MonetaryAmount<WrappedCurrency, BitcoinUnit>, btcAddressEnc: string, vaultId?: InterbtcPrimitivesVaultId, atomic?: boolean, retries?: number, availableVaults?: Map<InterbtcPrimitivesVaultId, MonetaryAmount<WrappedCurrency, BitcoinUnit>>): Promise<Redeem[]>;
    /**
     * Send a batch of aggregated redeem transactions (to one or more vaults)
     * @param amountsPerVault A mapping of vaults to redeem from, and wrapped token amounts to redeem using each vault
     * @param btcAddressEnc Bitcoin address where the redeemed BTC should be sent
     * @param atomic Whether the issue request should be handled atomically or not. Only makes a difference if more than
     * one vault is needed to fulfil it.
     * @returns An array of type {redeemId, vault} if the requests succeeded.
     * @throws Rejects the promise if none of the requests succeeded (or if at least one failed, when atomic=true).
     */
    requestAdvanced(amountsPerVault: Map<InterbtcPrimitivesVaultId, MonetaryAmount<WrappedCurrency, BitcoinUnit>>, btcAddressEnc: string, atomic: boolean): Promise<Redeem[]>;
    /**
     * Send a redeem execution transaction
     * @remarks If `txId` is not set, the `merkleProof` and `rawTx` must both be set.
     *
     * @param redeemId The ID generated by the redeem request transaction
     * @param btcTxId Bitcoin transaction ID
     */
    execute(requestId: string, btcTxId: string): Promise<void>;
    /**
     * Send a redeem cancellation transaction. After the redeem period has elapsed,
     * the redeemal request can be cancelled. As a result, the griefing collateral
     * of the vault will be slashed and sent to the redeemer
     * @param redeemId The ID returned by the redeem request transaction
     * @param reimburse (Optional) In case of redeem failure:
     *  - (Default) `false` = retry redeeming, with a different Vault
     *  - `true` = accept reimbursement in wrapped token
     */
    cancel(redeemId: string, reimburse?: boolean): Promise<void>;
    /**
     * @remarks Testnet utility function
     * @param blocks The time difference in number of blocks between a redeem request
     * is created and required completion time by a vault.
     * The redeem period has an upper limit to ensure the user gets their BTC in time
     * and to potentially punish a vault for inactivity or stealing BTC.
     */
    setRedeemPeriod(blocks: number): Promise<void>;
    /**
     *
     * @returns The time difference in number of blocks between a redeem request
     * is created and required completion time by a vault.
     * The redeem period has an upper limit to ensure the user gets their BTC in time
     * and to potentially punish a vault for inactivity or stealing BTC.
     */
    getRedeemPeriod(): Promise<number>;
    /**
     * @param redeemId The ID of the redeem request to fetch
     * @returns A redeem request object
     */
    getRequestById(redeemId: H256 | string): Promise<Redeem>;
    getRequestsByIds(redeemIds: (H256 | string)[]): Promise<Redeem[]>;
    /**
     * @returns The minimum amount of wrapped tokens that is accepted for redeem requests; any lower values would
     * risk the bitcoin client to reject the payment
     */
    getDustValue(): Promise<MonetaryAmount<WrappedCurrency, BitcoinUnit>>;
    /**
     * @returns The fee charged for redeeming. For instance, "0.005" stands for 0.5%
     */
    getFeeRate(): Promise<Big>;
    /**
     * @param amount The amount of wrapped tokens for which to compute the redeem fees
     * @returns The fees
     */
    getFeesToPay(amount: MonetaryAmount<WrappedCurrency, BitcoinUnit>): Promise<MonetaryAmount<WrappedCurrency, BitcoinUnit>>;
    /**
     * @returns If users execute a redeem with a Vault flagged for premium redeem,
     * they can earn a premium, slashed from the Vault's collateral.
     * This value is a percentage of the redeemed amount.
     */
    getPremiumRedeemFeeRate(): Promise<Big>;
    /**
     * Burn wrapped tokens for a premium
     * @param amount The amount of wrapped tokens to burn
     * @param collateralCurrency Liquidated collateral currency to use when burning wrapped tokens
     */
    burn(amount: MonetaryAmount<WrappedCurrency, BitcoinUnit>, collateralCurrency: CollateralCurrency): Promise<void>;
    /**
     * @param collateralCurrency Liquidated collateral currency to use when burning wrapped tokens
     * @returns The maximum amount of tokens that can be burned through a liquidation redeem
     */
    getMaxBurnableTokens(collateralCurrency: CollateralCurrency): Promise<MonetaryAmount<Currency<BitcoinUnit>, BitcoinUnit>>;
    /**
     * @param collateralCurrency Currency whose exchange rate with BTC to fetch
     * @returns The exchange rate (collateral currency to wrapped token currency)
     * used when burning tokens
     */
    getBurnExchangeRate<C extends CollateralUnit>(collateralCurrency: Currency<C>): Promise<ExchangeRate<Bitcoin, BitcoinUnit, typeof collateralCurrency, typeof collateralCurrency.units>>;
    /**
     * @returns The current inclusion fee based on the expected number of bytes
     * in the transaction, and the inclusion fee rate reported by the oracle
     */
    getCurrentInclusionFee(): Promise<MonetaryAmount<WrappedCurrency, BitcoinUnit>>;
}
export declare class DefaultRedeemAPI implements RedeemAPI {
    private api;
    private btcNetwork;
    private electrsAPI;
    private wrappedCurrency;
    private vaultsAPI;
    private oracleAPI;
    private transactionAPI;
    constructor(api: ApiPromise, btcNetwork: Network, electrsAPI: ElectrsAPI, wrappedCurrency: WrappedCurrency, vaultsAPI: VaultsAPI, oracleAPI: OracleAPI, transactionAPI: TransactionAPI);
    private getRedeemIdsFromEvents;
    request(amount: MonetaryAmount<WrappedCurrency, BitcoinUnit>, btcAddressEnc: string, vaultId?: InterbtcPrimitivesVaultId, atomic?: boolean, retries?: number, cachedVaults?: Map<InterbtcPrimitivesVaultId, MonetaryAmount<WrappedCurrency, BitcoinUnit>>): Promise<Redeem[]>;
    requestAdvanced(amountsPerVault: Map<InterbtcPrimitivesVaultId, MonetaryAmount<WrappedCurrency, BitcoinUnit>>, btcAddressEnc: string, atomic: boolean): Promise<Redeem[]>;
    execute(requestId: string, btcTxId: string): Promise<void>;
    cancel(requestId: string, reimburse?: boolean): Promise<void>;
    burn(amount: MonetaryAmount<WrappedCurrency, BitcoinUnit>, collateralCurrency: CollateralCurrency): Promise<void>;
    setRedeemPeriod(blocks: number): Promise<void>;
    getRedeemPeriod(): Promise<number>;
    getMaxBurnableTokens(collateralCurrency: CollateralCurrency): Promise<MonetaryAmount<Currency<BitcoinUnit>, BitcoinUnit>>;
    getBurnExchangeRate<C extends CollateralUnit>(collateralCurrency: Currency<C>): Promise<ExchangeRate<Bitcoin, BitcoinUnit, typeof collateralCurrency, typeof collateralCurrency.units>>;
    getCurrentInclusionFee(): Promise<MonetaryAmount<WrappedCurrency, BitcoinUnit>>;
    list(): Promise<Redeem[]>;
    getFeesToPay(amount: MonetaryAmount<WrappedCurrency, BitcoinUnit>): Promise<MonetaryAmount<WrappedCurrency, BitcoinUnit>>;
    getFeeRate(): Promise<Big>;
    getDustValue(): Promise<MonetaryAmount<WrappedCurrency, BitcoinUnit>>;
    getPremiumRedeemFeeRate(): Promise<Big>;
    getRequestById(redeemId: H256 | string): Promise<Redeem>;
    getRequestsByIds(redeemIds: (H256 | string)[]): Promise<Redeem[]>;
}
