// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
// AUTO-GENERATED FROM spec.wit — DO NOT EDIT

use async_trait::async_trait;

use super::types::*;
use crate::{
    error::Result,
    rpc::no_wasm::{NoWasmSend, NoWasmSync},
};

/// RpcClient interface — generated from spec.wit.
///
/// Every method here corresponds to a function in the `rpc-client` interface.
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
pub trait RpcClient: NoWasmSend + NoWasmSync {
    /// Gets the balance of an account in kelvins.
    ///
    /// # Parameters
    ///
    /// * `pubkey` - The public key (address) of the account to query.
    ///
    /// # Returns
    ///
    /// The account balance in the smallest denomination of the native token (kelvins).
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the account does not exist.
    async fn get_balance(&self, pubkey: &PublicKey) -> Result<Kelvin>;

    /// Gets detailed information about an on-chain account.
    ///
    /// # Parameters
    ///
    /// * `pubkey` - The public key (address) of the account to query.
    ///
    /// # Returns
    ///
    /// Detailed account information including balance, owner, data, and executable flag.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the account does not exist.
    async fn get_account_info(&self, pubkey: &PublicKey) -> Result<AccountInfo>;

    /// Gets the current finalized block height from the blockchain.
    ///
    /// The block height represents the number of blocks produced since genesis.
    /// Always returns the finalized block height for consistency.
    ///
    /// # Returns
    ///
    /// The current finalized block height.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_block_height(&self) -> Result<u64>;

    /// Gets the current finalized block height with advanced configuration.
    ///
    /// Provides access to advanced parameters for block height retrieval,
    /// specifically minimum context slot requirements.
    ///
    /// # Parameters
    ///
    /// * `min-context-slot` - The minimum context slot that the server must have
    /// reached before responding. If absent, no minimum is required.
    ///
    /// # Returns
    ///
    /// The current finalized block height.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_block_height_with_config(&self, min_context_slot: Option<u64>) -> Result<u64>;

    /// Gets detailed information about a transaction by its signature.
    ///
    /// # Parameters
    ///
    /// * `sig` - The transaction signature to look up.
    ///
    /// # Returns
    ///
    /// Full transaction details including block height, block hash, timestamp,
    /// execution metadata (fee, errors), and the transaction content.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the transaction is not found.
    async fn get_transaction(&self, sig: &Signature) -> Result<TransactionResponse>;

    /// Gets the total number of transactions processed since genesis.
    ///
    /// # Returns
    ///
    /// The total transaction count.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_transaction_count(&self) -> Result<u64>;

    /// Calculates the minimum balance required for rent exemption.
    ///
    /// Accounts with at least this balance are exempt from paying rent.
    ///
    /// # Parameters
    ///
    /// * `data-size` - The size of the account data in bytes.
    ///
    /// # Returns
    ///
    /// The minimum balance (in kelvins) required for rent exemption.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_minimum_balance_for_rent_exemption(&self, data_size: u64) -> Result<u64>;

    /// Gets the status of multiple transaction signatures.
    ///
    /// # Parameters
    ///
    /// * `signatures` - A list of transaction signatures to query.
    ///
    /// # Returns
    ///
    /// A list of signature statuses (slot, executed, error) corresponding
    /// to the input signatures.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_signature_statuses(
        &self,
        signatures: &[Signature],
    ) -> Result<Vec<Option<SignatureStatus>>>;

    /// Gets signatures associated with an address, with optional pagination.
    ///
    /// # Parameters
    ///
    /// * `address` - The address to query signatures for.
    /// * `config` - Optional configuration for pagination (limit, before, until).
    ///
    /// # Returns
    ///
    /// A list of signature info records for the given address.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_signatures_for_address(
        &self,
        address: &PublicKey,
        config: Option<GetSignaturesForAddressConfig>,
    ) -> Result<Vec<SignatureInfo>>;

    /// Gets current epoch information.
    ///
    /// # Returns
    ///
    /// Epoch information including epoch number, slot indices, block height,
    /// and transaction count.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_epoch_info(&self) -> Result<EpochInfo>;

    /// Gets the fee for a given serialized message.
    ///
    /// # Parameters
    ///
    /// * `message` - The base64-encoded serialized message to calculate fees for.
    ///
    /// # Returns
    ///
    /// A fee response containing the fee in kelvins, or absent if the message
    /// is invalid.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_fee_for_message(&self, message: &str) -> Result<FeeResponse>;

    /// Gets information for multiple accounts in a single request.
    ///
    /// # Parameters
    ///
    /// * `pubkeys` - A list of public keys to query.
    ///
    /// # Returns
    ///
    /// A list of optional account info records. Each entry is absent if that
    /// account does not exist.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_multiple_accounts(
        &self,
        pubkeys: &[PublicKey],
    ) -> Result<Vec<OptionalAccountInfo>>;

    /// Gets accounts owned by a given program or address.
    ///
    /// Returns all accounts whose owner matches the specified public key,
    /// along with optional pagination metadata.
    ///
    /// # Parameters
    ///
    /// * `owner` - The public key of the owner/program to query accounts for.
    /// * `filter` - Optional filter to specify account type (program accounts
    /// or token accounts). Defaults to program-accounts if absent.
    /// * `config` - Optional pagination configuration (limit, after cursor).
    ///
    /// # Returns
    ///
    /// A tuple of (accounts list, optional pagination info).
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_accounts_by_owner(
        &self,
        owner: &PublicKey,
        filter: Option<AccountFilter>,
        config: Option<GetAccountsByOwnerConfig>,
    ) -> Result<(Vec<OwnerAccount>, Option<PaginationInfo>)>;

    /// Gets a subscription by subscriber public key and nonce.
    ///
    /// # Parameters
    ///
    /// * `subscriber` - The public key of the subscriber.
    /// * `nonce` - The nonce identifying the specific subscription.
    ///
    /// # Returns
    ///
    /// The subscription record (kind, topic, subscriber, event-account).
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the subscription is not found.
    async fn get_subscription(&self, subscriber: &PublicKey, nonce: &str) -> Result<Subscription>;

    /// Gets transactions triggered by a subscription.
    ///
    /// Returns transactions that were automatically triggered in response to
    /// subscription matches or other programmatic conditions.
    ///
    /// # Parameters
    ///
    /// * `subscription-account` - The public key of the subscription account.
    /// * `limit` - Optional maximum number of transactions to return.
    ///
    /// # Returns
    ///
    /// A list of triggered transaction records (signature, block number).
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_triggered_transactions(
        &self,
        subscription_account: &PublicKey,
        limit: Option<u32>,
    ) -> Result<Vec<TriggeredTransaction>>;

    /// Gets the workflow lineage tree for a transaction.
    ///
    /// Traverses the chain of workflow-triggered transactions starting from
    /// a root transaction, building a tree of parent-child relationships.
    ///
    /// # Parameters
    ///
    /// * `request` - The lineage request including root signature, max depth,
    /// and whether to include event details.
    ///
    /// # Returns
    ///
    /// The workflow lineage response with nodes, leaves, and truncation info.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the root transaction is not found.
    async fn get_workflow_lineage(
        &self,
        request: &GetWorkflowLineageRequest,
    ) -> Result<GetWorkflowLineageResponse>;

    /// Gets paginated transactions from the blockchain.
    ///
    /// Returns a list of transactions, optionally filtered and paginated.
    /// Useful for transaction monitoring, analytics, and debugging.
    ///
    /// # Parameters
    ///
    /// * `config` - Optional configuration for pagination (limit, before cursor).
    /// If absent, defaults apply (limit: 100).
    ///
    /// # Returns
    ///
    /// A list of transaction info records with signatures, slots, block times,
    /// and error status.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_transactions(
        &self,
        config: Option<GetTransactionsConfig>,
    ) -> Result<Vec<TransactionInfo>>;

    /// Checks if a blockhash is still valid for transaction submission.
    ///
    /// # Parameters
    ///
    /// * `blockhash` - The blockhash to validate.
    ///
    /// # Returns
    ///
    /// `true` if the blockhash is still valid, `false` otherwise.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn is_blockhash_valid(&self, blockhash: &Hash) -> Result<IsBlockhashValidResponse>;

    /// Gets the health status of the RPC node.
    ///
    /// # Returns
    ///
    /// A health status string, typically "ok" when the node is healthy.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the node is unhealthy.
    async fn get_health(&self) -> Result<String>;

    /// Gets the health status of the validator.
    ///
    /// # Returns
    ///
    /// The validator health status record.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_validator_health(&self) -> Result<ValidatorHealth>;

    /// Gets the list of full nodes connected to the validator or full node.
    ///
    /// # Returns
    ///
    /// A list of connected nodes, each identified by a network public key
    /// and connection duration in milliseconds.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_connected_full_nodes(&self) -> Result<Vec<ConnectedNode>>;

    /// Gets the TEE's secret sharing public key for HPKE encryption.
    ///
    /// This public key is used to encrypt secrets that only the TEE cluster
    /// can decrypt.
    ///
    /// # Returns
    ///
    /// The X25519 public key (hex-encoded) used for HPKE encryption.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails, the TEE Registry state account
    /// doesn't exist, or the secret sharing public key has not been registered.
    async fn get_secret_sharing_pubkey(&self) -> Result<SecretSharingPubkey>;

    /// Gets the config hash prefix for protecting against replay attacks.
    ///
    /// Retrieves the first 64 bits of the config hash, which is used for
    /// transaction replay protection across chains.
    ///
    /// # Returns
    ///
    /// The config hash prefix as a u64 value.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_config_hash_prefix(&self) -> Result<ConfigHashPrefix>;

    /// Gets all accounts in the system.
    ///
    /// **Warning:** This can be very expensive on large networks. Intended
    /// primarily for testing and debugging on local/devnet.
    ///
    /// # Parameters
    ///
    /// * `config` - Optional configuration for encoding and data inclusion.
    ///
    /// # Returns
    ///
    /// A list of all account entries (pubkey + account info).
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_all_accounts(
        &self,
        config: Option<GetAllAccountsConfig>,
    ) -> Result<Vec<AllAccountsEntry>>;

    /// Gets a block by its height.
    ///
    /// # Parameters
    ///
    /// * `block-height` - The block height to query.
    /// * `config` - Optional configuration for transaction detail level
    /// ("full", "signatures", or "none"). Defaults to "full".
    ///
    /// # Returns
    ///
    /// Block information including blockhash, timestamp, and transactions
    /// (detail level depends on config).
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the block is not found.
    async fn get_block(
        &self,
        block_height: u64,
        config: Option<GetBlockConfig>,
    ) -> Result<BlockInfo>;

    /// Gets a list of confirmed block heights in a range (inclusive).
    ///
    /// # Parameters
    ///
    /// * `start-height` - The start of the block height range.
    /// * `end-height` - The end of the range. If absent, returns up to the
    /// latest confirmed block.
    ///
    /// # Returns
    ///
    /// A list of confirmed block height numbers.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_blocks(&self, start_height: u64, end_height: Option<u64>) -> Result<Vec<u64>>;

    /// Gets detailed information about a stake account.
    ///
    /// # Parameters
    ///
    /// * `pubkey` - The public key of the stake account.
    ///
    /// # Returns
    ///
    /// The stake account info (state, balances, authorities), or absent if
    /// the account is not a valid stake account.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_stake_account(&self, pubkey: &PublicKey) -> Result<Option<StakeAccountInfo>>;

    /// Gets all registered validator accounts.
    ///
    /// # Parameters
    ///
    /// * `request` - Request parameters specifying whether to use the frozen
    /// (last epoch) or pending (current) snapshot.
    ///
    /// # Returns
    ///
    /// A list of validator account info records.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_validator_accounts(
        &self,
        request: &GetValidatorAccountsRequest,
    ) -> Result<Vec<ValidatorAccountInfo>>;

    /// Gets the token balance of an SPL Token account.
    ///
    /// # Parameters
    ///
    /// * `pubkey` - The public key of the SPL Token account.
    ///
    /// # Returns
    ///
    /// Token balance information including raw amount, decimals, and
    /// human-readable amount string.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the account is not a valid
    /// token account.
    async fn get_token_account_balance(&self, pubkey: &PublicKey) -> Result<TokenBalance>;

    /// Gets registered REX requests for a creator.
    ///
    /// # Parameters
    ///
    /// * `creator` - The public key of the REX creator.
    /// * `nonce` - Optional nonce to filter for a specific REX request.
    /// If absent, returns all requests by the creator.
    ///
    /// # Returns
    ///
    /// A list of REX request records with their associated duties.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_rex_requests(
        &self,
        creator: &PublicKey,
        nonce: Option<String>,
    ) -> Result<Vec<RexInfoAndDuties>>;

    /// Gets missed REX duty proposal rounds for a specific REX request.
    ///
    /// # Parameters
    ///
    /// * `creator` - The public key of the REX creator.
    /// * `nonce` - The nonce identifying the specific REX request.
    ///
    /// # Returns
    ///
    /// A list of proposal round numbers where duties were missed.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_rex_missed_duties(&self, creator: &PublicKey, nonce: &str) -> Result<Vec<u64>>;

    /// Gets information about all known cluster nodes.
    ///
    /// # Returns
    ///
    /// A list of cluster node info records including stake, addresses,
    /// and public keys.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_cluster_nodes(&self) -> Result<Vec<ClusterNodeInfo>>;

    /// Gets the list of validator indices this node is connected to.
    ///
    /// # Returns
    ///
    /// A list of validator indices (u32).
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails.
    async fn get_connected_validators(&self) -> Result<Vec<u32>>;

    /// Submits a signed transaction to the network.
    ///
    /// # Parameters
    ///
    /// * `transaction` - The serialized, signed transaction as a byte array.
    /// * `options` - Optional send options (skip preflight, max retries).
    /// If absent, default options are used.
    ///
    /// # Returns
    ///
    /// The transaction signature, which can be used to check its status.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the transaction is rejected.
    async fn send_transaction(
        &self,
        transaction: &[u8],
        options: Option<SendTransactionOptions>,
    ) -> Result<Signature>;

    /// Requests an airdrop of tokens to the specified account.
    ///
    /// This method is typically only available on test networks (localnet, devnet).
    ///
    /// # Parameters
    ///
    /// * `pubkey` - The public key of the recipient account.
    /// * `amount` - The amount of kelvins to airdrop.
    ///
    /// # Returns
    ///
    /// The transaction signature of the airdrop transaction.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or airdrops are not supported.
    async fn request_airdrop(&self, pubkey: &PublicKey, amount: Kelvin) -> Result<Signature>;

    /// Polls until a transaction is confirmed or times out.
    ///
    /// This is a CDK compound method (not a single RPC call). It repeatedly
    /// calls getSignatureStatuses until the transaction is confirmed or the
    /// retry limit is reached.
    ///
    /// # Parameters
    ///
    /// * `sig` - The transaction signature (base58) to monitor.
    /// * `options` - Optional confirmation options (max retries, retry delay).
    /// Defaults: 30 retries, 1000ms delay.
    ///
    /// # Returns
    ///
    /// A confirmed transaction record with signature, executed status, and error.
    ///
    /// # Errors
    ///
    /// Returns an error if the transaction fails or confirmation times out.
    async fn confirm_transaction(
        &self,
        sig: &str,
        options: Option<ConfirmTransactionOptions>,
    ) -> Result<ConfirmedTransaction>;

    /// Sends a transaction and waits for confirmation.
    ///
    /// This is a CDK compound method that combines send-transaction and
    /// confirm-transaction into a single call.
    ///
    /// # Parameters
    ///
    /// * `transaction` - The serialized, signed transaction as a byte array.
    /// * `options` - Optional combined send-and-confirm options.
    ///
    /// # Returns
    ///
    /// A confirmed transaction record with signature, executed status, and error.
    ///
    /// # Errors
    ///
    /// Returns an error if sending fails, the transaction is rejected,
    /// or confirmation times out.
    async fn send_and_confirm_transaction(
        &self,
        transaction: &[u8],
        options: Option<SendAndConfirmOptions>,
    ) -> Result<ConfirmedTransaction>;

    /// Requests an airdrop and waits for confirmation.
    ///
    /// This is a CDK compound method that combines request-airdrop and
    /// confirm-transaction into a single call.
    ///
    /// # Parameters
    ///
    /// * `pubkey` - The public key of the recipient account.
    /// * `amount` - The amount of kelvins to airdrop.
    ///
    /// # Returns
    ///
    /// A confirmed transaction record for the airdrop.
    ///
    /// # Errors
    ///
    /// Returns an error if the airdrop fails or confirmation times out.
    async fn request_airdrop_and_confirm(
        &self,
        pubkey: &PublicKey,
        amount: Kelvin,
    ) -> Result<ConfirmedTransaction>;

    /// Submits an epoch change transaction (admin-only).
    ///
    /// This is a restricted admin method used for epoch management.
    /// Only available to authorized admin accounts.
    ///
    /// # Parameters
    ///
    /// * `request` - The epoch change request containing serialized data.
    ///
    /// # Returns
    ///
    /// A response indicating whether the submission was accepted.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the sender is not authorized.
    async fn send_admin_transaction(
        &self,
        request: &SubmitEpochChangeRequest,
    ) -> Result<SubmitEpochChangeResponse>;
}
