import { Network } from '@caravan/bitcoin';

interface UTXO {
    txid: string;
    vout: number;
    value: number;
    status: {
        confirmed: boolean;
        block_time: number;
    };
}
interface Transaction {
    txid: string;
    vin: Input[];
    vout: Output[];
    size: number;
    weight: number;
    fee: number;
    isSend: boolean;
    amount: number;
    block_time: number;
}
interface Input {
    prevTxId: string;
    vout: number;
    sequence: number;
}
interface Output {
    scriptPubkeyHex: string;
    scriptPubkeyAddress: string;
    value: number;
}
interface FeeRatePercentile {
    avgHeight: number;
    timestamp: number;
    avgFee_0: number;
    avgFee_10: number;
    avgFee_25: number;
    avgFee_50: number;
    avgFee_75: number;
    avgFee_90: number;
    avgFee_100: number;
}
interface TransactionDetails {
    txid: string;
    version: number;
    locktime: number;
    vin: Array<{
        txid: string;
        vout: number;
        sequence: number;
    }>;
    vout: Array<{
        value: number;
        scriptPubkey: string;
        scriptPubkeyAddress?: string;
    }>;
    size: number;
    vsize?: number;
    weight: number;
    fee: number;
    status: {
        confirmed: boolean;
        blockHeight?: number;
        blockHash?: string;
        blockTime?: number;
    };
    isReceived?: boolean;
}
interface WalletTransactionDetails extends TransactionDetails {
    amount?: number;
    confirmations?: number;
    category?: string;
    address?: string;
    abandoned?: boolean;
    time?: number;
}
/**
 * Interface for RPC response structure
 */
interface RPCResponse<T = unknown> {
    result: T;
    error?: {
        code: number;
        message: string;
    };
    id: number;
}

declare function bitcoindImportDescriptors({ url, auth, walletName, receive, change, rescan, }: {
    url: string;
    auth: {
        username: string;
        password: string;
    };
    walletName?: string;
    receive: string;
    change: string;
    rescan: boolean;
}): Promise<RPCResponse<unknown>>;

declare enum ClientType {
    PRIVATE = "private",
    PUBLIC = "public",
    MEMPOOL = "mempool",
    BLOCKSTREAM = "blockstream"
}
declare enum PublicBitcoinProvider {
    BLOCKSTREAM = "blockstream",
    MEMPOOL = "mempool"
}
declare class ClientBase {
    private readonly throttled;
    readonly host: string;
    constructor(throttled: boolean, host: string);
    private throttle;
    private Request;
    Get(path: string): Promise<any>;
    Post(path: string, data?: any): Promise<any>;
}
interface BitcoindClientConfig {
    url: string;
    username: string;
    password: string;
    walletName?: string;
}
interface BitcoindParams {
    url: string;
    auth: {
        username: string;
        password: string;
    };
    walletName?: string;
}
interface BlockchainClientParams {
    type: ClientType;
    provider?: PublicBitcoinProvider;
    network?: Network;
    throttled?: boolean;
    client?: BitcoindClientConfig;
}
declare class BlockchainClient extends ClientBase {
    readonly type: ClientType;
    readonly provider?: PublicBitcoinProvider;
    readonly network?: Network;
    readonly bitcoindParams: BitcoindParams;
    constructor({ type, provider, network, throttled, client, }: BlockchainClientParams);
    getAddressUtxos(address: string): Promise<any>;
    getAddressTransactions(address: string): Promise<Transaction[]>;
    broadcastTransaction(rawTx: string): Promise<any>;
    formatUtxo(utxo: UTXO): Promise<any>;
    fetchAddressUtxos(address: string): Promise<any>;
    getAddressStatus(address: string): Promise<any>;
    getFeeEstimate(blocks?: number): Promise<any>;
    getBlockFeeRatePercentileHistory(): Promise<FeeRatePercentile[]>;
    getTransactionHex(txid: string): Promise<any>;
    /**
   * Retrieves transaction history for one or more addresses (public clients only)
   *
   * This method is designed for public blockchain explorers (Mempool/Blockstream) that
   * maintain address indexes, allowing efficient address-specific queries.
   *
   * Why this method is PUBLIC CLIENT ONLY:
   * - Public APIs maintain address indexes for efficient lookups
   * - Bitcoin Core doesn't support address-specific queries (see getWalletTransactionHistory)
   * - Allows querying multiple addresses with Promise.all for efficiency
   *
   * For PRIVATE clients: Use getWalletTransactionHistory() which returns all wallet transactions
   *
   * @param address - Single address or array of addresses to query
   * @param count - Number of transactions to return per address (1-100)
   * @param skip - Number of transactions to skip for pagination
   * @returns Combined array of transactions sorted by time (newest first)
   * @throws Error if called on private client
   *
   * @example
   * // Single address
   * const txs = await client.getAddressTransactionHistory("bc1q...");
   *
   * // Multiple addresses
   * const txs = await client.getAddressTransactionHistory(["bc1q...", "bc1p..."]);
   *
   * @see getWalletTransactionHistory - For private clients
   */
    getAddressTransactionHistory(address: string | string[], count?: number, skip?: number): Promise<TransactionDetails[]>;
    /**
     * Retrieves transaction history for a Bitcoin Core wallet (private client only)
     *
     * This method returns only "send" (spent) transactions from the wallet. This design
     * decision was made after extensive discussion about Bitcoin Core's limitations:
     *
     * 1. Bitcoin Core doesn't maintain an address index for performance/privacy reasons
     * 2. The `listtransactions` RPC returns ALL wallet transactions with no address filtering
     * 3. Filtering by address after fetching would be O(n*m) complexity for multiple addresses
     *
     * Why this method is PRIVATE CLIENT ONLY:
     * - Public APIs (Mempool/Blockstream) support direct address querying
     * - Bitcoin Core requires different approach due to lack of address indexing
     * - This inconsistency is intentional to optimize for each client type's capabilities
     *
     * Why only "send" transactions:
     * - Unspent "receive" transactions are already available via fetchAddressUtxos()
     * - Avoids duplication of data that's accessible through UTXO methods
     * - Focuses on spent transactions which are needed for transaction history
     * - Coordinator can combine this with UTXO data for complete history
     *
     * For PUBLIC clients: Use getAddressTransactionHistory() which supports address filtering
     *
     * @param count - Number of transactions to return (1-1000)
     * @param skip - Number of transactions to skip for pagination
     * @param includeWatchOnly - Include watch-only addresses in results
     * @returns Array of spent transactions from the wallet
     * @throws Error if called on public client or if wallet name is missing
     *
     * @example
     * // For private client - get last 100 spent transactions
     * const spentTxs = await client.getWalletTransactionHistory(100);
     *
     * // For public client - use getAddressTransactionHistory instead
     * const addressTxs = await client.getAddressTransactionHistory(address);
     *
     * @see getAddressTransactionHistory - For public clients
     * @see fetchAddressUtxos - For unspent transactions
     */
    getWalletTransactionHistory(count?: number, skip?: number, includeWatchOnly?: boolean): Promise<WalletTransactionDetails[]>;
    /**
     * Gets detailed information about a wallet transaction including fee information
     *
     * This method is specifically for transactions that are tracked by the wallet,
     * and provides fee information that isn't available in the general getTransaction
     * method. This is especially useful for private nodes where fee information is
     * critical for UI display.
     *
     * @see https://developer.bitcoin.org/reference/rpc/gettransaction.html
     *
     * @param txid - Transaction ID to retrieve
     * @returns Normalized transaction details with fee information
     */
    getWalletTransaction(txid: string): Promise<TransactionDetails>;
    getTransaction(txid: string, forceRawTx?: boolean): Promise<TransactionDetails>;
    importDescriptors({ receive, change, rescan, }: {
        receive: string;
        change: string;
        rescan: boolean;
    }): Promise<object>;
    getWalletInfo(): Promise<RPCResponse<unknown>>;
    /**
     * Retrieves the fee information for a pending (incoming) transaction .
     *
     * Standard methods like `getTransaction` do not provide fee details for transactions
     * where the user is the recipient. However, this information is required for
     * fee bumping strategies like CPFP (Child Pays For Parent).
     *
     * This method :
     * - For private nodes: Uses `getmempoolentry` to fetch fee data from the node's mempool
     * - For public APIs: Uses mempool.space transaction endpoint to get fee information
     * - Returns null if the transaction is not pending (not in mempool)
     *
     * @see https://developer.bitcoin.org/reference/rpc/getmempoolentry.html?highlight=getmempoolentry
     * @see https://mempool.space/docs/api/rest#get-transaction
     *
     * @param txid - Transaction ID to get fees
     * @returns Tx fees in satoshis, or null if transaction is not pending
     */
    getFeesForPendingTransaction(txid: string): Promise<string | null>;
}

export { BlockchainClient, ClientType, type FeeRatePercentile, PublicBitcoinProvider, type Transaction, type TransactionDetails, type UTXO, type WalletTransactionDetails, bitcoindImportDescriptors };
