UNPKG

@hyperbridge/sdk

Version:

The hyperclient SDK provides utilities for querying proofs and statuses for cross-chain requests from HyperBridge.

1,648 lines (1,640 loc) 63.2 kB
import { ConsolaInstance } from 'consola'; import { GraphQLClient } from 'graphql-request'; import { Hex, Log, PublicClient } from 'viem'; import { ApiPromise } from '@polkadot/api'; import { SignerOptions } from '@polkadot/api/types'; type HexString = `0x${string}`; interface IConfig { source: IEvmConfig | ISubstrateConfig; dest: IEvmConfig | ISubstrateConfig; hyperbridge: IHyperbridgeConfig; tracing?: boolean; } interface IEvmConfig { rpcUrl: string; stateMachineId: string; host: string; consensusStateId: string; } interface ISubstrateConfig { wsUrl: string; consensusStateId: string; hasher: "Keccak" | "Blake2"; stateMachineId: string; } interface IHyperbridgeConfig { wsUrl: string; stateMachineId: string; consensusStateId: string; } interface IPostRequest { source: string; dest: string; from: HexString; to: HexString; nonce: bigint; body: HexString; timeoutTimestamp: bigint; } interface IGetRequest { source: string; dest: string; from: HexString; nonce: bigint; height: bigint; keys: HexString[]; timeoutTimestamp: bigint; context: HexString; } interface GetResponseStorageValues { key: HexString; value: HexString; } interface IPostResponse { post: IPostRequest; response: string; timeoutTimestamp: bigint; } type IMessage = { Requests: HexString[]; } | { Responses: HexString[]; }; type IndexerQueryClient = GraphQLClient; interface ClientConfig { pollInterval: number; queryClient: IndexerQueryClient; tracing?: boolean; source: IEvmConfig | ISubstrateConfig; dest: IEvmConfig | ISubstrateConfig; hyperbridge: IHyperbridgeConfig; } interface RetryConfig { maxRetries: number; backoffMs: number; logMessage?: string; logger?: ConsolaInstance; } interface IsmpRequest { source: string; dest: string; from: string; to: string; nonce: bigint; body: string; timeoutTimestamp: bigint; storage_key?: string; } declare const RequestStatus: Readonly<{ SOURCE: "SOURCE"; SOURCE_FINALIZED: "SOURCE_FINALIZED"; HYPERBRIDGE_DELIVERED: "HYPERBRIDGE_DELIVERED"; HYPERBRIDGE_FINALIZED: "HYPERBRIDGE_FINALIZED"; DESTINATION: "DESTINATION"; TIMED_OUT: "TIMED_OUT"; HYPERBRIDGE_TIMED_OUT: "HYPERBRIDGE_TIMED_OUT"; }>; type RequestStatus = typeof RequestStatus; type RequestStatusKey = keyof typeof RequestStatus; declare const TimeoutStatus: Readonly<{ PENDING_TIMEOUT: "PENDING_TIMEOUT"; DESTINATION_FINALIZED_TIMEOUT: "DESTINATION_FINALIZED_TIMEOUT"; HYPERBRIDGE_TIMED_OUT: "HYPERBRIDGE_TIMED_OUT"; HYPERBRIDGE_FINALIZED_TIMEOUT: "HYPERBRIDGE_FINALIZED_TIMEOUT"; TIMED_OUT: "TIMED_OUT"; }>; type TimeoutStatus = typeof TimeoutStatus; type TimeoutStatusKey = keyof typeof TimeoutStatus; type AllStatusKey = RequestStatusKey | TimeoutStatusKey; declare enum HyperClientStatus { PENDING = "PENDING", SOURCE_FINALIZED = "SOURCE_FINALIZED", HYPERBRIDGE_FINALIZED = "HYPERBRIDGE_FINALIZED", HYPERBRIDGE_VERIFIED = "HYPERBRIDGE_VERIFIED", DESTINATION = "DESTINATION", TIMED_OUT = "TIMED_OUT", HYPERBRIDGE_TIMED_OUT = "HYPERBRIDGE_TIMED_OUT", ERROR = "ERROR" } declare enum OrderStatus { PLACED = "PLACED", FILLED = "FILLED", REDEEMED = "REDEEMED", REFUNDED = "REFUNDED" } declare enum TeleportStatus { TELEPORTED = "TELEPORTED", RECEIVED = "RECEIVED", REFUNDED = "REFUNDED" } interface TokenGatewayAssetTeleportedResponse { tokenGatewayAssetTeleporteds: { nodes: Array<{ id: string; from: string; to: string; sourceChain: string; destChain: string; commitment: string; amount: string; usdValue: string; assetId: string; redeem: boolean; status: TeleportStatus; createdAt: string; blockNumber: string; blockTimestamp: string; transactionHash: string; statusMetadata: { nodes: Array<{ status: TeleportStatus; chain: string; timestamp: string; blockNumber: string; blockHash: string; transactionHash: string; }>; }; }>; }; } interface TokenGatewayAssetTeleportedWithStatus { id: string; from: string; to: string; sourceChain: string; destChain: string; commitment: string; amount: bigint; usdValue: string; assetId: string; redeem: boolean; status: TeleportStatus; createdAt: Date; blockNumber: bigint; blockTimestamp: bigint; transactionHash: string; statuses: Array<{ status: TeleportStatus; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp: bigint; }; }>; } interface BlockMetadata { blockHash: string; blockNumber: number; transactionHash: string; calldata?: string; timestamp?: number; } interface PostRequestStatus { status: RequestStatusKey; metadata: Partial<BlockMetadata>; } interface PostRequestTimeoutStatus { status: TimeoutStatusKey; metadata?: Partial<BlockMetadata>; } interface StateMachineUpdate { height: number; chain: string; blockHash: string; blockNumber: number; transactionHash: string; transactionIndex: number; stateMachineId: string; timestamp: number; } interface RequestResponse { requests: { nodes: Array<{ source: string; dest: string; to: HexString; from: HexString; nonce: bigint; body: HexString; timeoutTimestamp: bigint; statusMetadata: { nodes: Array<{ blockHash: string; blockNumber: string; timestamp: string; chain: string; status: string; transactionHash: string; }>; }; }>; }; } interface GetRequestResponse { getRequests: { nodes: Array<{ source: string; dest: string; to: HexString; from: HexString; nonce: bigint; height: bigint; keys: HexString[]; context: HexString; timeoutTimestamp: bigint; statusMetadata: { nodes: Array<{ blockHash: string; blockNumber: string; timestamp: string; chain: string; status: string; transactionHash: string; }>; }; }>; }; } type RequestStatusWithMetadata = { status: RequestStatus["SOURCE"]; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; } | { status: RequestStatus["SOURCE_FINALIZED"]; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; } | { status: RequestStatus["HYPERBRIDGE_DELIVERED"]; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; } | { status: RequestStatus["HYPERBRIDGE_FINALIZED"]; metadata: { calldata: Hex; blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; } | { status: RequestStatus["DESTINATION"]; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; } | { status: TimeoutStatus["PENDING_TIMEOUT"]; metadata: { blockHash: string; blockNumber: number; transactionHash: string; }; } | { status: TimeoutStatus["DESTINATION_FINALIZED_TIMEOUT"]; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; } | { status: TimeoutStatus["HYPERBRIDGE_TIMED_OUT"]; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; } | { status: TimeoutStatus["HYPERBRIDGE_FINALIZED_TIMEOUT"]; metadata: { calldata: Hex; blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; } | { status: TimeoutStatus["TIMED_OUT"]; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp?: number; }; }; interface GenericRequestWithStatuses { source: string; dest: string; from: HexString; nonce: bigint; timeoutTimestamp: bigint; statuses: Array<RequestStatusWithMetadata>; } interface PostRequestWithStatus extends GenericRequestWithStatuses { to: HexString; body: HexString; } interface GetRequestWithStatus extends GenericRequestWithStatuses { height: bigint; keys: HexString[]; context: HexString; } interface GetResponseByRequestIdResponse { getResponses: { nodes: Array<{ id: string; commitment: string; responseMessage: string[]; }>; }; } interface ResponseCommitmentWithValues { commitment: string; values: string[]; } interface RequestCommitment { requests: { nodes: Array<{ id: string; commitment: string; }>; }; } interface StateMachineResponse { stateMachineUpdateEvents: { nodes: { height: number; chain: string; blockHash: string; blockNumber: number; transactionHash: string; transactionIndex: number; stateMachineId: string; createdAt: string; }[]; }; } interface AssetTeleported { id: string; from: string; to: string; amount: bigint; dest: string; commitment: string; createdAt: Date; blockNumber: number; } interface AssetTeleportedResponse { assetTeleporteds: { nodes: AssetTeleported[]; }; } interface StateMachineIdParams { stateId: { Evm?: number; Substrate?: HexString; Polkadot?: number; Kusama?: number; }; consensusStateId: HexString; } /** * Configuration for a blockchain chain */ interface ChainConfig { /** * The unique identifier for the chain */ chainId: number; /** * The RPC URL to connect to the chain */ rpcUrl: string; /** * The address of the IntentGateway contract on this chain */ intentGatewayAddress: string; } /** * Represents token information for an order */ interface TokenInfo { /** * The address of the ERC20 token * address(0) is used as a sentinel for the native token */ token: HexString; /** * The amount of the token */ amount: bigint; } /** * Represents payment information for an order */ interface PaymentInfo extends TokenInfo { /** * The address to receive the output tokens */ beneficiary: HexString; } /** * Represents an order in the IntentGateway */ interface Order { /** * The unique identifier for the order */ id?: string; /** * The address of the user who is initiating the transfer */ user: HexString; /** * The state machine identifier of the origin chain */ sourceChain: string; /** * The state machine identifier of the destination chain */ destChain: string; /** * The block number by which the order must be filled on the destination chain */ deadline: bigint; /** * The nonce of the order */ nonce: bigint; /** * Represents the dispatch fees associated with the IntentGateway */ fees: bigint; /** * The tokens that the filler will provide */ outputs: PaymentInfo[]; /** * The tokens that are escrowed for the filler */ inputs: TokenInfo[]; /** * A bytes array to store the calls if any */ callData: HexString; /** * The transaction hash of the order */ transactionHash?: HexString; } interface DecodedOrderPlacedLog extends Log { eventName: string; args: { user: HexString; sourceChain: Hex; destChain: Hex; deadline: bigint; nonce: bigint; fees: bigint; outputs: Array<{ token: HexString; amount: bigint; beneficiary: HexString; }>; inputs: Array<{ token: HexString; amount: bigint; }>; callData: HexString; }; transactionHash: HexString; } /** * Options for filling an order */ interface FillOptions { /** * The fee paid to the relayer for processing transactions */ relayerFee: bigint; } /** * Options for canceling an order */ interface CancelOptions { /** * The fee paid to the relayer for processing transactions */ relayerFee: string; /** * Stores the height value */ height: string; } /** * Represents a new deployment of IntentGateway */ interface NewDeployment { /** * Identifier for the state machine */ stateMachineId: HexString; /** * The gateway identifier */ gateway: HexString; } /** * Represents the body of a request */ interface RequestBody { /** * Represents the commitment of an order */ commitment: HexString; /** * Stores the identifier for the beneficiary */ beneficiary: HexString; /** * An array of token identifiers */ tokens: TokenInfo[]; } /** * Represents the parameters for the IntentGateway module */ interface IntentGatewayParams { /** * The address of the host contract */ host: string; /** * Address of the dispatcher contract responsible for handling intents */ dispatcher: string; } /** * Enum representing the different kinds of incoming requests */ declare enum RequestKind { /** * Identifies a request for redeeming an escrow */ RedeemEscrow = 0, /** * Identifies a request for recording new contract deployments */ NewDeployment = 1, /** * Identifies a request for updating parameters */ UpdateParams = 2 } /** * Configuration for the IntentFiller */ interface FillerConfig { /** * Policy for determining confirmation requirements */ confirmationPolicy: { getConfirmationBlocks: (chainId: number, amount: bigint) => number; }; /** * Maximum number of orders to process concurrently */ maxConcurrentOrders?: number; /** * Minimum profitability threshold to consider filling an order * Expressed as a percentage (e.g., 0.5 = 0.5%) */ minProfitabilityThreshold?: number; /** * Gas price strategy for each chain * Maps chainId to a gas price strategy function */ gasPriceStrategy?: Record<string, () => Promise<string>>; /** * Maximum gas price willing to pay for each chain * Maps chainId to maximum gas price in wei */ maxGasPrice?: Record<string, string>; /** * Retry configuration for failed transactions */ retryConfig?: { /** * Maximum number of retry attempts */ maxAttempts: number; /** * Initial delay between retries in ms */ initialDelayMs: number; }; /** * Configuration for the pending queue */ pendingQueueConfig?: { /** * Delay in milliseconds before rechecking an order for confirmations * Default: 30000 (30 seconds) */ recheckDelayMs?: number; /** * Maximum number of times to recheck an order before giving up * Default: 10 */ maxRechecks?: number; }; } /** * Result of an order execution attempt */ interface ExecutionResult { /** * Whether the execution was successful */ success: boolean; /** * The transaction hash if successful */ txHash?: string; /** * Error message if unsuccessful */ error?: string; /** * Gas used by the transaction */ gasUsed?: string; /** * Gas price used for the transaction */ gasPrice?: string; /** * Total transaction cost in wei */ txCost?: string; /** * Block number when the transaction was confirmed */ confirmedAtBlock?: number; /** * Timestamp when the transaction was confirmed */ confirmedAt?: Date; /** * Actual profitability achieved */ actualProfitability?: number; /** * Strategy used to fill the order */ strategyUsed?: string; /** * Any tokens exchanged during the fill process */ exchanges?: Array<{ fromToken: HexString; toToken: HexString; fromAmount: string; toAmount: string; exchangeRate: string; }>; /** * The time it took to fill the order */ processingTimeMs?: number; } /** * Represents a dispatch post for cross-chain communication */ interface DispatchPost { /** * Bytes representation of the destination state machine */ dest: HexString; /** * The destination module */ to: HexString; /** * The request body */ body: HexString; /** * Timeout for this request in seconds */ timeout: bigint; /** * The amount put up to be paid to the relayer, * this is charged in `IIsmpHost.feeToken` to `msg.sender` */ fee: bigint; /** * Who pays for this request? */ payer: HexString; } interface DispatchGet { /** * Bytes representation of the destination state machine */ dest: HexString; /** * Height at which to read the state machine */ height: bigint; /** * Raw storage keys to fetch values from the counterparty */ keys: HexString[]; /** * Timeout for this request in seconds */ timeout: bigint; /** * The amount put up to be paid to the relayer */ fee: bigint; /** * Context for the request */ context: HexString; } interface StateMachineHeight { id: { stateId: { Evm?: number; Substrate?: HexString; Polkadot?: number; Kusama?: number; }; consensusStateId: HexString; }; height: bigint; } /** * The EvmHost protocol parameters */ interface HostParams { /** * The default timeout in seconds for messages. If messages are dispatched * with a timeout value lower than this this value will be used instead */ defaultTimeout: bigint; /** * The default per byte fee */ perByteFee: bigint; /** * The cost for applications to access the hyperbridge state commitment. * They might do so because the hyperbridge state contains the verified state commitments * for all chains and they want to directly read the state of these chains state bypassing * the ISMP protocol entirely. */ stateCommitmentFee: bigint; /** * The fee token contract address. This will typically be DAI. * but we allow it to be configurable to prevent future regrets. */ feeToken: HexString; /** * The admin account, this only has the rights to freeze, or unfreeze the bridge */ admin: HexString; /** * Ismp message handler contract. This performs all verification logic * needed to validate cross-chain messages before they are dispatched to local modules */ handler: HexString; /** * The authorized host manager contract, is itself an `IIsmpModule` * which receives governance requests from the Hyperbridge chain to either * withdraw revenue from the host or update its protocol parameters */ hostManager: HexString; /** * The local UniswapV2Router02 contract, used for swapping the native token to the feeToken. */ uniswapV2: HexString; /** * The unstaking period of Polkadot's validators. In order to prevent long-range attacks */ unStakingPeriod: bigint; /** * Minimum challenge period for state commitments in seconds */ challengePeriod: bigint; /** * The consensus client contract which handles consensus proof verification */ consensusClient: HexString; /** * State machines whose state commitments are accepted */ readonly stateMachines: readonly bigint[]; /** * The state machine identifier for hyperbridge */ hyperbridge: HexString; } declare enum EvmLanguage { Solidity = 0, Vyper = 1 } interface OrderStatusMetadata { status: OrderStatus; chain: string; timestamp: bigint; blockNumber: string; transactionHash: string; filler?: string; } interface OrderWithStatus { id: string; user: string; sourceChain: string; destChain: string; commitment: string; deadline: bigint; nonce: bigint; fees: bigint; inputTokens: string[]; inputAmounts: bigint[]; inputValuesUSD: string[]; inputUSD: string; outputTokens: string[]; outputAmounts: bigint[]; outputBeneficiaries: string[]; calldata: string; status: OrderStatus; createdAt: Date; blockNumber: bigint; blockTimestamp: bigint; transactionHash: string; statuses: Array<{ status: OrderStatus; metadata: { blockHash: string; blockNumber: number; transactionHash: string; timestamp: bigint; filler?: string; }; }>; } interface OrderResponse { orderPlaceds: { nodes: Array<{ id: string; user: string; sourceChain: string; destChain: string; commitment: string; deadline: string; nonce: string; fees: string; inputTokens: string[]; inputAmounts: string[]; inputValuesUSD: string[]; inputUSD: string; outputTokens: string[]; outputAmounts: string[]; outputBeneficiaries: string[]; calldata: string; status: OrderStatus; createdAt: string; blockNumber: string; blockTimestamp: string; transactionHash: string; statusMetadata: { nodes: Array<{ status: OrderStatus; chain: string; timestamp: string; blockNumber: string; blockHash: string; transactionHash: string; filler?: string; }>; }; }>; }; } declare class AbortSignalInternal extends Error { constructor(message: string); static isError(error: unknown): error is AbortSignalInternal; } /** * The default address used as fallback when no address is provided. * This represents the zero address in EVM chains. */ declare const DEFAULT_ADDRESS = "0x0000000000000000000000000000000000000000"; /** * Parameters for an EVM chain. */ interface EvmChainParams { /** * The chain ID of the EVM chain. */ chainId: number; /** * The host address of the EVM chain. */ host: HexString; /** * The URL of the EVM chain. */ url: string; } /** * Encapsulates an EVM chain. */ declare class EvmChain implements IChain { private readonly params; private publicClient; constructor(params: EvmChainParams); /** * Derives the key for the request receipt. * @param {HexString} commitment - The commitment to derive the key from. * @returns {HexString} The derived key. */ requestReceiptKey(commitment: HexString): HexString; /** * Queries the request receipt. * @param {HexString} commitment - The commitment to query. * @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request. */ queryRequestReceipt(commitment: HexString): Promise<HexString | undefined>; /** * Queries the proof of the commitments. * @param {IMessage} message - The message to query. * @param {string} counterparty - The counterparty address. * @param {bigint} [at] - The block number to query at. * @returns {Promise<HexString>} The proof. */ queryProof(message: IMessage, counterparty: string, at?: bigint): Promise<HexString>; /** * Query and return the encoded storage proof for the provided keys at the given height. * @param {bigint} at - The block height at which to query the storage proof. * @param {HexString[]} keys - The keys for which to query the storage proof. * @returns {Promise<HexString>} The encoded storage proof. */ queryStateProof(at: bigint, keys: HexString[]): Promise<HexString>; /** * Returns the current timestamp of the chain. * @returns {Promise<bigint>} The current timestamp. */ timestamp(): Promise<bigint>; /** * Get the latest state machine height for a given state machine ID. * @param {StateMachineIdParams} stateMachineId - The state machine ID. * @returns {Promise<bigint>} The latest state machine height. */ latestStateMachineHeight(stateMachineId: StateMachineIdParams): Promise<bigint>; /** * Get the state machine update time for a given state machine height. * @param {StateMachineHeight} stateMachineheight - The state machine height. * @returns {Promise<bigint>} The statemachine update time in seconds. */ stateMachineUpdateTime(stateMachineHeight: StateMachineHeight): Promise<bigint>; /** * Get the challenge period for a given state machine id. * @param {StateMachineIdParams} stateMachineId - The state machine ID. * @returns {Promise<bigint>} The challenge period in seconds. */ challengePeriod(stateMachineId: StateMachineIdParams): Promise<bigint>; /** * Encodes an ISMP message for the EVM chain. * @param {IIsmpMessage} message The ISMP message to encode. * @returns {HexString} The encoded calldata. */ encode(message: IIsmpMessage): HexString; } /** * Slot for storing request commitments. */ declare const REQUEST_COMMITMENTS_SLOT = 0n; /** * Slot index for response commitments map */ declare const RESPONSE_COMMITMENTS_SLOT = 1n; /** * Slot index for requests receipts map */ declare const REQUEST_RECEIPTS_SLOT = 2n; /** * Slot index for response receipts map */ declare const RESPONSE_RECEIPTS_SLOT = 3n; /** * Slot index for state commitment map */ declare const STATE_COMMITMENTS_SLOT = 5n; /** * Derives the storage slot for a specific field in the StateCommitment struct * * struct StateCommitment { * uint256 timestamp; // slot + 0 * bytes32 overlayRoot; // slot + 1 * bytes32 stateRoot; // slot + 2 * } * * @param stateMachineId - The state machine ID * @param height - The block height * @param field - The field index in the struct (0 for timestamp, 1 for overlayRoot, 2 for stateRoot) * @returns The storage slot for the specific field */ declare function getStateCommitmentFieldSlot(stateMachineId: bigint, height: bigint, field: 0 | 1 | 2): HexString; declare function getStateCommitmentSlot(stateMachineId: bigint, height: bigint): HexString; /** * Generates a Merkle Mountain Range (MMR) root hash and proof for a post request. * * This function takes a post request and tree size, encodes it according to the PostRequest format, * and generates both the MMR root hash and a proof. The function builds an MMR with `treeSize` leaves, * where most leaves are variations of the encoded request (XORed with their index), except for the * last leaf, which is the unmodified request. The proof is generated for this unmodified leaf. * * @param postRequest - The post request to generate the MMR root and proof for * @param treeSize - Controls how many leaves will be added to the MMR (exactly `treeSize` leaves) * @returns An object containing: * - root: The MMR root hash as a hex string * - proof: An array of hex strings representing the MMR proof for the unmodified request * - index: The index of the unmodified request in the MMR * - kIndex: The k-index of the unmodified request in the MMR * - treeSize: The number of leaves in the MMR * - mmrSize: The size of the MMR in nodes */ declare function generateRootWithProof(postRequest: IPostRequest, treeSize: bigint): Promise<{ root: HexString; proof: HexString[]; index: bigint; kIndex: bigint; treeSize: bigint; mmrSize: bigint; }>; declare function __test(): Promise<string>; type IStateMachine = { tag: "Evm"; value: number; } | { tag: "Polkadot"; value: number; } | { tag: "Kusama"; value: number; } | { tag: "Substrate"; value: number[]; } | { tag: "Tendermint"; value: number[]; }; declare const ADDRESS_ZERO: HexString; declare const DUMMY_PRIVATE_KEY: HexString; /** * Calculates the commitment hash for a post request. * @param post The post request to calculate the commitment hash for. * @returns The commitment hash and the encode packed data. */ declare function postRequestCommitment(post: IPostRequest): { commitment: HexString; encodePacked: HexString; }; declare function orderCommitment(order: Order): HexString; /** * Converts a bytes32 token address to bytes20 format * This removes the extra padded zeros from the address */ declare function bytes32ToBytes20(bytes32Address: string): HexString; declare function bytes20ToBytes32(bytes20Address: string): HexString; declare function hexToString(hex: string): string; /** * Calculates the commitment hash for a get request. * @param get The get request to calculate the commitment hash for. * @returns The commitment hash. */ declare function getRequestCommitment(get: IGetRequest): HexString; /** * Estimates the gas required for a post request transaction on the source chain. * This function constructs a post request, generates mock proofs, and estimates * the gas cost for executing the transaction on the source chain. */ declare function estimateGasForPost(params: { postRequest: IPostRequest; sourceClient: PublicClient; hostLatestStateMachineHeight: bigint; hostAddress: HexString; }): Promise<bigint>; /** * Constructs the request body for a redeem escrow operation. * This function encodes the order commitment, beneficiary address, and token inputs * to match the format expected by the IntentGateway contract. */ declare function constructRedeemEscrowRequestBody(order: Order, beneficiary: HexString): HexString; /** * Calculates the balance mapping location for a given slot and holder address. * This function handles the different encoding formats used by Solidity and Vyper. * * @param slot - The slot number to calculate the mapping location for. * @param holder - The address of the holder to calculate the mapping location for. * @param language - The language of the contract. * @returns The balance mapping location as a HexString. */ declare function calculateBalanceMappingLocation(slot: bigint, holder: string, language: EvmLanguage): HexString; interface SubstrateChainParams { ws: string; hasher: "Keccak" | "Blake2"; } declare class SubstrateChain implements IChain { private readonly params; api?: ApiPromise; constructor(params: SubstrateChainParams); connect(): Promise<void>; /** * Disconnects the Substrate chain connection. */ disconnect(): Promise<void>; /** * Returns the storage key for a request receipt in the child trie * The request commitment is the key * @param key - The H256 hash key (as a 0x-prefixed hex string) * @returns The storage key as a hex string */ requestReceiptKey(key: HexString): HexString; /** * Returns the storage key for a request commitment in the child trie * The request commitment is the key * @param key - The H256 hash key (as a 0x-prefixed hex string) * @returns The storage key as a hex string */ requestCommitmentKey(key: HexString): HexString; /** * Queries a request commitment from the ISMP child trie storage. * @param {HexString} commitment - The commitment hash to look up. * @returns {Promise<HexString | undefined>} The commitment data if found, undefined otherwise. */ queryRequestCommitment(commitment: HexString): Promise<HexString | undefined>; /** * Queries the request receipt. * @param {HexString} commitment - The commitment to query. * @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request. */ queryRequestReceipt(commitment: HexString): Promise<HexString | undefined>; /** * Returns the current timestamp of the chain. * @returns {Promise<bigint>} The current timestamp. */ timestamp(): Promise<bigint>; /** * Queries the proof of the commitments. * @param {IMessage} message - The message to query. * @param {string} counterparty - The counterparty address. * @param {bigint} [at] - The block number to query at. * @returns {Promise<HexString>} The proof. */ queryProof(message: IMessage, counterparty: string, at?: bigint): Promise<HexString>; /** * Submit an unsigned ISMP transaction to the chain. Resolves when the transaction is finalized. * @param message - The message to be submitted. * @returns A promise that resolves to an object containing the transaction hash, block hash, and block number. */ submitUnsigned(message: IIsmpMessage): Promise<{ transactionHash: string; blockHash: string; blockNumber: number; timestamp: number; }>; /** * Query the state proof for a given set of keys at a specific block height. * @param at The block height to query the state proof at. * @param keys The keys to query the state proof for. * @returns The state proof as a hexadecimal string. */ queryStateProof(at: bigint, keys: HexString[]): Promise<HexString>; /** * Get the latest state machine height for a given state machine ID. * @param {StateMachineIdParams} stateMachineId - The state machine ID. * @returns {Promise<bigint>} The latest state machine height. */ latestStateMachineHeight(stateMachineId: StateMachineIdParams): Promise<bigint>; /** * Get the state machine update time for a given state machine height. * @param {StateMachineHeight} stateMachineheight - The state machine height. * @returns {Promise<bigint>} The statemachine update time in seconds. */ stateMachineUpdateTime(stateMachineHeight: StateMachineHeight): Promise<bigint>; /** * Get the challenge period for a given state machine id. * @param {StateMachineIdParams} stateMachineId - The state machine ID. * @returns {Promise<bigint>} The challenge period in seconds. */ challengePeriod(stateMachineId: StateMachineIdParams): Promise<bigint>; /** * Encode an ISMP calldata for a substrate chain. * @param message The ISMP message to encode. * @returns The encoded message as a hexadecimal string. */ encode(message: IIsmpMessage): HexString; /** * Returns the index of a pallet by its name, by looking up the pallets in the runtime metadata. * @param {string} name - The name of the pallet. * @returns {number} The index of the pallet. */ private getPalletIndex; } /** * Converts a state machine ID string to an enum value. * @param {string} id - The state machine ID string. * @returns {IStateMachine} The corresponding enum value. */ declare function convertStateMachineIdToEnum(id: string): IStateMachine; declare function encodeISMPMessage(message: IIsmpMessage): Uint8Array; /** * Type representing an ISMP message. */ type IIsmpMessage = IRequestMessage | ITimeoutPostRequestMessage | IGetResponseMessage; interface IRequestMessage { /** * The kind of message. */ kind: "PostRequest"; /** * The requests to be posted. */ requests: IPostRequest[]; /** * The proof of the requests. */ proof: IProof; /** * The signer of the message. */ signer: HexString; } interface IGetRequestMessage { /** * The kind of message. */ kind: "GetRequest"; /** * The requests to be posted. */ requests: IGetRequest[]; /** * The proof of the requests. */ proof: IProof; /** * The signer of the message. */ signer: HexString; } interface IGetResponse { /** * The request that triggered this response. */ get: IGetRequest; /** * The response message. */ values: GetResponseStorageValues[]; } interface IGetResponseMessage { /** * The kind of message. */ kind: "GetResponse"; /** * The responses to be posted. */ responses: IGetResponse[]; /** * The proof of the responses. */ proof: IProof; /** * The signer of the message. */ signer: HexString; } interface ITimeoutPostRequestMessage { /** * The kind of message. */ kind: "TimeoutPostRequest"; /** * The requests to be posted. */ requests: IPostRequest[]; /** * The proof of the requests. */ proof: IProof; } interface IProof { /** * The height of the proof. */ height: bigint; /** * The state machine identifier of the proof. */ stateMachine: string; /** * The associated consensus state identifier of the proof. */ consensusStateId: string; /** * The encoded storage proof */ proof: HexString; } /** * Interface representing a chain. */ interface IChain { timestamp(): Promise<bigint>; /** * Returns the state trie key for the request-receipt storage item for the given request commitment. */ requestReceiptKey(commitment: HexString): HexString; /** * Query and return the request-receipt for the given request commitment. */ queryRequestReceipt(commitment: HexString): Promise<HexString | undefined>; /** * Query and return the encoded storage proof for the provided keys at the given height. */ queryStateProof(at: bigint, keys: HexString[]): Promise<HexString>; queryProof(message: IMessage, counterparty: string, at?: bigint): Promise<HexString>; encode(message: IIsmpMessage): HexString; /** * Get the latest state machine height for a given state machine ID. */ latestStateMachineHeight(stateMachineId: StateMachineIdParams): Promise<bigint>; /** * Get the challenge period for a given state machine ID. */ challengePeriod(stateMachineId: StateMachineIdParams): Promise<bigint>; /** * Get the update time for a statemachine height. */ stateMachineUpdateTime(stateMachineHeight: StateMachineHeight): Promise<bigint>; } /** * Returns the chain interface for a given state machine identifier * @param chainConfig - Chain configuration * @returns Chain interface */ declare function getChain(chainConfig: IEvmConfig | ISubstrateConfig): Promise<IChain>; /** * IndexerClient provides methods for interacting with the Hyperbridge indexer. * * This client facilitates querying and tracking cross-chain requests and their status * through the Hyperbridge protocol. It supports: * * - Querying state machine updates by block height or timestamp * - Retrieving request status information by transaction hash * - Monitoring request status changes through streaming interfaces * - Handling request timeout flows and related proof generation * - Tracking request finalization across source and destination chains * * The client implements automatic retries with exponential backoff for network * resilience and provides both simple query methods and advanced streaming * interfaces for real-time status tracking. * * The URLs provided in the configuration must point to archive nodes to allow the client to query for storage proofs * of potentially much older blocks. Regular nodes only store the state for recent blocks and will not be able * to provide the necessary proofs for cross-chain verification, especially in timeout scenarios. * * @example * ```typescript * const client = new IndexerClient({ * url: "https://indexer.hyperbridge.xyz/graphql", * pollInterval: 2000, * source: { * stateMachineId: "EVM-1", * consensusStateId: "ETH0" * rpcUrl: "", * host: "0x87ea45..", * }, * dest: { * stateMachineId: "EVM-42161", * consensusStateId: "ETH0" * rpcUrl: "", * host: "0x87ea42345..", * }, * hyperbridge: { * stateMachineId: "POLKADOT-3367", * consensusStateId: "DOT0" * wsUrl: "ws://localhost:9944" * } * }); * * // Query a request status * const status = await client.queryRequestWithStatus("0x1234..."); * * // Stream status updates * for await (const update of client.postRequestStatusStream("0x1234...")) { * console.log(`Request status: ${update.status}`); * } * ``` */ declare class IndexerClient { /** * GraphQL client used for making requests to the indexer */ private client; /** * Configuration for the IndexerClient including URLs, poll intervals, and chain-specific settings */ private config; private logger; /** * Default configuration for retry behavior when network requests fail * - maxRetries: Maximum number of retry attempts before failing * - backoffMs: Initial backoff time in milliseconds (doubles with each retry) */ private defaultRetryConfig; /** * Creates a new IndexerClient instance */ constructor(config: PartialClientConfig); /** * Query for a single state machine update event greater than or equal to the given height. * @params statemachineId - ID of the state machine * @params height - Starting block height * @params chain - The identifier for the chain where the state machine update should be queried (corresponds to a stateMachineId) * @returns Closest state machine update */ queryStateMachineUpdateByHeight({ statemachineId, height, chain, }: { statemachineId: string; chain: string; height: number; }): Promise<StateMachineUpdate | undefined>; /** * Query for a single state machine update event greater than or equal to the given timestamp. * @params statemachineId - ID of the state machine * @params timestamp - Starting block timestamp * @params chain - The identifier for the chain where the state machine update should be queried (corresponds to a stateMachineId) * @returns Closest state machine update */ queryStateMachineUpdateByTimestamp({ statemachineId, commitmentTimestamp, chain, }: { statemachineId: string; commitmentTimestamp: bigint; chain: string; }): Promise<StateMachineUpdate | undefined>; /** * Queries a request by CommitmentHash * * @param commitment_hash - Can be commitment * @returns Latest status and block metadata of the request */ queryPostRequest(commitment_hash: string): Promise<PostRequestWithStatus | undefined>; /** * Queries a request by any of its associated hashes and returns it alongside its statuses * Statuses will be one of SOURCE, HYPERBRIDGE_DELIVERED and DESTINATION * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash * @returns Latest status and block metadata of the request */ queryGetRequest(hash: string): Promise<GetRequestWithStatus | undefined>; /** * Queries the response associated with a specific request ID and returns its commitment * @param requestId - The ID of the request to find the associated response for * @returns The response associated with the given request ID, or undefined if not found */ queryResponseByRequestId(requestId: string): Promise<ResponseCommitmentWithValues | undefined>; /** * Enhances a request with finality events by querying state machine updates. * * This method augments a request object with additional inferred status events * that represent chain finality confirmations. It adds: * - SOURCE_FINALIZED: When the source chain has finalized the request * - HYPERBRIDGE_FINALIZED: When Hyperbridge has finalized the delivery confirmation * * The method also generates appropriate calldata for submitting cross-chain proofs * when applicable. * * @param request - The request to enhance with finality events * @returns The request with finality events added * @private */ private addRequestFinalityEvents; /** * Adds timeout finality events to a request by querying for relevant timeout proofs and * chain state necessary for timeout processing. * * This method enhances a request object with additional status events related to the * timeout flow, including: * - PENDING_TIMEOUT: When a request has passed its timeout timestamp * - DESTINATION_FINALIZED: When the destination chain has finalized the timeout timestamp * - HYPERBRIDGE_FINALIZED_TIMEOUT: When hyperbridge has finalized the timeout state * * The method also generates appropriate calldata for submitting timeout proofs. * * @param request - Request to fill timeout events for * @returns Request with timeout events filled in, including any proof calldata for timeout submissions * @private */ private addTimeoutFinalityEvents; /** * Queries a request returns it alongside its statuses, * including any finalization events. * @param hash - Commitment hash * @returns Full request data with all inferred status events, including SOURCE_FINALIZED and HYPERBRIDGE_FINALIZED * @remarks Unlike queryRequest(), this method adds derived finalization status events by querying state machine updates */ queryRequestWithStatus(hash: string): Promise<PostRequestWithStatus | undefined>; /** * Create a Stream of status updates for a post request. * Stream ends when either the request reaches the destination or times out. * If the stream yields TimeoutStatus.PENDING_TIMEOUT, use postRequestTimeoutStream() to begin timeout processing. * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash * @returns AsyncGenerator that emits status updates until a terminal state is reached * @example * * let client = new IndexerClient(config) * let stream = client.postRequestStatusStream(hash) * * // you can use a for-await-of loop * for await (const status of stream) { * console.log(status) * } * * // you can also use a while loop * while (true) { * const status = await stream.next() * if (status.done) { * break * } * console.log(status.value) * } * */ postRequestStatusStream(hash: HexString): AsyncGenerator<RequestStatusWithMetadata, void>; timeoutStream(timeoutTimestamp: bigint, chain: IChain): AsyncGenerator<RequestStatusWithMetadata, void>; /** * Create a Stream of status updates * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash * @returns AsyncGenerator that emits status updates until a terminal state is reached */ private postRequestStatusStreamInternal; private sleep_for; private sleep_for_interval; /** * Create a Stream of status updates for a get request. * Stream ends when either the request reaches the destination or times out. * If the stream yields TimeoutStatus.PENDING_TIMEOUT, use postRequestTimeoutStream() to begin timeout processing. * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash * @returns AsyncGenerator that emits status updates until a terminal state is reached * @example * * let client = new IndexerClient(config) * let stream = client.getRequestStatusStream(hash) * * // you can use a for-await-of loop * for await (const status of stream) { * console.log(status) * } * * // you can also use a while loop * while (true) { * const status = await stream.next() * if (status.done) { * break * } * console.log(status.value) * } * */ getRequestStatusStream(hash: HexString): AsyncGenerator<RequestStatusWithMetadata, void>; /** * Create a Stream of status updates * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash * @returns AsyncGenerator that emits status updates until a terminal state is reached */ private getRequestStatusStreamInternal; /** * Create a Stream of status updates for a timed out post request. * @param ha