@bolt-liquidity-hq/sui-client 0.1.0-beta.11 → 0.1.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +445 -367
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +170 -64
- package/dist/index.d.ts +170 -64
- package/dist/index.js +434 -363
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lib/client.ts","../src/config/mainnet.ts","../src/config/testnet.ts","../src/lib/oracle/get-asset-pairs.ts","../src/lib/constants/defaults.ts","../src/lib/constants/sui-objects.ts","../src/lib/helpers/bcs-parse.ts","../src/lib/helpers/coin-manager.ts","../src/lib/helpers/queries.ts","../src/lib/helpers/txs.ts","../src/lib/oracle/parsers.ts","../src/types/bcs.ts","../src/types/oracle.ts","../src/types/router.ts","../src/types/pool.ts","../src/lib/oracle/get-assets.ts","../src/lib/oracle/get-oracle-config.ts","../src/lib/oracle/get-price.ts","../src/lib/oracle/get-prices.ts","../src/lib/router/estimate-swap-exact-in-gas-fees.ts","../src/lib/router/get-all-base-liquidity.ts","../src/lib/router/parsers.ts","../src/lib/router/get-all-quotes-for-user.ts","../src/lib/router/get-pool-for-base.ts","../src/lib/router/get-pools.ts","../src/lib/router/get-router-config.ts","../src/lib/router/swap-exact-in.ts","../src/lib/settlement/get-pool-info.ts","../src/lib/settlement/parsers.ts","../src/tests/constants/sui-objects.ts","../src/lib/settlement/get-pool-info-for-base.ts"],"sourcesContent":["export { BoltSuiClient } from './lib/client';\n\nexport * from './types';\n","import type {\n Address,\n BaseLiquidityDetails,\n Coin,\n InvertiblePrice,\n OracleAssetPair,\n OracleConfig,\n PoolConfig,\n Pool,\n Price,\n RouterConfig,\n SwapParams,\n SwapResult,\n Contracts,\n AssetsConfig,\n Asset,\n} from '@bolt-liquidity-hq/core';\nimport { BaseClient, MissingParameterError } from '@bolt-liquidity-hq/core';\nimport { SuiClient, type SuiTransactionBlockResponse } from '@mysten/sui/client';\nimport type { Signer } from '@mysten/sui/cryptography';\n\nimport {\n MainnetAssets,\n MainnetChainConfig,\n MainnetContracts,\n MainnetPackageId,\n MainnetPoolGlobalConfigId,\n TestnetAssets,\n TestnetChainConfig,\n TestnetContracts,\n TestnetPoolGlobalConfigId,\n TestnetPackageId,\n MainnetNativeTokenDenom,\n TestnetNativeTokenDenom,\n} from '../config';\nimport { getAssets, getAssetPairs, getOracleConfig, getPrice, getPrices } from './oracle';\nimport {\n estimateSwapExactInGasFees,\n getAllBaseLiquidity,\n getAllQuotesForUser,\n getPoolForBase,\n getPools,\n getRouterConfig,\n swapExactIn,\n} from './router';\nimport { getPoolInfo, getPoolInfoForBase } from './settlement';\nimport type { SuiChainConfig, SuiClientConfig } from '../types';\n\n/**\n * Client implementation for interacting with the Bolt Liquidity Outpost on Sui blockchain.\n *\n * This class extends the abstract {@link BaseClient} to provide Sui-specific functionality\n * for querying and executing transactions on Bolt Protocol's oracle and router smart contracts.\n * It uses SuiTransactionBlockResponse as the transaction output type, providing detailed transaction execution information.\n *\n * @extends {BaseClient<Signer, SuiTransactionBlockResponse>}\n *\n * @group Bolt API Clients\n *\n * @example\n * ```typescript\n * // Create a client for Sui mainnet\n * const client = new BoltSuiClient();\n *\n * // Query oracle prices\n * const price = await client.getPrice(\"0x2::sui::SUI\", \"0xusdcAddress...\");\n *\n * // Execute a swap (requires signer)\n * const signer = // ... get signer from wallet\n * const result = await client.swap({\n * assetIn: \"0x2::sui::SUI\",\n * amountIn: \"1000000000\", // 1 SUI (9 decimals)\n * assetOut: \"0xusdcAddress...\"\n * }, signer);\n * ```\n */\nexport class BoltSuiClient extends BaseClient<Signer, SuiTransactionBlockResponse> {\n /**\n * The Sui-specific chain configuration including RPC endpoint\n */\n public override chainConfig: SuiChainConfig;\n\n /**\n * Package Id for the deployed Bolt contracts on Sui\n */\n public packageId: string;\n\n /**\n * Object Id for the GlobalConfig of the deployed Pool contracts\n */\n public poolGlobalConfigId: string;\n\n /**\n * Cached instance of the Signer for transaction execution\n * @private\n */\n public signer?: Signer;\n\n /**\n * Instance of the Sui client to interact with the blockchain\n */\n public suiClient: SuiClient;\n\n /**\n * Creates a new instance of the BoltSuiClient.\n *\n * The client automatically configures itself based on the specified environment,\n * loading the appropriate contract addresses, chain configuration, native token denomination,\n * and assets from configuration files.\n *\n * @param config - (Optional) Configuration for the client\n * @param config.environment - (Optional) The deployment environment ('mainnet' or 'testnet'). Defaults to 'mainnet'\n * @param config.customOverride - (Optional) Custom overrides for chain configuration, contracts, native token, and assets\n * @param config.customOverride.chainConfig - (Optional) Override chain configuration\n * @param config.customOverride.chainConfig.id - (Optional) Custom chain ID\n * @param config.customOverride.chainConfig.name - (Optional) Custom chain name\n * @param config.customOverride.chainConfig.rpcEndpoint - (Optional) Custom RPC endpoint URL\n * @param config.customOverride.packageId - (Optional) Custom package ID for Bolt contracts\n * @param config.customOverride.poolGlobalConfigId - (Optional) Custom Object ID for the Pool contracts' Global Config\n * @param config.customOverride.contracts - (Optional) Override contract addresses\n * @param config.customOverride.contracts.oracle - (Optional) Custom oracle contract address\n * @param config.customOverride.contracts.router - (Optional) Custom router contract address\n * @param config.customOverride.nativeTokenDenom - (Optional) Custom native token denomination (e.g., \"SUI\")\n * @param config.customOverride.assetsConfig - (Optional) Custom asset configurations indexed by denom\n * @param config.signer - (Optional) Pre-existing Signer for transaction signing\n * @param config.suiClient - (Optional) Pre-existing SuiClient to use for blockchain queries\n *\n * @throws {InvalidObjectError} Thrown when required configuration fields are missing\n *\n * @example\n * ```typescript\n * // Use default configuration (Sui mainnet)\n * const client = new BoltSuiClient();\n *\n * // Use testnet configuration\n * const testnetClient = new BoltSuiClient({\n * environment: 'testnet'\n * });\n *\n * // Use custom chain configuration\n * const customClient = new BoltSuiClient({\n * customOverride: {\n * chainConfig: {\n * id: 'sui-custom',\n * name: 'Sui Custom',\n * rpcEndpoint: 'https://custom-rpc.example.com'\n * },\n * packageId: '0xcustom_package_id...',\n * poolGlobalConfigId: '0xcustom_global_config_id...',\n * contracts: {\n * oracle: '0xcustom_oracle...',\n * router: '0xcustom_router...'\n * },\n * nativeTokenDenom: 'SUI',\n * assetsConfig: {\n * '0x2::sui::SUI': {\n * symbol: 'SUI',\n * name: 'Sui',\n * chainId: 'sui-custom',\n * denom: '0x2::sui::SUI',\n * decimals: 9,\n * logo: 'https://example.com/sui.png',\n * coingeckoId: 'sui'\n * }\n * }\n * }\n * });\n *\n * // Use pre-existing Sui client and signer\n * const clientWithCustomClient = new BoltSuiClient({\n * suiClient: mySuiClient,\n * signer: mySigner\n * });\n * ```\n */\n constructor(config?: SuiClientConfig) {\n const { environment = 'mainnet', customOverride, signer, suiClient } = config ?? {};\n\n const defaultChainConfig: SuiChainConfig =\n environment === 'mainnet' ? MainnetChainConfig : TestnetChainConfig;\n const defaultContracts: Contracts =\n environment === 'mainnet' ? MainnetContracts : TestnetContracts;\n const defaultPackageId = environment === 'mainnet' ? MainnetPackageId : TestnetPackageId;\n const defaultPoolGlobalConfigId =\n environment === 'mainnet' ? MainnetPoolGlobalConfigId : TestnetPoolGlobalConfigId;\n const defaultNativeTokenDenom =\n environment === 'mainnet' ? MainnetNativeTokenDenom : TestnetNativeTokenDenom;\n const assetsConfig: AssetsConfig = environment === 'mainnet' ? MainnetAssets : TestnetAssets;\n\n // Apply overrides\n const chainConfig: SuiChainConfig = {\n id: customOverride?.chainConfig?.id ?? defaultChainConfig.id,\n name: customOverride?.chainConfig?.name ?? defaultChainConfig.name,\n rpcEndpoint: customOverride?.chainConfig?.rpcEndpoint ?? defaultChainConfig.rpcEndpoint,\n };\n const packageId = customOverride?.packageId ?? defaultPackageId;\n const poolGlobalConfigId = customOverride?.poolGlobalConfigId ?? defaultPoolGlobalConfigId;\n const contracts: Contracts = {\n oracle: customOverride?.contracts?.oracle ?? defaultContracts.oracle,\n router: customOverride?.contracts?.router ?? defaultContracts.router,\n };\n const nativeTokenDenom = customOverride?.nativeTokenDenom ?? defaultNativeTokenDenom;\n\n for (const item of Object.values(customOverride?.assetsConfig ?? {})) {\n assetsConfig[item.denom] = item;\n }\n\n super({\n customOverride: {\n chainConfig,\n contracts,\n nativeTokenDenom,\n assetsConfig,\n },\n });\n\n this.chainConfig = chainConfig;\n this.packageId = packageId;\n this.poolGlobalConfigId = poolGlobalConfigId;\n this.signer = signer;\n this.suiClient = suiClient ?? new SuiClient({ url: chainConfig.rpcEndpoint });\n }\n\n /**\n * Gets or sets the signer for transaction execution.\n *\n * This method manages the signer instance used for signing transactions.\n * A signer must be provided either when creating the client, on first call,\n * or to replace the existing signer.\n *\n * @param newSigner - Optional new signer to replace the existing one\n *\n * @returns The current signer instance\n *\n * @throws {MissingParameterError} Thrown when no signer is available and none is provided\n *\n * @example\n * ```typescript\n * // Get the current signer (throws if none exists)\n * const currentSigner = client.getSigner();\n *\n * // Set a new signer\n * const newSigner = // ... obtain signer from wallet\n * const signer = client.getSigner(newSigner);\n * ```\n */\n public getSigner(newSigner?: Signer): Signer {\n this.signer = newSigner ?? this.signer;\n\n if (!this.signer) {\n throw new MissingParameterError('signer');\n }\n\n return this.signer;\n }\n\n // The following methods inherit their documentation from BaseClient\n // Only add documentation here if you need to override or add implementation-specific details\n\n /** @inheritdoc */\n public async getOracleConfig(): Promise<OracleConfig> {\n return await getOracleConfig(this);\n }\n\n /** @inheritdoc */\n async getAllOracleAssetPairs(): Promise<OracleAssetPair[]> {\n return await getAssetPairs(this);\n }\n\n /** @inheritdoc */\n async getPrice(baseDenom: string, quoteDenom: string): Promise<InvertiblePrice> {\n return await getPrice(this, baseDenom, quoteDenom);\n }\n\n /** @inheritdoc */\n async getAllPrices(): Promise<Price[]> {\n return await getPrices(this);\n }\n\n /** @inheritdoc */\n async getRouterConfig(): Promise<RouterConfig> {\n return await getRouterConfig(this);\n }\n\n /** @inheritdoc */\n async getAllBaseAssetsLiquidity(): Promise<Record<Address, BaseLiquidityDetails>> {\n return await getAllBaseLiquidity(this);\n }\n\n /** @inheritdoc */\n async getAllQuotesByUser(address: Address): Promise<Record<Address, Coin[]>> {\n return await getAllQuotesForUser(this, address);\n }\n\n /** @inheritdoc */\n async getPoolByBaseAsset(baseDenom: string): Promise<Pool> {\n return await getPoolForBase(this, baseDenom);\n }\n\n /** @inheritdoc */\n async getAllPools(): Promise<Pool[]> {\n return await getPools(this);\n }\n\n // Satisfy the base class requirement\n async getPoolConfig(poolContractAddress: string): Promise<PoolConfig> {\n return await getPoolInfo(this, poolContractAddress);\n }\n\n /** @inheritdoc */\n async getAssets(): Promise<Asset[]> {\n return await getAssets(this);\n }\n\n /** @inheritdoc */\n async getPoolConfigByBaseAsset(baseDenom: string): Promise<PoolConfig> {\n return await getPoolInfoForBase(this, baseDenom);\n }\n\n /**\n * @inheritdoc\n *\n * @example\n * ```typescript\n * // Get signer from wallet (e.g., Sui Wallet, Suiet, etc.)\n * const signer = // ... obtain signer from wallet\n *\n * // Execute swap: 1 SUI for USDC\n * const result = await client.swap({\n * assetIn: \"0x2::sui::SUI\",\n * amountIn: \"1000000000\", // 1 SUI (9 decimals)\n * assetOut: \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\", // USDC address\n * minimumAmountOut: \"1950000\", // Minimum 1.95 USDC expected (6 decimals)\n * receiver: \"0x...\" // Optional custom receiver address\n * }, signer);\n *\n * console.log(`Swap successful!`);\n * console.log(`Transaction digest: ${result.txHash}`);\n * console.log(`Received: ${result.amountOut} ${result.assetOut}`);\n * console.log(`Gas cost: ${result.txOutput.effects.gasUsed.computationCost}`);\n * console.log(`Status: ${result.txOutput.effects.status.status}`);\n * ```\n *\n * @remarks\n * This implementation returns a SuiTransactionBlockResponse as the transaction output,\n * which includes details like gas costs, transaction effects, object changes, and events.\n */\n async swap(\n params: SwapParams,\n signer?: Signer\n ): Promise<SwapResult<SuiTransactionBlockResponse>> {\n return await swapExactIn(this, params, signer);\n }\n\n /**\n * @inheritdoc\n *\n * @example\n * ```typescript\n * // Get signer from wallet (e.g., Sui Wallet, Suiet, etc.)\n * const signer = // ... obtain signer from wallet\n *\n * // Estimate gas for swapping 1 SUI to USDC\n * const gasEstimate = await client.estimateSwapGasFees({\n * assetIn: \"0x2::sui::SUI\",\n * amountIn: \"1000000000\", // 1 SUI (9 decimals)\n * assetOut: \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\", // USDC\n * minimumAmountOut: \"1950000\" // Min 1.95 USDC (6 decimals)\n * }, signer, 1.3); // 30% safety margin\n *\n * if (gasEstimate) {\n * console.log(`Estimated gas: ${gasEstimate.amount} ${gasEstimate.denom}`);\n * }\n * ```\n *\n * @remarks\n * - For Sui, gas is always paid in SUI tokens\n * - The returned amount is in MIST (smallest unit, 9 decimals)\n * - Gas estimation uses Sui's dry run transaction capability\n * - The gasAdjustment parameter helps account for variations in actual execution\n * - Sui's gas model includes computation, storage, and storage rebates\n */\n async estimateSwapGasFees(\n params: SwapParams,\n signer?: Signer,\n gasAdjustment?: number\n ): Promise<Coin | undefined> {\n return await estimateSwapExactInGasFees(this, params, signer, gasAdjustment);\n }\n}\n","import type { AssetsConfig, Contracts } from '@bolt-liquidity-hq/core';\nimport { SUI_DECIMALS, SUI_TYPE_ARG } from '@mysten/sui/utils';\n\nimport type { SuiChainConfig } from '../types';\n\nexport const MainnetChainConfig: SuiChainConfig = {\n name: 'Sui',\n id: '101',\n rpcEndpoint: 'https://fullnode.mainnet.sui.io:443',\n};\n\nexport const MainnetContracts: Contracts = {\n oracle: '0x...',\n router: '0x...',\n};\n\nexport const MainnetPackageId: string = '0x...';\n\nexport const MainnetPoolGlobalConfigId: string = '0x...';\n\nexport const MainnetNativeTokenDenom: string = SUI_TYPE_ARG;\n\nexport const MainnetAssets: AssetsConfig = {\n [SUI_TYPE_ARG]: {\n symbol: 'SUI',\n name: 'Sui',\n chainId: '101',\n denom: SUI_TYPE_ARG,\n decimals: SUI_DECIMALS,\n logo: 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/sui/info/logo.png',\n coingeckoId: 'sui',\n },\n '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC': {\n symbol: 'USDC',\n name: 'Circle USDC',\n chainId: '101',\n denom: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n logo: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/USDCoin.png',\n coingeckoId: 'usd-coin',\n },\n};\n","import type { AssetsConfig, Contracts } from '@bolt-liquidity-hq/core';\nimport { SUI_DECIMALS, SUI_TYPE_ARG } from '@mysten/sui/utils';\n\nimport type { SuiChainConfig } from '../types';\n\nexport const TestnetChainConfig: SuiChainConfig = {\n name: 'Sui Testnet',\n id: '103',\n rpcEndpoint: 'https://fullnode.testnet.sui.io:443',\n};\n\nexport const TestnetContracts: Contracts = {\n oracle: '0xecece01cfb23b5439e04b18fe656eaf2746b9087cf68f1d48797c8f71a3dd93b',\n router: '0x3881fdcb4a7fbcda8edc230e6f92eb57b24c0be6b44af0b5e1d0b45564f3ed00',\n};\n\nexport const TestnetPackageId: string =\n '0x22384b1841229e2be878bb7e88833c03e23ff5dc39accd050fb932120602f85e';\n\nexport const TestnetPoolGlobalConfigId: string =\n '0xa9491e59fa63e666cbfdea2e880b2d8ba0085eeb244220cefa3fb817559cd79c';\n\nexport const TestnetNativeTokenDenom: string = SUI_TYPE_ARG;\n\nexport const TestnetAssets: AssetsConfig = {\n [SUI_TYPE_ARG]: {\n symbol: 'SUI',\n name: 'Sui',\n chainId: '103',\n denom: SUI_TYPE_ARG,\n decimals: SUI_DECIMALS,\n logo: 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/sui/info/logo.png',\n coingeckoId: 'sui',\n },\n '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC': {\n symbol: 'USDC',\n name: 'Circle USDC',\n chainId: '103',\n denom: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',\n decimals: 6,\n logo: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/USDCoin.png',\n coingeckoId: 'usd-coin',\n },\n};\n","import type { OracleAssetPair } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\n\nimport type { BoltSuiClient } from '../client';\nimport { DEFAULT_PAGINATION_LIMIT, PRICE_ORACLE_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseAssetPairsResponsePaginatedStructOutput } from './parsers';\nimport { AssetPairsResponsePaginatedStruct } from '../../types';\n\n/**\n * Queries the oracle smart contract to retrieve all supported asset pairs with automatic pagination handling.\n *\n * This function fetches the complete list of trading pairs that the oracle contract\n * supports for price feeds. Each asset pair represents a base/quote relationship\n * that can be used for price queries and swaps within the Bolt protocol. The function\n * automatically handles pagination to ensure all pairs are retrieved, regardless of\n * the total number.\n *\n * @param client - The BoltSuiClient instance.\n *\n * @returns A promise that resolves to an array of OracleAssetPair objects, each containing:\n * - base: Information about the base asset\n * - name: The full name of the base asset (currently same as symbol)\n * - symbol: The trading symbol (e.g., \"SUI\", \"ETH\")\n * - precision: The number of decimal places for the base asset\n * - quote: Information about the quote asset\n * - name: The full name of the quote asset (currently same as symbol)\n * - symbol: The trading symbol (e.g., \"USDC\", \"USDT\")\n * - precision: The number of decimal places for the quote asset\n *\n * @throws {TransactionFailedError} When the oracle contract query fails, which could happen if:\n * - The oracle contract is not properly initialized\n * - The contract address is incorrect\n * - Network connection issues occur\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - The contract returned data in an unexpected format\n * - The BCS deserialization failed\n * - The contract ABI has changed\n */\nexport const getAssetPairs = async (client: BoltSuiClient): Promise<OracleAssetPair[]> => {\n /**\n * The Move function name in the oracle module that returns paginated asset pairs.\n * This function signature in Move:\n * public fun asset_pairs_paginated(\n * oracle: &Oracle,\n * limit: Option<u64>,\n * cursor: Option<String>\n * ): AssetPairsResponsePaginated\n */\n const ASSET_PAIRS_PAGINATED_FUNCTION = 'asset_pairs_paginated';\n\n const result: OracleAssetPair[] = [];\n\n let currentCursor = null;\n\n let hasNextPage = true;\n\n while (hasNextPage) {\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, PRICE_ORACLE_MODULE, ASSET_PAIRS_PAGINATED_FUNCTION],\n [\n client.contracts.oracle,\n bcs.option(bcs.u64()).serialize(DEFAULT_PAGINATION_LIMIT),\n bcs.option(bcs.string()).serialize(currentCursor),\n ]\n );\n\n const output = parseDevInspectResult(response, AssetPairsResponsePaginatedStruct);\n\n const assetPairs = parseAssetPairsResponsePaginatedStructOutput(output);\n\n result.push(...assetPairs);\n\n currentCursor = output.next_cursor;\n hasNextPage = output.has_next_page;\n }\n\n return result;\n};\n","export const DEFAULT_PAGINATION_LIMIT = 50;\n","export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000000000000000000000000000';\n\nexport const SUI_SYSTEM_CLOCK = '0x6';\n\nexport const PRICE_ORACLE_MODULE = 'price_oracle';\n\nexport const ROUTER_MODULE = 'router';\n\nexport const POOL_MODULE = 'settlement';\n","import { InvalidObjectError, ParseError } from '@bolt-liquidity-hq/core';\nimport type { BcsType } from '@mysten/bcs';\nimport { bcs } from '@mysten/bcs';\nimport type { DevInspectResults } from '@mysten/sui/client';\n\nimport type { BcsParsed } from '../../types';\n\n/**\n * Extracts raw bytes from a DevInspectResults object at the specified indices.\n *\n * This utility function navigates the nested structure of Sui's DevInspectResults\n * to extract the raw byte array from a specific return value.\n *\n * @param result - The DevInspectResults object returned from a Sui devInspect call\n * @param resultIndex - The index of the result to extract from (defaults to 0)\n * @param returnValueIndex - The index of the return value within the result (defaults to 0)\n *\n * @returns The extracted bytes as a Uint8Array, or null if the specified indices don't exist\n *\n * @example\n * ```typescript\n * const result = await suiClient.devInspectTransactionBlock({...});\n * const bytes = extractBytes(result, 0, 0);\n * if (bytes) {\n * const parsedValue = bcs.u64().parse(bytes);\n * }\n * ```\n */\nexport const extractBytes = (\n result: DevInspectResults,\n resultIndex: number = 0,\n returnValueIndex: number = 0\n): Uint8Array | null => {\n const returnValues = result.results?.[resultIndex]?.returnValues;\n if (!returnValues || !returnValues[returnValueIndex]) {\n return null;\n }\n\n const [bytes] = returnValues[returnValueIndex];\n return new Uint8Array(bytes);\n};\n\n/**\n * A utility class providing static methods for parsing common BCS (Binary Canonical Serialization) types.\n *\n * BCS is the serialization format used by Sui for encoding Move types. This class\n * provides convenient wrappers around the @mysten/bcs library's parsing functions\n * for commonly used primitive and composite types.\n *\n * @example\n * ```typescript\n * // Parse a u64 value\n * const bytes = new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0]);\n * const value = BcsCommonParser.parseU64(bytes); // \"1\"\n *\n * // Parse a vector of strings\n * const vectorBytes = // ... bytes from Sui\n * const strings = BcsCommonParser.parseVector(vectorBytes, bcs.string());\n *\n * // Parse an optional value\n * const optionBytes = // ... bytes from Sui\n * const maybeValue = BcsCommonParser.parseOption(optionBytes, bcs.u32());\n * ```\n */\nexport class BcsCommonParser {\n /**\n * Parses a BCS-encoded unsigned 8-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u8 value as a number (0-255)\n */\n static parseU8(bytes: Uint8Array): number {\n return bcs.u8().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 16-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u16 value as a number (0-65535)\n */\n static parseU16(bytes: Uint8Array): number {\n return bcs.u16().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 32-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u32 value as a number (0-4294967295)\n */\n static parseU32(bytes: Uint8Array): number {\n return bcs.u32().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 64-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u64 value as a string (to preserve precision)\n *\n * @remarks\n * Returns a string because JavaScript numbers cannot safely represent\n * all 64-bit integer values without loss of precision.\n */\n static parseU64(bytes: Uint8Array): string {\n return bcs.u64().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 128-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u128 value as a string\n */\n static parseU128(bytes: Uint8Array): string {\n return bcs.u128().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 256-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u256 value as a string\n */\n static parseU256(bytes: Uint8Array): string {\n return bcs.u256().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded boolean value.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed boolean value\n */\n static parseBool(bytes: Uint8Array): boolean {\n return bcs.bool().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded string.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed string value\n */\n static parseString(bytes: Uint8Array): string {\n return bcs.string().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded vector (dynamic array) of elements.\n *\n * @template T - The type of elements in the vector\n * @param bytes - The BCS-encoded bytes to parse\n * @param elementParser - The BCS parser for individual vector elements\n * @returns An array of parsed elements\n *\n * @example\n * ```typescript\n * // Parse a vector of u64 values\n * const numbers = BcsCommonParser.parseVector(bytes, bcs.u64());\n *\n * // Parse a vector of custom structs\n * const customType = bcs.struct('MyStruct', {\n * id: bcs.u64(),\n * name: bcs.string()\n * });\n * const structs = BcsCommonParser.parseVector(bytes, customType);\n * ```\n */\n static parseVector<T>(bytes: Uint8Array, elementParser: BcsType<T>): T[] {\n return bcs.vector(elementParser).parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded Option type (similar to Rust's Option or Move's Option).\n *\n * @template T - The type of the optional value\n * @param bytes - The BCS-encoded bytes to parse\n * @param elementParser - The BCS parser for the optional value if present\n * @returns The parsed value if Some, or null if None\n *\n * @example\n * ```typescript\n * // Parse an optional address\n * const maybeAddress = BcsCommonParser.parseOption(bytes, bcs.string());\n * if (maybeAddress) {\n * console.log(`Address: ${maybeAddress}`);\n * } else {\n * console.log('No address provided');\n * }\n * ```\n */\n static parseOption<T>(bytes: Uint8Array, elementParser: BcsType<T>): T | null {\n return bcs.option(elementParser).parse(bytes);\n }\n}\n\n/**\n * Parses a single return value from a DevInspectResults object using a specified BCS parser.\n *\n * This function combines byte extraction and BCS parsing into a single operation,\n * handling errors appropriately and providing detailed error context.\n *\n * @template T - The expected TypeScript type after parsing\n * @template Input - The input type for the BCS parser (usually the same as T)\n *\n * @param result - The DevInspectResults object from a Sui devInspect call\n * @param bcsType - The BCS parser to use for deserializing the bytes\n * @param resultIndex - The index of the result to parse (defaults to 0)\n * @param returnValueIndex - The index of the return value within the result (defaults to 0)\n *\n * @returns The parsed value of type T\n *\n * @throws {InvalidObjectError} When no bytes are found at the specified indices\n * @throws {ParseError} When BCS parsing fails due to malformed data\n *\n * @example\n * ```typescript\n * // Parse a u64 return value\n * const result = await suiClient.devInspectTransactionBlock({...});\n * const balance = parseDevInspectResult(result, bcs.u64());\n *\n * // Parse a custom struct\n * const PriceInfo = bcs.struct('PriceInfo', {\n * price: bcs.u64(),\n * timestamp: bcs.u64(),\n * });\n * const priceInfo = parseDevInspectResult(result, PriceInfo);\n *\n * // Parse from a specific return value\n * const secondReturnValue = parseDevInspectResult(result, bcs.string(), 0, 1);\n * ```\n */\nexport const parseDevInspectResult = <T, Input>(\n result: DevInspectResults,\n bcsType: BcsType<T, Input>,\n resultIndex: number = 0,\n returnValueIndex: number = 0\n): T => {\n const bytes = extractBytes(result, resultIndex, returnValueIndex);\n if (!bytes) {\n throw new InvalidObjectError('When trying to parse result, no bytes found', {\n bcsType,\n resultIndex,\n returnValueIndex,\n });\n }\n\n try {\n return bcsType.parse(bytes);\n } catch (error) {\n throw new ParseError('DevInspectResult', 'from bcs to a typescript type', {\n error,\n result,\n bcsType,\n resultIndex,\n returnValueIndex,\n });\n }\n};\n\n/**\n * Parses multiple return values from a DevInspectResults object using an array of BCS parsers.\n *\n * This function is useful when a Move function returns multiple values that need to be\n * parsed with different BCS types. It applies each parser in the schema array to the\n * corresponding return value index.\n *\n * @template T - A tuple type representing the array of BCS parsers\n *\n * @param info - The DevInspectResults object from a Sui devInspect call\n * @param schema - An array of BCS parsers, one for each expected return value\n *\n * @returns A tuple containing the parsed values, with types matching the schema\n *\n * @example\n * ```typescript\n * // Parse multiple return values of different types\n * const result = await suiClient.devInspectTransactionBlock({...});\n * const [balance, isActive, userName] = parseMultipleResults(\n * result,\n * [bcs.u64(), bcs.bool(), bcs.string()] as const\n * );\n *\n * // Parse multiple complex types\n * const TokenInfo = bcs.struct('TokenInfo', {\n * symbol: bcs.string(),\n * decimals: bcs.u8(),\n * });\n * const [tokenA, tokenB, liquidityAmount] = parseMultipleResults(\n * result,\n * [TokenInfo, TokenInfo, bcs.u128()] as const\n * );\n * ```\n *\n * @remarks\n * - The function assumes all return values are from the first result (index 0)\n * - Each parser in the schema array corresponds to a return value at the same index\n * - Type safety is preserved through TypeScript's tuple types\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const parseMultipleResults = <T extends readonly BcsType<any>[]>(\n info: DevInspectResults,\n schema: T\n): { [K in keyof T]: BcsParsed<T[K]> } => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return schema.map((bcsType, index) => parseDevInspectResult(info, bcsType, 0, index)) as {\n [K in keyof T]: BcsParsed<T[K]>;\n };\n};\n","import { InsufficientFundsError, MissingParameterError } from '@bolt-liquidity-hq/core';\nimport type { SuiClient, PaginatedCoins, CoinStruct } from '@mysten/sui/client';\nimport type { Argument, Transaction } from '@mysten/sui/transactions';\nimport { SUI_TYPE_ARG } from '@mysten/sui/utils';\n\n/**\n * Configuration options for coin selection algorithms.\n *\n * These options control how the CoinManager selects coins when preparing\n * transactions, allowing optimization for different scenarios.\n */\nexport interface CoinSelectionOptions {\n /**\n * Array of coin object IDs to exclude from selection.\n * Useful for avoiding coins that are locked or reserved for other transactions.\n *\n * @example [\"0x123...\", \"0x456...\"]\n */\n excludeIds?: string[];\n\n /**\n * When true, prefers merging multiple coins even if a single coin could cover the amount.\n * This can help consolidate fragmented coin holdings.\n *\n * @default false\n */\n preferMerge?: boolean;\n\n /**\n * When true, uses the minimum number of coins needed to cover the amount.\n * This preserves coin count but may use larger denominations.\n *\n * @default false\n */\n minimizeInputs?: boolean;\n\n /**\n * When true, allows returning a partial amount if insufficient funds.\n * The result will contain all available coins even if they don't meet the target.\n *\n * @default false\n */\n allowPartial?: boolean;\n}\n\n/**\n * Result of the coin selection process.\n *\n * Contains the selected coins and metadata about what operations\n * are needed to prepare them for the transaction.\n */\nexport interface CoinSelectionResult {\n /**\n * Array of selected coin objects that will be used in the transaction.\n */\n coins: CoinStruct[];\n\n /**\n * Total balance of all selected coins as a string.\n * May exceed the requested amount if exact change isn't available.\n */\n totalBalance: string;\n\n /**\n * Whether the selected coins need to be merged into a single coin.\n * True when multiple coins are selected.\n */\n requiresMerge: boolean;\n\n /**\n * Whether the resulting coin needs to be split to get the exact amount.\n * True when totalBalance exceeds the requested amount.\n */\n requiresSplit: boolean;\n}\n\n/**\n * Manages coin selection and preparation for Sui transactions.\n *\n * The CoinManager class provides utilities for working with coins on the Sui blockchain,\n * including fetching balances, selecting optimal coins for transactions, and preparing\n * coin inputs with automatic merging and splitting as needed.\n *\n * @example\n * ```typescript\n * const coinManager = new CoinManager(suiClient, userAddress);\n *\n * // Get total balance\n * const balance = await coinManager.getTotalBalance(\n * \"0x2::sui::SUI\"\n * );\n *\n * // Select coins for a transaction\n * const selection = await coinManager.selectCoins(\n * \"0x2::sui::SUI\",\n * \"1000000000\", // 1 SUI\n * { minimizeInputs: true }\n * );\n *\n * // Prepare coin input for transaction\n * const tx = new Transaction();\n * const coinInput = await coinManager.prepareCoinInput(\n * tx,\n * \"0x2::sui::SUI\",\n * \"1000000000\"\n * );\n * ```\n *\n * @group Helpers\n */\nexport class CoinManager {\n /**\n * Creates a new CoinManager instance.\n *\n * @param client - The SuiClient instance for blockchain interactions\n * @param defaultOwner - Optional default owner address for coin operations.\n * If not provided, owner must be specified in each method call.\n *\n * @example\n * ```typescript\n * // With default owner\n * const coinManager = new CoinManager(suiClient, \"0x123...\");\n *\n * // Without default owner (must specify in each call)\n * const coinManager = new CoinManager(suiClient);\n * ```\n */\n constructor(\n private client: SuiClient,\n private defaultOwner?: string\n ) {}\n\n /**\n * Fetches all coins of a specific type owned by an address.\n *\n * This method handles pagination automatically to retrieve all coins,\n * regardless of how many exist. Coins are returned in the order\n * provided by the blockchain.\n *\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @returns A promise that resolves to an array of all coins of the specified type\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n *\n * @example\n * ```typescript\n * // Get all SUI coins\n * const suiCoins = await coinManager.getAllCoins(\"0x2::sui::SUI\");\n * console.log(`Found ${suiCoins.length} SUI coins`);\n *\n * // Get all USDC coins for a specific owner\n * const usdcCoins = await coinManager.getAllCoins(\n * \"0x5d4b...::coin::COIN\",\n * \"0xowner...\"\n * );\n *\n * // Display coin details\n * suiCoins.forEach(coin => {\n * console.log(`Coin ID: ${coin.coinObjectId}`);\n * console.log(`Balance: ${coin.balance}`);\n * });\n * ```\n */\n async getAllCoins(coinType: string, owner?: string): Promise<CoinStruct[]> {\n const ownerAddress = this.getOwnerAddress(owner);\n\n // Fetch all coins with pagination\n const allCoins: CoinStruct[] = [];\n let cursor: string | undefined | null;\n\n do {\n const response: PaginatedCoins = await this.client.getCoins({\n owner: ownerAddress,\n coinType,\n cursor,\n });\n\n allCoins.push(...response.data);\n cursor = response.hasNextPage ? response.nextCursor : undefined;\n } while (cursor);\n\n return allCoins;\n }\n\n /**\n * Resolves the owner address from the provided parameter or default.\n *\n * This is a helper method used internally to ensure an owner address\n * is always available for coin operations.\n *\n * @param owner - Optional owner address to use\n *\n * @returns The resolved owner address\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n *\n * @example\n * ```typescript\n * // With default owner set\n * const address = coinManager.getOwnerAddress(); // Returns defaultOwner\n *\n * // With explicit owner\n * const address = coinManager.getOwnerAddress(\"0x123...\"); // Returns \"0x123...\"\n *\n * // Without default owner or parameter\n * const address = coinManager.getOwnerAddress(); // Throws MissingParameterError\n * ```\n */\n getOwnerAddress(owner?: string): string {\n const address = owner || this.defaultOwner;\n if (!address) throw new MissingParameterError('owner');\n\n return address;\n }\n\n /**\n * Gets the total balance of a specific coin type for an owner.\n *\n * This method returns the sum of all coins of the specified type,\n * providing a quick way to check if sufficient funds are available\n * without fetching all coin objects.\n *\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @returns A promise that resolves to the total balance as a string\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n *\n * @example\n * ```typescript\n * // Get SUI balance\n * const suiBalance = await coinManager.getTotalBalance(\"0x2::sui::SUI\");\n * console.log(`Total SUI: ${suiBalance}`);\n *\n * // Get USDC balance for specific owner\n * const usdcBalance = await coinManager.getTotalBalance(\n * \"0x5d4b...::coin::COIN\",\n * \"0xowner...\"\n * );\n *\n * // Convert to decimal for display (assuming 9 decimals for SUI)\n * const suiDecimal = Number(suiBalance) / 1e9;\n * console.log(`${suiDecimal} SUI`);\n * ```\n */\n async getTotalBalance(coinType: string, owner?: string): Promise<string> {\n const ownerAddress = this.getOwnerAddress(owner);\n\n const balance = await this.client.getBalance({\n owner: ownerAddress,\n coinType,\n });\n\n return balance.totalBalance;\n }\n\n /**\n * Asserts that the owner has sufficient balance for a transaction.\n *\n * This is a convenience method that checks the balance and throws\n * a descriptive error if insufficient. Useful for fail-fast validation\n * before attempting complex transaction preparation.\n *\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param amount - The required amount as a string\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n * @throws {InsufficientFundsError} When the balance is less than the required amount\n *\n * @example\n * ```typescript\n * try {\n * // Check if user has 1 SUI\n * await coinManager.assertEnoughBalance(\n * \"0x2::sui::SUI\",\n * \"1000000000\" // 1 SUI\n * );\n *\n * // Proceed with transaction\n * console.log(\"Sufficient balance confirmed\");\n * } catch (error) {\n * if (error instanceof InsufficientFundsError) {\n * console.error(`Need ${error.data.amount}, but only have ${error.data.available}`);\n * }\n * }\n * ```\n */\n async assertEnoughBalance(coinType: string, amount: string, owner?: string): Promise<void> {\n const ownerAddress = this.getOwnerAddress(owner);\n\n const totalBalance = await this.getTotalBalance(coinType, owner);\n\n if (BigInt(totalBalance) < BigInt(amount)) {\n throw new InsufficientFundsError(amount, totalBalance, { coinType, amount, ownerAddress });\n }\n }\n\n /**\n * Selects optimal coins to cover a specific amount.\n *\n * This method implements intelligent coin selection algorithms that consider\n * various factors like minimizing inputs, preserving large coins, and\n * avoiding fragmentation. It determines whether merging or splitting is needed.\n *\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param amount - The target amount to select for, as a string\n * @param options - Configuration options for the selection algorithm\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @returns A promise that resolves to a CoinSelectionResult with selected coins and metadata\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n * @throws {InsufficientFundsError} When available coins cannot cover the amount (unless allowPartial is true)\n *\n * @example\n * ```typescript\n * // Basic selection\n * const selection = await coinManager.selectCoins(\n * \"0x2::sui::SUI\",\n * \"1000000000\" // 1 SUI\n * );\n *\n * if (selection.requiresMerge) {\n * console.log(`Need to merge ${selection.coins.length} coins`);\n * }\n * if (selection.requiresSplit) {\n * console.log(`Need to split coin for exact amount`);\n * }\n *\n * // Minimize number of inputs\n * const minimalSelection = await coinManager.selectCoins(\n * \"0x2::sui::SUI\",\n * \"5000000000\",\n * { minimizeInputs: true }\n * );\n *\n * // Exclude specific coins and allow partial\n * const partialSelection = await coinManager.selectCoins(\n * \"0x2::sui::SUI\",\n * \"10000000000\",\n * {\n * excludeIds: [\"0x123...\"],\n * allowPartial: true\n * }\n * );\n * ```\n *\n * @remarks\n * The selection algorithm follows these priorities:\n * 1. Exact match - single coin with exact amount\n * 2. Single coin that covers amount (requires split)\n * 3. Multiple coins (requires merge, possibly split)\n *\n * When minimizeInputs is false, smaller coins are used first to preserve larger ones.\n */\n async selectCoins(\n coinType: string,\n amount: string,\n options: CoinSelectionOptions = {},\n owner?: string\n ): Promise<CoinSelectionResult> {\n const ownerAddress = this.getOwnerAddress(owner);\n const coins = await this.getAllCoins(coinType, owner);\n\n // Filter out excluded coins\n const availableCoins = options.excludeIds\n ? coins.filter((c) => !options.excludeIds?.includes(c.coinObjectId))\n : coins;\n\n if (availableCoins.length === 0) {\n throw new InsufficientFundsError(amount, '0', {\n availableCoins,\n coinType,\n ownerAddress,\n });\n }\n\n const targetAmount = BigInt(amount);\n\n // Sort by balance (largest first)\n availableCoins.sort((a, b) => {\n const diff = BigInt(b.balance) - BigInt(a.balance);\n return diff > 0n ? 1 : diff < 0n ? -1 : 0;\n });\n\n // Check for exact match\n const exactMatch = availableCoins.find((c) => BigInt(c.balance) === targetAmount);\n if (exactMatch) {\n return {\n coins: [exactMatch],\n totalBalance: amount,\n requiresMerge: false,\n requiresSplit: false,\n };\n }\n\n // Check for single coin that can cover amount\n const singleCoin = availableCoins.find((c) => BigInt(c.balance) > targetAmount);\n if (singleCoin && !options.preferMerge) {\n return {\n coins: [singleCoin],\n totalBalance: singleCoin.balance,\n requiresMerge: false,\n requiresSplit: true,\n };\n }\n\n // Need multiple coins\n const selectedCoins: CoinStruct[] = [];\n let totalBalance = 0n;\n\n if (options.minimizeInputs) {\n // Try to minimize number of coins used\n for (const coin of availableCoins) {\n selectedCoins.push(coin);\n totalBalance += BigInt(coin.balance);\n if (totalBalance >= targetAmount) break;\n }\n } else {\n // Use smallest coins first to preserve larger coins\n const sortedAsc = [...availableCoins].sort((a, b) => {\n const diff = BigInt(a.balance) - BigInt(b.balance);\n return diff > 0n ? 1 : diff < 0n ? -1 : 0;\n });\n\n for (const coin of sortedAsc) {\n if (totalBalance >= targetAmount) break;\n selectedCoins.push(coin);\n totalBalance += BigInt(coin.balance);\n }\n }\n\n // Check if we have enough\n if (totalBalance < targetAmount) {\n if (options.allowPartial) {\n return {\n coins: selectedCoins,\n totalBalance: totalBalance.toString(),\n requiresMerge: selectedCoins.length > 1,\n requiresSplit: false,\n };\n }\n\n throw new InsufficientFundsError(amount, totalBalance.toString(), {\n amount,\n coinType,\n totalBalance: totalBalance.toString(),\n ownerAddress,\n });\n }\n\n return {\n coins: selectedCoins,\n totalBalance: totalBalance.toString(),\n requiresMerge: selectedCoins.length > 1,\n requiresSplit: totalBalance > targetAmount,\n };\n }\n\n /**\n * Prepares a coin input for a transaction with automatic merging and splitting.\n *\n * This is the main method for transaction preparation. It handles all the complexity\n * of coin selection, merging multiple coins if needed, and splitting for exact amounts.\n * Special handling is provided for SUI gas coins.\n *\n * @param tx - The Transaction object to add coin operations to\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param amount - The exact amount needed for the transaction, as a string\n * @param options - Configuration options for coin selection\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @returns A promise that resolves to an Argument that can be used in Move calls\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n * @throws {InsufficientFundsError} When available coins cannot cover the amount\n *\n * @example\n * ```typescript\n * const tx = new Transaction();\n *\n * // Prepare exact SUI amount (uses gas coin)\n * const suiCoin = await coinManager.prepareCoinInput(\n * tx,\n * \"0x2::sui::SUI\",\n * \"1000000000\" // 1 SUI\n * );\n *\n * // Prepare custom coin with options\n * const customCoin = await coinManager.prepareCoinInput(\n * tx,\n * \"0x5d4b...::coin::COIN\",\n * \"1000000\", // 1 USDC\n * {\n * minimizeInputs: true,\n * excludeIds: [\"0x123...\"]\n * }\n * );\n *\n * // Use in a Move call\n * tx.moveCall({\n * target: `${packageId}::module::swap`,\n * arguments: [suiCoin, customCoin],\n * });\n * ```\n *\n * @remarks\n * - SUI coins are handled specially by splitting from the gas coin\n * - Single coins matching the exact amount are used directly\n * - Multiple coins are automatically merged\n * - Coins with excess balance are automatically split\n * - The resulting Argument can be used directly in Move calls\n */\n async prepareCoinInput(\n tx: Transaction,\n coinType: string,\n amount: string,\n options: CoinSelectionOptions = {},\n owner?: string\n ): Promise<Argument> {\n const ownerAddress = this.getOwnerAddress(owner);\n\n // Handle SUI specially\n if (coinType === SUI_TYPE_ARG) {\n const [coin] = tx.splitCoins(tx.gas, [amount]);\n return coin;\n }\n\n // Select coins\n const selection = await this.selectCoins(coinType, amount, options, owner);\n\n if (!selection.coins[0]) {\n throw new InsufficientFundsError(amount, '0', {\n coinType,\n amount,\n ownerAddress,\n });\n }\n\n // Single coin, exact amount\n if (selection.coins.length === 1 && !selection.requiresSplit) {\n return tx.object(selection.coins[0].coinObjectId);\n }\n\n // Single coin, needs split\n if (selection.coins.length === 1 && selection.requiresSplit) {\n const [split] = tx.splitCoins(tx.object(selection.coins[0].coinObjectId), [amount]);\n return split;\n }\n\n // Multiple coins, need merge\n const primaryCoin = tx.object(selection.coins[0].coinObjectId);\n const mergeCoins = selection.coins.slice(1).map((c) => tx.object(c.coinObjectId));\n\n tx.mergeCoins(primaryCoin, mergeCoins);\n\n // Split if needed\n if (selection.requiresSplit) {\n const [split] = tx.splitCoins(primaryCoin, [amount]);\n return split;\n }\n\n return primaryCoin;\n }\n}\n","import { type Address, TransactionFailedError, UnexpectedError } from '@bolt-liquidity-hq/core';\nimport type { SerializedBcs } from '@mysten/bcs';\nimport type { DevInspectResults, SuiClient } from '@mysten/sui/client';\nimport { Transaction } from '@mysten/sui/transactions';\n\nimport { ZERO_ADDRESS } from '../constants';\n\n/**\n * Executes a read-only query against a Sui Move function using devInspect.\n *\n * This function allows you to call Move functions without committing a transaction\n * to the blockchain. It's perfect for querying contract state, simulating transactions,\n * or getting computed values from view functions. The devInspect feature runs the\n * transaction in a sandboxed environment and returns the results without any state changes.\n *\n * @param suiClient - The SuiClient instance used to interact with the Sui network\n * @param target - The Move function to call, either as:\n * - A string in the format \"packageId::module::function\"\n * - A tuple of [packageId, module, function]\n * @param args - Optional array of arguments to pass to the Move function. Each argument can be:\n * - A string representing an object ID (will be passed as an object reference)\n * - A SerializedBcs object containing pre-serialized BCS data (will be passed as a pure value)\n * @param typeArguments - Optional array of type arguments for generic Move functions\n * @param senderAddress - Optional sender address for the simulated transaction.\n * Defaults to ZERO_ADDRESS if not provided. Some functions may require a specific\n * sender to check permissions or balances.\n *\n * @returns A promise that resolves to DevInspectResults containing:\n * - effects: Transaction effects showing gas costs and object changes\n * - events: Events that would be emitted by the transaction\n * - results: Array of results with return values from the Move function\n * - error: Any execution errors (if status is not 'success')\n *\n * @throws {TransactionFailedError} When the Move function execution fails\n * @throws {UnexpectedError} When there's a network error or other unexpected failure\n *\n * @example\n * ```typescript\n * // Query a simple getter function\n * const result = await queryDevInspect(\n * suiClient,\n * `${packageId}::oracle::get_price`,\n * [baseAssetId, quoteAssetId]\n * );\n *\n * // Query with type arguments\n * const balanceResult = await queryDevInspect(\n * suiClient,\n * [packageId, \"pool\", \"get_balance\"],\n * [poolObjectId],\n * [\"0x2::sui::SUI\"] // Type argument for the coin type\n * );\n *\n * // Query with serialized BCS arguments\n * const amountBcs = bcs.u64().serialize(1000000).toBytes();\n * const swapResult = await queryDevInspect(\n * suiClient,\n * `${packageId}::router::get_amount_out`,\n * [amountBcs, poolObjectId],\n * undefined,\n * userAddress // Use actual user address for more specific simulation\n * );\n *\n * // Parse the results\n * if (result.effects.status.status === 'success') {\n * const returnValue = result.results?.[0]?.returnValues?.[0];\n * if (returnValue) {\n * const price = bcs.u64().parse(new Uint8Array(returnValue[0]));\n * }\n * }\n * ```\n *\n * @remarks\n * - devInspect is read-only and cannot modify blockchain state\n * - Gas is still calculated but not charged\n * - Object modifications are simulated but not persisted\n * - Some functions may behave differently in devInspect vs actual execution\n * - The ZERO_ADDRESS default sender may not work for functions that check ownership\n */\nexport const queryDevInspect = async (\n suiClient: SuiClient,\n target: string | [string, string, string],\n args?: (SerializedBcs<unknown> | string)[],\n typeArguments?: string[],\n senderAddress?: Address\n): Promise<DevInspectResults> => {\n const tx = new Transaction();\n\n const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;\n\n const txArgs = args?.map((item) =>\n typeof item === 'string' ? tx.object(item) : tx.pure(item.toBytes())\n );\n\n tx.moveCall({\n target: targetString,\n arguments: txArgs,\n typeArguments,\n });\n\n try {\n // Use devInspectTransactionBlock to execute without submitting to chain\n const result = await suiClient.devInspectTransactionBlock({\n transactionBlock: tx,\n sender: senderAddress ?? ZERO_ADDRESS,\n });\n\n // Process the results\n if (result.effects.status.status === 'success') {\n return result;\n } else {\n throw new TransactionFailedError('N/A', 'Failed to query smart contract', { result });\n }\n } catch (error) {\n throw UnexpectedError.from(error, 'Failed to query smart contract', {\n target: targetString,\n args,\n typeArguments,\n });\n }\n};\n","import {\n type Coin,\n DEFAULT_GAS_ADJUSTMENT,\n TransactionFailedError,\n UnexpectedError,\n} from '@bolt-liquidity-hq/core';\nimport type { SerializedBcs } from '@mysten/bcs';\nimport type {\n SuiClient,\n SuiTransactionBlockResponse,\n SuiTransactionBlockResponseOptions,\n} from '@mysten/sui/client';\nimport type { Signer } from '@mysten/sui/cryptography';\nimport { Transaction, type TransactionArgument } from '@mysten/sui/transactions';\nimport { SUI_TYPE_ARG } from '@mysten/sui/utils';\nimport { BigNumber } from 'bignumber.js';\n\n/**\n * Signs and executes a transaction on the Sui blockchain.\n *\n * This function builds, signs, and submits a transaction to the Sui network. It provides\n * a convenient wrapper around the Sui SDK's transaction building and execution flow,\n * handling argument serialization and error cases. The function supports calling any\n * Move function on Sui with proper type arguments and parameters.\n *\n * @param suiClient - The SuiClient instance used to interact with the Sui network\n * @param signer - The Signer instance (e.g., Ed25519Keypair) used to sign the transaction\n * @param target - The Move function to call, either as:\n * - A string in the format \"packageId::module::function\"\n * - A tuple of [packageId, module, function]\n * @param args - Optional array of arguments to pass to the Move function. Each argument can be:\n * - A string representing an object ID (will be passed as an object reference)\n * - A SerializedBcs object containing pre-serialized BCS data (will be passed as a pure value)\n * - A TransactionArgument created by the Transaction builder\n * @param typeArguments - Optional array of type arguments for generic Move functions.\n * These are fully qualified type names like \"0x2::sui::SUI\"\n * @param transaction - Optional pre-existing Transaction object to add the Move call to.\n * If not provided, a new Transaction will be created.\n * @param options - Optional response options to specify what data to include in the response\n * (e.g., effects, events, object changes, balance changes)\n *\n * @returns A promise that resolves to SuiTransactionBlockResponse containing:\n * - digest: The transaction digest (hash)\n * - effects: Transaction effects showing gas costs, created/modified/deleted objects\n * - events: Events emitted during transaction execution\n * - objectChanges: Detailed changes to objects (if requested in options)\n * - balanceChanges: Changes to coin balances (if requested in options)\n *\n * @throws {TransactionFailedError} When the Move function execution fails on-chain\n * @throws {UnexpectedError} When there's a network error, signing error, or other unexpected failure\n *\n * @example\n * ```typescript\n * // Simple transfer\n * const result = await signAndExecuteTx(\n * suiClient,\n * keypair,\n * '0x2::coin::transfer',\n * [coinObjectId, recipientAddress],\n * ['0x2::sui::SUI']\n * );\n *\n * // Call a swap function with serialized amount\n * const amountBcs = bcs.u64().serialize(1000000).toBytes();\n * const swapResult = await signAndExecuteTx(\n * suiClient,\n * keypair,\n * [packageId, 'pool', 'swap'],\n * [poolObjectId, amountBcs],\n * ['0x2::sui::SUI', `${packageId}::usdc::USDC`],\n * undefined,\n * {\n * showEffects: true,\n * showEvents: true,\n * showObjectChanges: true\n * }\n * );\n *\n * // Build a complex transaction\n * const tx = new Transaction();\n * const [coin] = tx.splitCoins(tx.gas, [1000000]);\n * await signAndExecuteTx(\n * suiClient,\n * keypair,\n * `${packageId}::market::place_order`,\n * [marketId, coin, tx.pure.u64(price)],\n * undefined,\n * tx // Pass the existing transaction\n * );\n *\n * // Handle the response\n * if (result.effects?.status.status === 'success') {\n * console.log('Transaction successful:', result.digest);\n * console.log('Gas used:', result.effects.gasUsed);\n *\n * // Process created objects\n * result.effects.created?.forEach(obj => {\n * console.log('Created object:', obj.reference.objectId);\n * });\n * }\n * ```\n *\n * @remarks\n * - The transaction is executed immediately and state changes are permanent\n * - Gas fees are charged based on computation and storage costs\n * - The signer must have sufficient SUI balance to pay for gas\n * - Object references must exist and be owned by the signer (for owned objects)\n * - Shared objects can be accessed by any transaction but may require consensus\n * - The function automatically handles BCS serialization for SerializedBcs arguments\n * - Failed transactions still consume gas fees\n */\nexport const signAndExecuteTx = async (\n suiClient: SuiClient,\n signer: Signer,\n target: string | [string, string, string],\n args?: (TransactionArgument | SerializedBcs<unknown> | string)[],\n typeArguments?: string[],\n transaction?: Transaction,\n options?: SuiTransactionBlockResponseOptions\n): Promise<SuiTransactionBlockResponse> => {\n const tx = transaction ?? new Transaction();\n\n const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;\n\n const txArgs = args?.map((item) =>\n typeof item === 'string' ? tx.object(item) : 'toBytes' in item ? tx.pure(item.toBytes()) : item\n );\n\n tx.moveCall({\n target: targetString,\n arguments: txArgs,\n typeArguments,\n });\n\n try {\n const result = await suiClient.signAndExecuteTransaction({\n signer,\n transaction: tx,\n options,\n });\n\n if (result.effects?.status.status === 'success') {\n return result;\n } else {\n throw new TransactionFailedError(result.digest, result.effects?.status.error, { result });\n }\n } catch (error) {\n throw UnexpectedError.from(error, 'Failed to execute transaction', {\n target: targetString,\n args,\n typeArguments,\n });\n }\n};\n\n/**\n * Estimates the gas price for a transaction on the Sui blockchain.\n *\n * This function builds a transaction and performs a dry run to estimate gas costs\n * without actually executing the transaction on-chain. It returns the gas denomination\n * (always 'SUI' for Sui network) and the estimated amount including the gas adjustment\n * multiplier.\n *\n * @param suiClient - The SuiClient instance used to interact with the Sui network\n * @param target - The Move function to call, either as:\n * - A string in the format \"packageId::module::function\"\n * - A tuple of [packageId, module, function]\n * @param args - Optional array of arguments to pass to the Move function. Each argument can be:\n * - A string representing an object ID (will be passed as an object reference)\n * - A SerializedBcs object containing pre-serialized BCS data (will be passed as a pure value)\n * - A TransactionArgument created by the Transaction builder\n * @param typeArguments - Optional array of type arguments for generic Move functions.\n * These are fully qualified type names like \"0x2::sui::SUI\"\n * @param transaction - Optional pre-existing Transaction object to add the Move call to.\n * If not provided, a new Transaction will be created.\n * @param gasAdjustment - Optional multiplier for gas estimation (default: 1.5). Use higher values for\n * safety margin. For example, 1.5 means 50% buffer above estimated gas.\n *\n * @returns A promise that resolves to an object containing:\n * - denom: The gas denomination (always 'SUI' for Sui network)\n * - amount: The estimated gas amount as a string, including the gas adjustment\n *\n * @throws {UnexpectedError} When there's a network error or dry run fails\n *\n * @example\n * ```typescript\n * // Estimate gas for a simple transfer\n * const gasEstimate = await estimateGasPrice(\n * suiClient,\n * keypair,\n * '0x2::coin::transfer',\n * [coinObjectId, recipientAddress],\n * ['0x2::sui::SUI']\n * );\n * console.log(`Estimated gas: ${gasEstimate.amount} ${gasEstimate.denom}`);\n *\n * // Estimate with higher safety margin\n * const safeGasEstimate = await estimateGasPrice(\n * suiClient,\n * keypair,\n * [packageId, 'pool', 'swap'],\n * [poolObjectId, amountBcs],\n * ['0x2::sui::SUI', `${packageId}::usdc::USDC`],\n * 1.5 // 50% buffer\n * );\n *\n * // Use with existing transaction\n * const tx = new Transaction();\n * const [coin] = tx.splitCoins(tx.gas, [1000000]);\n * const gasPrice = await estimateGasPrice(\n * suiClient,\n * keypair,\n * `${packageId}::market::place_order`,\n * [marketId, coin, tx.pure.u64(price)],\n * undefined,\n * 1.2,\n * tx\n * );\n * ```\n *\n * @remarks\n * - This function performs a dry run, so no state changes occur\n * - The estimation includes computation units, storage costs, and storage rebates\n * - Gas prices on Sui can vary based on network congestion\n * - The gasAdjustment parameter helps account for potential variations\n * - Always ensure sufficient balance for the estimated gas plus transaction amount\n * - For shared objects, gas costs may be higher due to consensus requirements\n */\nexport const estimateTxGasPrice = async (\n suiClient: SuiClient,\n target: string | [string, string, string],\n args?: (TransactionArgument | SerializedBcs<unknown> | string)[],\n typeArguments?: string[],\n transaction?: Transaction,\n gasAdjustment: number = DEFAULT_GAS_ADJUSTMENT\n): Promise<Coin | undefined> => {\n const tx = transaction ?? new Transaction();\n\n const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;\n\n const txArgs = args?.map((item) =>\n typeof item === 'string' ? tx.object(item) : 'toBytes' in item ? tx.pure(item.toBytes()) : item\n );\n\n tx.moveCall({\n target: targetString,\n arguments: txArgs,\n typeArguments,\n });\n\n try {\n // Build the transaction\n const transactionBytes = await tx.build({ client: suiClient });\n\n // Perform dry run to estimate gas\n const dryRunResult = await suiClient.dryRunTransactionBlock({\n transactionBlock: transactionBytes,\n });\n\n if (dryRunResult.effects.status.status !== 'success') {\n throw new UnexpectedError(\n `Dry run failed: ${dryRunResult.effects.status.error}`,\n 'Failed to estimate gas',\n {\n target: targetString,\n args,\n typeArguments,\n error: dryRunResult.effects.status.error,\n }\n );\n }\n\n // Extract gas information from the dry run result\n const gasUsed = dryRunResult.effects.gasUsed;\n\n // Calculate total gas cost (computation + storage - storage rebate)\n const totalGasCost = BigNumber(gasUsed.computationCost)\n .plus(gasUsed.storageCost)\n .minus(gasUsed.storageRebate);\n\n // Apply gas adjustment multiplier\n const adjustedGasCost = totalGasCost.times(gasAdjustment);\n\n return {\n denom: SUI_TYPE_ARG,\n amount: adjustedGasCost.toFixed(0, BigNumber.ROUND_CEIL),\n };\n } catch {\n return;\n }\n};\n","import type {\n InvertiblePrice,\n OracleConfig,\n OracleAssetPair,\n Price,\n} from '@bolt-liquidity-hq/core';\nimport { InvalidObjectError } from '@bolt-liquidity-hq/core';\nimport { BigNumber } from 'bignumber.js';\n\nimport type {\n AssetPairsResponsePaginatedStructOutput,\n AssetPairsResponseStructOutput,\n AssetPairStructOutput,\n OracleConfigStructOutput,\n PriceDataStructOutput,\n PriceResponseStructOutput,\n PricesResponsePaginatedStructOutput,\n} from '../../types';\n\n/**\n * Parses a raw oracle configuration response from the Sui blockchain into a structured OracleConfig object.\n *\n * This function transforms the snake_case properties from the Sui Move contract response\n * into camelCase properties following TypeScript conventions. It also converts the\n * price expiry time from seconds to a structured format with seconds and nanoseconds.\n *\n * @param output - The raw oracle configuration response from the contract query\n * @param output.admin - The admin address that can update oracle prices\n * @param output.price_threshold_ratio - The maximum allowed price deviation ratio\n * @param output.default_price_expiry_seconds - The default time in seconds before prices expire\n *\n * @returns A parsed OracleConfig object with:\n * - admin: The admin address of the oracle contract\n * - priceThresholdRatio: The threshold ratio for price updates (e.g., \"0.01\" for 1%)\n * - priceExpireTime: Object with seconds and nanoseconds representing expiry duration\n *\n * @example\n * ```typescript\n * const output = {\n * admin: \"0x1234...\",\n * price_threshold_ratio: \"0.01\",\n * default_price_expiry_seconds: \"3600\" // 1 hour\n * };\n *\n * const config = parseOracleConfigStructOutput(output);\n * console.log(config.admin); // \"0x1234...\"\n * console.log(config.priceThresholdRatio); // \"0.01\"\n * console.log(config.priceExpireTime.secs); // 3600\n * ```\n */\nexport const parseOracleConfigStructOutput = (output: OracleConfigStructOutput): OracleConfig => {\n return {\n admin: output.admin,\n priceThresholdRatio: output.price_threshold_ratio,\n priceExpireTime: {\n secs: Number(output.default_price_expiry_seconds),\n nanos: 0,\n },\n };\n};\n\n/**\n * Parses a single asset pair structure from the Sui oracle contract into an OracleAssetPair object.\n *\n * This function converts the raw asset pair data containing base and quote asset information\n * into a structured format. Note that the name field is currently set to the same value\n * as the symbol field in the Sui implementation.\n *\n * @param output - The raw asset pair data from the contract\n * @param output.base_symbol - The symbol of the base asset (e.g., \"SUI\", \"USDC\")\n * @param output.base_precision - The decimal precision of the base asset (e.g., 9 for SUI)\n * @param output.quote_symbol - The symbol of the quote asset\n * @param output.quote_precision - The decimal precision of the quote asset\n *\n * @returns An OracleAssetPair object containing:\n * - base: Object with name, symbol, and precision for the base asset\n * - quote: Object with name, symbol, and precision for the quote asset\n *\n * @example\n * ```typescript\n * const rawPair = {\n * base_symbol: \"SUI\",\n * base_precision: 9,\n * quote_symbol: \"USDC\",\n * quote_precision: 6\n * };\n *\n * const pair = parseAssetPairStructOutput(rawPair);\n * console.log(pair.base.symbol); // \"SUI\"\n * console.log(pair.base.precision); // 9\n * console.log(pair.quote.symbol); // \"USDC\"\n * ```\n */\nexport const parseAssetPairStructOutput = (output: AssetPairStructOutput): OracleAssetPair => {\n return {\n base: {\n name: output.base_symbol,\n symbol: output.base_symbol,\n precision: output.base_precision,\n },\n quote: {\n name: output.quote_symbol,\n symbol: output.quote_symbol,\n precision: output.quote_precision,\n },\n };\n};\n\n/**\n * Parses a response containing multiple asset pairs from the oracle contract.\n *\n * This function processes an array of asset pairs returned by the oracle's\n * get_asset_pairs query, converting each raw pair into the standardized format.\n *\n * @param output - The response object containing an array of asset pairs\n * @param output.asset_pairs - Array of raw asset pair data\n *\n * @returns An array of parsed OracleAssetPair objects\n *\n * @example\n * ```typescript\n * const output = {\n * asset_pairs: [\n * { base_symbol: \"SUI\", base_precision: 9, quote_symbol: \"USDC\", quote_precision: 6 },\n * { base_symbol: \"ETH\", base_precision: 18, quote_symbol: \"USDC\", quote_precision: 6 }\n * ]\n * };\n *\n * const pairs = parseAssetPairsResponseStructOutput(output);\n * console.log(pairs.length); // 2\n * console.log(pairs[0].base.symbol); // \"SUI\"\n * ```\n */\nexport const parseAssetPairsResponseStructOutput = (\n output: AssetPairsResponseStructOutput\n): OracleAssetPair[] => {\n return output.asset_pairs.map((item) => parseAssetPairStructOutput(item));\n};\n\n/**\n * Parses raw price data from the oracle contract into an InvertiblePrice object.\n *\n * This function converts the price information including the price value and expiry time.\n * The expiry time is converted from milliseconds to nanoseconds for consistency with\n * the broader system's time representation.\n *\n * @param output - The raw price data from the contract\n * @param output.price - The price value as a string (to maintain precision)\n * @param output.expiry_time_ms - The price expiry time in milliseconds since Unix epoch\n * @param baseDenom - The denomination of the base asset (e.g., \"0x2::sui::SUI\")\n * @param quoteDenom - The denomination of the quote asset (e.g., \"0xusdcAddress...\")\n *\n * @returns An InvertiblePrice object containing:\n * - baseDenom: The denom of the base token\n * - quoteDenom: The denom of the quote token\n * - price: The price value as a string\n * - expiryTime: The expiry time in nanoseconds as a string\n * - isInverse: Always false (price is not inverted)\n *\n * @example\n * ```typescript\n * const priceData = {\n * base_symbol: \"0x2::sui::SUI\".\n * quote_symbol: \"0xusdcAddress...\".\n * price: \"2.5\",\n * expiry_time_ms: \"1700000000000\" // milliseconds\n * };\n *\n * const price = parsePriceDataStructOutput(\n * priceData,\n * \"0x2::sui::SUI\",\n * \"0xusdcAddress...\"\n * );\n * console.log(price.price); // \"2.5\"\n * console.log(price.baseDenom); // \"0x2::sui::SUI\"\n * console.log(price.quoteDenom); // \"0xusdcAddress...\"\n * console.log(price.expiryTime); // \"1700000000000000000\" (nanoseconds)\n * ```\n */\nexport const parsePriceDataStructOutput = (output: PriceDataStructOutput): InvertiblePrice => {\n return {\n baseDenom: output.base_symbol,\n quoteDenom: output.quote_symbol,\n price: output.price,\n expiryTime: BigNumber(output.expiry_time_ms).times(1_000_000).toFixed(),\n isInverse: false,\n };\n};\n\n/**\n * Parses a price response from the oracle contract, extracting the price data if available.\n *\n * This function handles the response from price queries which may or may not contain\n * valid price data. It checks for the presence of pair_data and throws an error\n * if the price is not available.\n *\n * @param output - The price response from the oracle contract\n * @param output.pair_data - Optional price data for the requested pair\n * @param baseDenom - The denomination of the base asset\n * @param quoteDenom - The denomination of the quote asset\n *\n * @returns An InvertiblePrice object with the parsed price information\n *\n * @throws {InvalidObjectError} When pair_data is not present in the response,\n * indicating that no price is available for the requested pair\n *\n * @example\n * ```typescript\n * // Successful response with price data\n * const output = {\n * pair_data: {\n * price: \"2.5\",\n * expiry_time_ms: \"1700000000000\"\n * }\n * };\n *\n * const price = parsePriceResponseStructOutput(\n * output,\n * \"0x2::sui::SUI\",\n * \"0xusdcAddress...\"\n * );\n * console.log(price.price); // \"2.5\"\n *\n * // Response without price data\n * const emptyOutput = { pair_data: null };\n * // This will throw InvalidObjectError\n * ```\n */\nexport const parsePriceResponseStructOutput = (\n output: PriceResponseStructOutput\n): InvertiblePrice => {\n if (!output.pair_data) {\n throw new InvalidObjectError(\"Can't find pair data price\");\n }\n\n return parsePriceDataStructOutput(output.pair_data);\n};\n\n/**\n * Parses a paginated response containing multiple asset pairs from the oracle contract.\n *\n * This function is similar to parseAssetPairsResponseStructOutput but handles\n * paginated responses which may be used for larger datasets or API endpoints\n * that support pagination.\n *\n * @param output - The paginated response containing asset pairs\n * @param output.asset_pairs - Array of raw asset pair data\n *\n * @returns An array of parsed OracleAssetPair objects\n *\n * @example\n * ```typescript\n * const paginatedOutput = {\n * asset_pairs: [\n * { base_symbol: \"SUI\", base_precision: 9, quote_symbol: \"USDC\", quote_precision: 6 },\n * { base_symbol: \"ETH\", base_precision: 18, quote_symbol: \"USDC\", quote_precision: 6 }\n * ],\n * // Additional pagination fields would be here in a real output\n * };\n *\n * const pairs = parseAssetPairsResponsePaginatedStructOutput(paginatedOutput);\n * console.log(pairs.length); // 2\n * ```\n */\nexport const parseAssetPairsResponsePaginatedStructOutput = (\n output: AssetPairsResponsePaginatedStructOutput\n): OracleAssetPair[] => {\n return output.asset_pairs.map((item) => parseAssetPairStructOutput(item));\n};\n\n/**\n * Parses a paginated response containing multiple prices from the oracle contract.\n *\n * This function processes bulk price data that may be returned from queries\n * for all available prices in the oracle.\n *\n * @param output - The paginated response containing price data\n * @param output.prices - Array of raw price data objects\n *\n * @returns An array of parsed Price objects\n *\n * @example\n * ```typescript\n * const paginatedPrices = {\n * prices: [\n * { price: \"2.5\", expiry_time_ms: \"1700000000000\" },\n * { price: \"1800\", expiry_time_ms: \"1700000000000\" }\n * ],\n * // Additional pagination fields would be here\n * };\n *\n * const prices = parsePricesResponsePaginatedStructOutput(paginatedPrices);\n * console.log(prices.length); // 2\n * console.log(prices[0].price); // \"2.5\"\n * ```\n */\nexport const parsePricesResponsePaginatedStructOutput = (\n output: PricesResponsePaginatedStructOutput\n): Price[] => {\n return output.prices.map((item) => parsePriceDataStructOutput(item));\n};\n","import { bcs, BcsType } from '@mysten/bcs';\n\nexport const PaginationStruct = {\n total_count: bcs.u64(),\n has_next_page: bcs.bool(),\n next_cursor: bcs.option(bcs.string()),\n};\n\nexport const BcsAddressType = new BcsType({\n name: 'address',\n\n read(reader) {\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) {\n bytes[i] = reader.read8();\n }\n return (\n '0x' +\n Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n );\n },\n\n write(value, writer) {\n // Remove 0x prefix if present\n const hex = value.startsWith('0x') ? value.slice(2) : value;\n // Pad to 64 characters (32 bytes)\n const paddedHex = hex.padStart(64, '0');\n\n for (let i = 0; i < 32; i++) {\n const byte = parseInt(paddedHex.substr(i * 2, 2), 16);\n writer.write8(byte);\n }\n },\n});\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type BcsParsed<T extends BcsType<any, any>> = ReturnType<T['parse']>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type BcsParsedMultiple<T extends readonly BcsType<any>[]> = {\n [K in keyof T]: BcsParsed<T[K]>;\n};\n","import { bcs } from '@mysten/bcs';\n\nimport { BcsAddressType, PaginationStruct, type BcsParsed } from './bcs';\n\nexport const OracleConfigStruct = bcs.struct('Config', {\n admin: BcsAddressType,\n price_threshold_ratio: bcs.u64(),\n default_price_expiry_seconds: bcs.u64(),\n});\nexport type OracleConfigStructOutput = BcsParsed<typeof OracleConfigStruct>;\n\nexport const AssetPairStruct = bcs.struct('AssetPair', {\n base_symbol: bcs.string(),\n quote_symbol: bcs.string(),\n base_precision: bcs.u8(),\n quote_precision: bcs.u8(),\n});\nexport type AssetPairStructOutput = BcsParsed<typeof AssetPairStruct>;\n\nexport const AssetPairsResponseStruct = bcs.struct('AssetPairsResponse', {\n asset_pairs: bcs.vector(AssetPairStruct),\n});\nexport type AssetPairsResponseStructOutput = BcsParsed<typeof AssetPairsResponseStruct>;\n\nexport const AssetPairsResponsePaginatedStruct = bcs.struct('AssetPairsResponsePaginated', {\n asset_pairs: bcs.vector(AssetPairStruct),\n ...PaginationStruct,\n});\nexport type AssetPairsResponsePaginatedStructOutput = BcsParsed<\n typeof AssetPairsResponsePaginatedStruct\n>;\n\nexport const PriceDataStruct = bcs.struct('PriceData', {\n base_symbol: bcs.string(),\n quote_symbol: bcs.string(),\n price: bcs.u128(),\n expiry_time_ms: bcs.u64(),\n last_updated_ms: bcs.u64(),\n updater: BcsAddressType,\n});\nexport type PriceDataStructOutput = BcsParsed<typeof PriceDataStruct>;\n\nexport const PriceResponseStruct = bcs.struct('PriceResponse', {\n pair_data: bcs.option(PriceDataStruct),\n});\nexport type PriceResponseStructOutput = BcsParsed<typeof PriceResponseStruct>;\n\nexport const PricesResponsePaginatedStruct = bcs.struct('PricesResponsePaginated', {\n prices: bcs.vector(PriceDataStruct),\n ...PaginationStruct,\n});\nexport type PricesResponsePaginatedStructOutput = BcsParsed<typeof PricesResponsePaginatedStruct>;\n","import { bcs } from '@mysten/bcs';\n\nimport { BcsAddressType, type BcsParsed, PaginationStruct } from './bcs';\n\nexport const RouterConfigStruct = bcs.struct('Config', {\n admin: BcsAddressType,\n default_price_oracle_contract: BcsAddressType,\n default_protocol_fee_recipient: BcsAddressType,\n default_protocol_fee: bcs.u64(),\n default_lp_fee: bcs.u64(),\n});\nexport type RouterConfigStructOutput = BcsParsed<typeof RouterConfigStruct>;\n\nexport const MarketStruct = bcs.struct('Market', {\n base_asset_symbol: bcs.string(),\n quote_assets_symbols: bcs.vector(bcs.string()),\n market_address: bcs.string(),\n is_permissioned: bcs.bool(),\n created_at_ms: bcs.u64(),\n});\nexport type MarketStructOutput = BcsParsed<typeof MarketStruct>;\n\nexport const MarketResponseStruct = bcs.struct('MarketResponse', {\n market: bcs.option(MarketStruct),\n});\nexport type MarketResponseStructOutput = BcsParsed<typeof MarketResponseStruct>;\n\nexport const MarketsResponseStruct = bcs.struct('MarketsResponse', {\n markets: bcs.vector(MarketStruct),\n});\nexport type MarketsResponseStructOutput = BcsParsed<typeof MarketsResponseStruct>;\n\nexport const MarketsResponsePaginatedStruct = bcs.struct('MarketsResponsePaginated', {\n markets: bcs.vector(MarketStruct),\n ...PaginationStruct,\n});\nexport type MarketsResponsePaginatedStructOutput = BcsParsed<typeof MarketsResponsePaginatedStruct>;\n\nexport const BaseLiquidityInfoStruct = bcs.struct('BaseLiquidityInfo', {\n denom: bcs.string(),\n amount: bcs.u64(),\n});\nexport type BaseLiquidityInfoStructOutput = BcsParsed<typeof BaseLiquidityInfoStruct>;\n\nexport const BaseLiquidityResponseStruct = bcs.struct('BaseLiquidityResponse', {\n base_assets: bcs.vector(BaseLiquidityInfoStruct),\n ...PaginationStruct,\n});\nexport type BaseLiquidityResponseStructOutput = BcsParsed<typeof BaseLiquidityResponseStruct>;\n","import { bcs } from '@mysten/bcs';\n\nimport { BcsAddressType, type BcsParsedMultiple } from './bcs';\n\nexport const GetPoolInfoResponseStruct = [\n bcs.u64(),\n bcs.u128(),\n BcsAddressType,\n bcs.bool(),\n] as const;\nexport type GetPoolInfoResponseStructOutput = BcsParsedMultiple<typeof GetPoolInfoResponseStruct>;\n\nexport const GetFeesResponseStruct = [bcs.u64(), bcs.u64(), bcs.u64()] as const;\nexport type GetFeesResponseStructOutput = BcsParsedMultiple<typeof GetFeesResponseStruct>;\n","import type { Asset, OracleAsset } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\n\n/**\n * Retrieves all unique assets available in the Bolt protocol by querying oracle asset pairs\n * and enriching them with additional metadata from the client's asset configuration.\n *\n * This function performs the following operations:\n * 1. Fetches all oracle asset pairs from the blockchain\n * 2. Extracts unique assets from both base and quote positions\n * 3. Maps oracle assets to full Asset objects using client configuration\n * 4. Provides fallback values for assets not found in the configuration\n *\n * @param client - The BoltSuiClient instance used to query the blockchain\n * and access asset configuration.\n *\n * @returns A promise that resolves to an array of Asset objects, each containing:\n * - symbol: The asset's trading symbol (e.g., \"SUI\", \"USDC\")\n * - name: The full name of the asset (e.g., \"Sui\", \"USD Coin\")\n * - chainId: The blockchain network identifier (e.g., \"sui-mainnet\")\n * - denom: The chain-specific denomination (e.g., \"0x2::sui::SUI\")\n * - decimals: The number of decimal places for precision\n * - logo: Optional URL to the asset's logo image\n * - coingeckoId: Optional CoinGecko identifier for market data integration\n *\n * @throws {TransactionFailedError} When the oracle contract query fails\n * @throws {ParseError} When the oracle response cannot be properly parsed\n * @throws {UnexpectedError} When network issues prevent the query from completing\n */\nexport const getAssets = async (client: BoltSuiClient): Promise<Asset[]> => {\n // Fetch all trading pairs from the oracle to discover available assets\n const assetPairs = await client.getAllOracleAssetPairs();\n\n /**\n * Map to store unique assets by symbol.\n * This ensures each asset appears only once in the final result,\n * even if it appears in multiple trading pairs.\n */\n const uniqueOracleAssets: Record<string, OracleAsset> = {};\n\n // Extract unique assets from all trading pairs\n for (const item of assetPairs) {\n uniqueOracleAssets[item.base.symbol] = item.base;\n uniqueOracleAssets[item.quote.symbol] = item.quote;\n }\n\n return Object.values(uniqueOracleAssets).map(\n (item) =>\n client.assetsConfig[item.symbol] ??\n // Fallback to minimal asset data from oracle\n {\n symbol: item.name,\n name: item.name,\n chainId: client.chainConfig.id,\n denom: item.symbol,\n decimals: item.precision,\n logo: undefined,\n coingeckoId: undefined,\n }\n );\n};\n","import type { OracleConfig } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\nimport { PRICE_ORACLE_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseOracleConfigStructOutput } from './parsers';\nimport { OracleConfigStruct } from '../../types';\n\n/**\n * Queries the oracle smart contract to retrieve its current configuration settings.\n *\n * This function fetches the oracle's configuration parameters which govern how\n * price feeds are managed, including expiration times, update thresholds, and\n * administrative settings. The configuration is essential for understanding\n * oracle behavior and constraints when working with price feeds.\n *\n * @param client - The BoltSuiClient instance\n *\n * @returns A promise that resolves to an OracleConfig object containing:\n * - admin: The Sui address authorized to update oracle settings and prices\n * - priceThresholdRatio: The minimum price change ratio required for updates\n * (e.g., \"0.01\" means 1% minimum change required)\n * - priceExpireTime: Object with time duration for price validity:\n * - secs: Number of seconds before a price is considered stale\n * - nanos: Additional nanoseconds (always 0 in current implementation)\n *\n * @throws {TransactionFailedError} When the oracle contract query fails, possibly due to:\n * - Invalid oracle contract address\n * - Oracle contract not initialized\n * - Network connectivity issues\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format from the contract\n * - BCS deserialization failure\n * - Contract ABI mismatch\n * @throws {InvalidObjectError} When required data is missing from the response\n */\nexport const getOracleConfig = async (client: BoltSuiClient): Promise<OracleConfig> => {\n /**\n * The Move function name in the oracle module that returns configuration.\n * This function signature in Move:\n * public fun config(oracle: &Oracle): OracleConfig\n */\n const CONFIG_FUNCTION = 'config';\n\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, PRICE_ORACLE_MODULE, CONFIG_FUNCTION],\n [client.contracts.oracle]\n );\n\n const output = parseDevInspectResult(response, OracleConfigStruct);\n\n return parseOracleConfigStructOutput(output);\n};\n","import type { InvertiblePrice } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\nimport { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils';\n\nimport type { BoltSuiClient } from '../client';\nimport { PRICE_ORACLE_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parsePriceResponseStructOutput } from './parsers';\nimport { PriceResponseStruct } from '../../types';\n\n/**\n * Queries the oracle smart contract to retrieve the current price for a specific asset pair.\n *\n * This function fetches the latest price feed for a given base/quote asset combination\n * from the Bolt oracle. The oracle maintains price feeds that are updated by authorized\n * price feeders and validated against configured thresholds. Prices have expiration times\n * to ensure stale data is not used for trading.\n *\n * @param client - The BoltSuiClient instance\n * @param baseDenom - The denomination/type of the base asset in Sui format\n * (e.g., \"0x2::sui::SUI\", \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\")\n * @param quoteDenom - The denomination/type of the quote asset in Sui format\n * Price will be expressed as: 1 base = X quote\n *\n * @returns A promise that resolves to an InvertiblePrice object containing:\n * - baseDenom: The denom of the base token\n * - quoteDenom: The denom of the quote token\n * - price: The current price as a decimal string (e.g., \"2.5\" means 1 base = 2.5 quote)\n * - expiryTime: Unix timestamp in nanoseconds when this price becomes stale\n * - isInverse: Always false in current implementation (price is not inverted)\n *\n * @throws {InvalidObjectError} When the requested asset pair has no price data available,\n * which can occur if:\n * - The pair is not registered in the oracle\n * - The price has expired and not been updated\n * - The oracle has never received a price for this pair\n * @throws {TransactionFailedError} When the oracle contract query fails due to:\n * - Invalid oracle contract address\n * - Network connectivity issues\n * - Contract execution errors\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format\n * - BCS deserialization failure\n */\nexport const getPrice = async (\n client: BoltSuiClient,\n baseDenom: string,\n quoteDenom: string\n): Promise<InvertiblePrice> => {\n /**\n * The Move function name in the oracle module that returns price for a pair.\n * This function signature in Move:\n * public fun get_price(\n * oracle: &Oracle,\n * base_denom: String,\n * quote_denom: String,\n * clock: &Clock\n * ): PriceResponse\n */\n const GET_PRICE_FUNCTION = 'get_price';\n\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, PRICE_ORACLE_MODULE, GET_PRICE_FUNCTION],\n [\n client.contracts.oracle,\n bcs.string().serialize(baseDenom),\n bcs.string().serialize(quoteDenom),\n SUI_CLOCK_OBJECT_ID,\n ]\n );\n\n const output = parseDevInspectResult(response, PriceResponseStruct);\n\n return parsePriceResponseStructOutput(output, baseDenom, quoteDenom);\n};\n","import type { Price } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\n\nimport type { BoltSuiClient } from '../client';\nimport { DEFAULT_PAGINATION_LIMIT, PRICE_ORACLE_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parsePricesResponsePaginatedStructOutput } from './parsers';\nimport { PricesResponsePaginatedStruct } from '../../types';\n\n/**\n * Queries the oracle smart contract to retrieve all available price feeds with automatic pagination.\n *\n * This function fetches the current prices for all asset pairs supported by the oracle\n * in a paginated manner. It's more efficient than making multiple individual price\n * queries when you need prices for multiple pairs. The function automatically handles\n * pagination to ensure all prices are retrieved, regardless of the total number.\n *\n * @param client - The BoltSuiClient instance\n *\n * @returns A promise that resolves to an array of Price objects, each containing:\n * - baseDenom: The denom of the base token\n * - quoteDenom: The denom of the quote token\n * - price: The current price as a decimal string\n * - expiryTime: Unix timestamp in nanoseconds when this price becomes stale\n *\n * @throws {TransactionFailedError} When the oracle contract query fails due to:\n * - Invalid oracle contract address\n * - Oracle not properly initialized\n * - Network connectivity issues\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format from the contract\n * - BCS deserialization failure\n * - Contract ABI mismatch\n */\nexport const getPrices = async (client: BoltSuiClient): Promise<Price[]> => {\n /**\n * The Move function name in the oracle module that returns paginated prices.\n * This function signature in Move:\n * public fun get_prices_paginated(\n * oracle: &Oracle,\n * limit: Option<u64>,\n * cursor: Option<String>\n * ): PricesResponsePaginated\n */\n const GET_PRICES_PAGINATED_FUNCTION = 'get_prices_paginated';\n\n const result: Price[] = [];\n\n let currentCursor = null;\n\n let hasNextPage = true;\n\n while (hasNextPage) {\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, PRICE_ORACLE_MODULE, GET_PRICES_PAGINATED_FUNCTION],\n [\n client.contracts.oracle,\n bcs.option(bcs.u64()).serialize(DEFAULT_PAGINATION_LIMIT),\n bcs.option(bcs.string()).serialize(currentCursor),\n ]\n );\n\n const output = parseDevInspectResult(response, PricesResponsePaginatedStruct);\n\n const assetPairs = parsePricesResponsePaginatedStructOutput(output);\n\n result.push(...assetPairs);\n\n currentCursor = output.next_cursor;\n hasNextPage = output.has_next_page;\n }\n\n return result;\n};\n","import { type Coin, DEFAULT_GAS_ADJUSTMENT, type SwapParams } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\nimport type { Signer } from '@mysten/sui/cryptography';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils';\n\nimport type { BoltSuiClient } from '../client';\nimport { ROUTER_MODULE } from '../constants';\nimport { CoinManager, estimateTxGasPrice } from '../helpers';\n\n/**\n * Estimates the gas fees required for executing a swap transaction on the Sui blockchain.\n *\n * This function simulates a swap transaction to calculate the required gas fees without\n * actually executing the swap. It constructs a transaction with the swap_exact_in Move\n * function call and uses Sui's dry run capability to estimate gas costs in SUI tokens.\n *\n * @param client - The BoltSuiClient instance\n * @param params - The swap parameters\n * @param params.assetIn - The type of the asset being sold (e.g., \"0x2::sui::SUI\")\n * @param params.amountIn - The exact amount of input asset to swap (in minimal denomination)\n * @param params.assetOut - The type of the asset being bought (e.g., \"0x5d...::coin::COIN\")\n * @param params.minimumAmountOut - Optional minimum acceptable amount of output asset.\n * Used for slippage protection in the swap simulation.\n * @param params.receiver - Optional recipient address for the swapped assets.\n * If not provided, defaults to the signer's address.\n * @param signer - Optional signer for the transaction. If not provided,\n * uses the client's cached signer. Required on first call if no cached signer exists.\n * @param gasAdjustment - Multiplier for gas estimation to add safety margin.\n * Defaults to DEFAULT_GAS_ADJUSTMENT (typically 1.5 for 50% buffer).\n *\n * @returns A promise that resolves to:\n * - A Coin object with `amount` (gas fee in MIST) and `denom` (\"0x2::sui::SUI\")\n * - `undefined` if the simulation fails or gas estimation is not supported\n *\n * @throws {MissingParameterError} Thrown internally when no signer is available\n */\nexport const estimateSwapExactInGasFees = async (\n client: BoltSuiClient,\n { assetIn, amountIn, assetOut, minimumAmountOut, receiver }: SwapParams,\n signer?: Signer,\n gasAdjustment: number = DEFAULT_GAS_ADJUSTMENT\n): Promise<Coin | undefined> => {\n const SWAP_EXACT_IN_FUNCTION = 'swap_exact_in';\n\n const finalSigner = client.getSigner(signer);\n\n const tx = new Transaction();\n\n const coinManager = new CoinManager(client.suiClient, finalSigner.toSuiAddress());\n\n const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);\n\n return await estimateTxGasPrice(\n client.suiClient,\n [client.packageId, ROUTER_MODULE, SWAP_EXACT_IN_FUNCTION],\n [\n client.contracts.router,\n bcs.string().serialize(assetOut),\n '', // TODO: pass correct pool when router can actually route to the pools depending on other arguments\n bcs.string().serialize(assetIn),\n bcs.option(bcs.string()).serialize(minimumAmountOut),\n bcs.option(bcs.string()).serialize(receiver),\n coinInput,\n SUI_CLOCK_OBJECT_ID,\n ],\n [assetIn, assetOut],\n tx,\n gasAdjustment\n );\n};\n","import type { Address, BaseLiquidityDetails } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\n\nimport type { BoltSuiClient } from '../client';\nimport { DEFAULT_PAGINATION_LIMIT, ROUTER_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseBaseLiquidityResponseStructOutput } from './parsers';\nimport { BaseLiquidityResponseStruct } from '../../types';\n\n/**\n * Queries the router smart contract to retrieve the total base asset liquidity across all pools with automatic pagination.\n *\n * This function fetches the current liquidity levels for all base assets in their respective\n * pools. Each pool in the Bolt protocol handles swaps for a specific base asset against\n * multiple quote assets, and this query returns how much of each base asset is currently\n * available in its pool for trading, along with the total shares for each pool. The function\n * automatically handles pagination to ensure all pools are retrieved.\n *\n * @param client - The BoltSuiClient instance\n *\n * @returns A promise that resolves to a Record mapping pool addresses to BaseLiquidityDetails objects.\n * Each entry represents:\n * - Key: Currently using base asset denom as key (see TODO in remarks)\n * - Value: A BaseLiquidityDetails object containing:\n * - baseLiquidity: A Coin object with:\n * - amount: The quantity of base asset liquidity (currently hardcoded to \"10\")\n * - denom: The type of the base asset (e.g., \"0x2::sui::SUI\")\n * - totalShares: The total number of liquidity shares (currently hardcoded to \"10\")\n *\n * @throws {TransactionFailedError} When the router contract query fails due to:\n * - Invalid router contract address\n * - Router not properly initialized\n * - Network connectivity issues\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format\n * - BCS deserialization failure\n */\nexport const getAllBaseLiquidity = async (\n client: BoltSuiClient\n): Promise<Record<Address, BaseLiquidityDetails>> => {\n /**\n * The Move function name in the router module that returns paginated base liquidity.\n * This function signature in Move:\n * public fun base_liquidity_all_paginated(\n * router: &Router,\n * limit: Option<u64>,\n * cursor: Option<String>\n * ): BaseLiquidityResponse\n */\n const BASE_LIQUIDITY_ALL_PAGINATED_FUNCTION = 'base_liquidity_all_paginated';\n\n const result: Record<Address, BaseLiquidityDetails> = {};\n\n let currentCursor = null;\n\n let hasNextPage = true;\n\n while (hasNextPage) {\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, ROUTER_MODULE, BASE_LIQUIDITY_ALL_PAGINATED_FUNCTION],\n [\n client.contracts.router,\n bcs.option(bcs.u64()).serialize(DEFAULT_PAGINATION_LIMIT),\n bcs.option(bcs.string()).serialize(currentCursor),\n ]\n );\n\n const output = parseDevInspectResult(response, BaseLiquidityResponseStruct);\n\n const baseLiquidities = parseBaseLiquidityResponseStructOutput(output);\n\n for (const item of baseLiquidities) {\n // TODO: fix when we get the correct values\n // Currently using base asset denom as key instead of pool address\n // This should be changed to use actual pool addresses when available\n result[item.baseLiquidity.denom] = item;\n }\n\n // Update pagination state for the next iteration\n currentCursor = output.next_cursor;\n hasNextPage = output.has_next_page;\n }\n\n return result;\n};\n","import type { Pool, RouterConfig, BaseLiquidityDetails } from '@bolt-liquidity-hq/core';\nimport { NotFoundError } from '@bolt-liquidity-hq/core';\n\nimport type {\n BaseLiquidityResponseStructOutput,\n MarketResponseStructOutput,\n MarketsResponsePaginatedStructOutput,\n MarketsResponseStructOutput,\n MarketStructOutput,\n RouterConfigStructOutput,\n} from '../../types';\n\n/**\n * Parses a raw market structure from the Sui blockchain into a structured Pool object.\n *\n * This function transforms the raw market data returned by the Sui router contract\n * into a standardized Pool format. In the Sui implementation, markets and pools\n * are conceptually the same, representing liquidity pools for base/quote asset pairs.\n *\n * @param output - The raw market data from the Sui contract\n * @param output.market_address - The Sui object ID of the market/pool\n * @param output.base_asset_symbol - The type/symbol of the base asset\n * @param output.quote_assets_symbols - Array of quote asset types/symbols\n *\n * @returns A parsed Pool object containing:\n * - poolAddress: The Sui object ID of the pool\n * - baseDenom: The type of the base asset (e.g., \"0x2::sui::SUI\")\n * - quoteDenoms: Array of available quote asset types\n *\n * @example\n * ```typescript\n * const rawMarket = {\n * market_address: \"0x1234...\",\n * base_asset_symbol: \"0x2::sui::SUI\",\n * quote_assets_symbols: [\"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\"]\n * };\n *\n * const pool = parseMarketStructOutput(rawMarket);\n * console.log(pool.poolAddress); // \"0x1234...\"\n * console.log(pool.baseDenom); // \"0x2::sui::SUI\"\n * console.log(pool.quoteDenoms); // [\"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\"]\n * ```\n *\n * @remarks\n * - In Sui, asset symbols are full type paths (e.g., \"0x2::sui::SUI\")\n * - A market can have multiple quote assets paired with one base asset\n * - The market_address is a unique Sui object ID\n */\nexport const parseMarketStructOutput = (output: MarketStructOutput): Pool => {\n return {\n poolAddress: output.market_address,\n baseDenom: output.base_asset_symbol,\n quoteDenoms: output.quote_assets_symbols,\n };\n};\n\n/**\n * Parses a market response that may or may not contain market data.\n *\n * This function handles responses from queries for specific markets, which include\n * an optional market field. If no market is found, it throws an appropriate error.\n *\n * @param output - The market query response from the Sui contract\n * @param output.market - Optional market data if found\n *\n * @returns A parsed Pool object representing the market\n *\n * @throws {NotFoundError} When the market field is null or undefined,\n * indicating the requested market doesn't exist\n *\n * @example\n * ```typescript\n * // Successful response with market data\n * const response = {\n * market: {\n * market_address: \"0x1234...\",\n * base_asset_symbol: \"0x2::sui::SUI\",\n * quote_assets_symbols: [\"0x5d4b...::coin::COIN\"]\n * }\n * };\n * const pool = parseMarketResponseStructOutput(response);\n *\n * // Response without market (will throw)\n * const emptyResponse = { market: null };\n * // Throws NotFoundError\n * ```\n */\nexport const parseMarketResponseStructOutput = (output: MarketResponseStructOutput): Pool => {\n if (!output.market) {\n throw new NotFoundError('Market', undefined, { output });\n }\n\n return parseMarketStructOutput(output.market);\n};\n\n/**\n * Parses a response containing all available markets/pools into an array of Pool objects.\n *\n * This function processes the response from the router's markets query, which returns\n * all active liquidity pools in the Bolt protocol on Sui.\n *\n * @param output - The raw response from the router's markets query\n * @param output.markets - Array of market structures\n *\n * @returns An array of parsed Pool objects, each representing a liquidity pool\n *\n * @example\n * ```typescript\n * const output = {\n * markets: [\n * {\n * market_address: \"0xabc...\",\n * base_asset_symbol: \"0x2::sui::SUI\",\n * quote_assets_symbols: [\"0x5d4b...::coin::COIN\"]\n * },\n * {\n * market_address: \"0xdef...\",\n * base_asset_symbol: \"0xaf8...::coin::COIN\",\n * quote_assets_symbols: [\"0x5d4b...::coin::COIN\", \"0x2::sui::SUI\"]\n * }\n * ]\n * };\n *\n * const pools = parseMarketsResponseStructOutput(output);\n * console.log(pools.length); // 2\n * pools.forEach(pool => {\n * console.log(`Pool for ${pool.baseDenom} at ${pool.poolAddress}`);\n * console.log(`Quote assets: ${pool.quoteDenoms.join(', ')}`);\n * });\n * ```\n *\n * @remarks\n * - Each market represents a pool with one base asset and one or more quote assets\n * - Markets are returned in the order they exist on-chain\n * - Empty markets array is valid and returns an empty array\n */\nexport const parseMarketsResponseStructOutput = (output: MarketsResponseStructOutput): Pool[] => {\n return output.markets.map((item) => parseMarketStructOutput(item));\n};\n\n/**\n * Parses a paginated response containing markets/pools into an array of Pool objects.\n *\n * This function handles paginated market responses, which are used when there are\n * too many markets to return in a single query. It extracts just the market data,\n * leaving pagination handling to the calling function.\n *\n * @param output - The paginated response from the router's markets query\n * @param output.markets - Array of market structures for this page\n * @param output.has_next_page - Whether more pages exist (not used in parser)\n * @param output.next_cursor - Cursor for next page (not used in parser)\n *\n * @returns An array of parsed Pool objects for this page of results\n *\n * @example\n * ```typescript\n * const paginatedOutput = {\n * markets: [\n * {\n * market_address: \"0xabc...\",\n * base_asset_symbol: \"0x2::sui::SUI\",\n * quote_assets_symbols: [\"0x5d4b...::coin::COIN\"]\n * }\n * ],\n * has_next_page: true,\n * next_cursor: \"0xabc...\"\n * };\n *\n * const pools = parseMarketsResponsePaginatedStructOutput(paginatedResponse);\n * console.log(pools.length); // 1 (just this page)\n * ```\n *\n * @see {@link parseMarketsResponseStructOutput} for non-paginated version\n */\nexport const parseMarketsResponsePaginatedStructOutput = (\n output: MarketsResponsePaginatedStructOutput\n): Pool[] => {\n return output.markets.map((item) => parseMarketStructOutput(item));\n};\n\n/**\n * Parses a raw router configuration response from the Sui blockchain into a structured RouterConfig object.\n *\n * This function transforms the snake_case properties from the Sui router contract response\n * into camelCase properties following TypeScript conventions. The router configuration\n * controls global settings for the Bolt protocol on Sui.\n *\n * @param output - The raw router configuration response from the contract query\n * @param output.admin - The Sui address with admin privileges\n * @param output.default_price_oracle_contract - Default oracle object ID for price feeds\n * @param output.default_protocol_fee_recipient - Address that receives protocol fees\n * @param output.default_protocol_fee - Protocol fee as decimal string (e.g., \"0.003\" = 0.3%)\n * @param output.default_lp_fee - LP fee as decimal string (e.g., \"0.002\" = 0.2%)\n *\n * @returns A parsed RouterConfig object with:\n * - admin: The admin address of the router contract\n * - defaultPriceOracleContract: Object ID of the default price oracle\n * - defaultProtocolFeeRecipient: Address that receives protocol fees\n * - defaultProtocolFee: The default protocol fee percentage (as decimal string)\n * - defaultLpFee: The default liquidity provider fee percentage (as decimal string)\n *\n * @example\n * ```typescript\n * const output = {\n * admin: \"0xadmin...\",\n * default_price_oracle_contract: \"0xoracle...\",\n * default_protocol_fee_recipient: \"0xtreasury...\",\n * default_protocol_fee: \"0.003\",\n * default_lp_fee: \"0.002\"\n * };\n *\n * const config = parseRouterConfigStructOutput(output);\n * console.log(config.admin); // \"0xadmin...\"\n * console.log(config.defaultProtocolFee); // \"0.003\" (0.3%)\n * console.log(config.defaultLpFee); // \"0.002\" (0.2%)\n *\n * // Calculate total fees\n * const totalFeePercent = (parseFloat(config.defaultProtocolFee) +\n * parseFloat(config.defaultLpFee)) * 100;\n * console.log(`Total fees: ${totalFeePercent}%`); // \"Total fees: 0.5%\"\n * ```\n *\n * @remarks\n * - Fees are represented as decimal strings (0.003 = 0.3%)\n * - The router configuration applies globally unless overridden at the pool level\n * - Admin can update these default values\n * - Protocol fees go to the specified recipient address\n * - LP fees are distributed to liquidity providers\n */\nexport const parseRouterConfigStructOutput = (output: RouterConfigStructOutput): RouterConfig => {\n return {\n admin: output.admin,\n defaultPriceOracleContract: output.default_price_oracle_contract,\n defaultProtocolFeeRecipient: output.default_protocol_fee_recipient,\n defaultProtocolFee: output.default_protocol_fee,\n defaultLpFee: output.default_lp_fee,\n };\n};\n\n/**\n * Parses a base liquidity response into a structured format.\n *\n * This function processes the response from base liquidity queries, which provide\n * information about the base assets and their amounts locked in pools. The function\n * maps the raw liquidity information into a standardized format for use throughout\n * the SDK.\n *\n * @param output - The raw response from a base liquidity query\n * @param output.base_assets - Array of base asset information objects containing:\n * - denom: The asset type (e.g., \"0x2::sui::SUI\")\n * - amount: The amount of base asset in the pool\n *\n * @returns An array of BaseLiquidityDetails objects, each containing:\n * - baseLiquidity: Object with:\n * - denom: The asset type from the input\n * - amount: The amount of base asset from the input\n * - totalShares: The total LP shares (currently empty string, pending contract update)\n *\n * @example\n * ```typescript\n * const output = {\n * base_assets: [\n * { denom: \"0x2::sui::SUI\", amount: \"1000000000\" },\n * { denom: \"0xaf8...::coin::COIN\", amount: \"5000000\" }\n * ]\n * };\n *\n * const details = parseBaseLiquidityResponseStructOutput(output);\n * // Result: [\n * // {\n * // baseLiquidity: { denom: \"0x2::sui::SUI\", amount: \"1000000000\" },\n * // totalShares: \"\"\n * // },\n * // {\n * // baseLiquidity: { denom: \"0xaf8...::coin::COIN\", amount: \"5000000\" },\n * // totalShares: \"\"\n * // }\n * // ]\n *\n * // Display liquidity information\n * details.forEach(detail => {\n * console.log(`Asset: ${detail.baseLiquidity.denom}`);\n * console.log(`Amount: ${detail.baseLiquidity.amount}`);\n * });\n * ```\n *\n * @remarks\n * - **TODO**: The totalShares field is currently set to an empty string because\n * the smart contract doesn't return this information yet. This will be updated\n * when the contract is enhanced to include total LP shares data.\n * - The function preserves the exact amounts from the contract response\n * - Each base asset in a pool has its own liquidity amount tracked separately\n * - The amounts are returned as strings to preserve precision for large numbers\n */\nexport const parseBaseLiquidityResponseStructOutput = (\n output: BaseLiquidityResponseStructOutput\n): BaseLiquidityDetails[] => {\n return output.base_assets.map((item) => ({\n baseLiquidity: {\n denom: item.denom,\n amount: item.amount,\n },\n totalShares: '', // TODO: add real total shares if it is returned by the smart contract later\n }));\n};\n","import type { Address, Coin } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\n\nimport type { BoltSuiClient } from '../client';\nimport { ROUTER_MODULE } from '../constants';\nimport { queryDevInspect } from '../helpers';\n\n/**\n * Queries the router smart contract to retrieve all quote asset positions for a specific liquidity provider.\n *\n * This function fetches all withdrawable quote assets that a liquidity provider (LP) has\n * deposited across all pools in the Bolt protocol. LPs provide quote assets (like USDC)\n * to pools, enabling traders to swap base assets for these quote assets. This query\n * returns the current balance of quote assets the LP can withdraw from each pool.\n *\n * @param client - The BoltSuiClient instance\n * @param lpAddress - The Sui address of the liquidity provider to query\n * Must be a valid Sui address format (e.g., \"0x1234...\")\n *\n * @returns A promise that resolves to a Record mapping pool addresses to arrays of Coin objects.\n * Each entry represents:\n * - Key: The pool object ID where the LP has deposits\n * - Value: An array of Coin objects, each containing:\n * - amount: The withdrawable quantity of quote asset (as string)\n * - denom: The type of the quote asset (e.g., \"0x5d4b...::coin::COIN\")\n *\n * @throws {TransactionFailedError} When the router contract query fails due to:\n * - Invalid router contract address\n * - Invalid LP address format\n * - Router not properly initialized\n * - Network connectivity issues\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format\n * - BCS deserialization failure\n */\nexport const getAllQuotesForUser = async (\n client: BoltSuiClient,\n lpAddress: Address\n): Promise<Record<Address, Coin[]>> => {\n /**\n * The Move function name in the router module that returns all quote positions for a user.\n * This function signature in Move:\n * public fun quotes_for_user_all(\n * router: &Router,\n * lp_address: String\n * ): QuotesForUserResponse\n */\n const QUOTES_FOR_USER_ALL_FUNCTION = 'quotes_for_user_all';\n\n // Query the router contract for all quote positions of the specified LP\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, ROUTER_MODULE, QUOTES_FOR_USER_ALL_FUNCTION],\n [client.contracts.router, bcs.string().serialize(lpAddress)]\n );\n\n console.log(response);\n\n // TODO: contract doesn't have this implemented yet\n // When implemented, this will parse the response into the expected format:\n // const output = parseDevInspectResult(response, QuotesForUserResponseStruct);\n // return parseQuotesForUserResponse(output);\n\n // TODO: contract doesn't have this implemented yet\n // Returning empty object until contract implementation is complete\n return {};\n};\n","import type { Pool } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\n\nimport type { BoltSuiClient } from '../client';\nimport { ROUTER_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseMarketResponseStructOutput } from './parsers';\nimport { MarketResponseStruct } from '../../types';\n\n/**\n * Queries the router smart contract to retrieve pool information for a specific base asset.\n *\n * This function fetches the market/pool details for a given base asset type. In the Bolt protocol\n * on Sui, each market (pool) is dedicated to trading one base asset against multiple quote assets.\n * This query returns the pool's object ID and available quote assets for the specified base asset.\n * Markets and pools are used interchangeably in the Sui implementation.\n *\n * @param client - The BoltSuiClient instance\n * @param baseDenom - The type of the base asset in Sui format\n * (e.g., \"0x2::sui::SUI\", \"0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5::coin::COIN\")\n *\n * @returns A promise that resolves to a Pool object containing:\n * - poolAddress: The Sui object ID of the market/pool\n * - baseDenom: The type of the base asset (echoes the input)\n * - quoteDenoms: Array of types for available quote assets that can be traded against the base\n *\n * @throws {NotFoundError} When no pool exists for the specified base asset, which occurs if:\n * - The base asset has no market created yet\n * - The base asset type is not recognized by the router\n * - The market was removed or not initialized\n * @throws {TransactionFailedError} When the router contract query fails due to:\n * - Invalid router contract address\n * - Network connectivity issues\n * - Invalid base asset type format\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format\n * - BCS deserialization failure\n */\nexport const getPoolForBase = async (client: BoltSuiClient, baseDenom: string): Promise<Pool> => {\n /**\n * The Move function name in the router module that returns market info for a base asset.\n * This function signature in Move:\n * public fun market_for_base(\n * router: &Router,\n * base_denom: String\n * ): MarketResponse\n */\n const MARKET_FOR_BASE_FUNCTION = 'market_for_base';\n\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, ROUTER_MODULE, MARKET_FOR_BASE_FUNCTION],\n [client.contracts.router, bcs.string().serialize(baseDenom)]\n );\n\n const output = parseDevInspectResult(response, MarketResponseStruct);\n\n return parseMarketResponseStructOutput(output);\n};\n","import type { Pool } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\n\nimport type { BoltSuiClient } from '../client';\nimport { DEFAULT_PAGINATION_LIMIT, ROUTER_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseMarketsResponsePaginatedStructOutput } from './parsers';\nimport { MarketsResponsePaginatedStruct } from '../../types';\n\n/**\n * Queries the router smart contract to retrieve information about all deployed pools with automatic pagination.\n *\n * This function fetches a comprehensive list of all markets/pools in the Bolt protocol on Sui,\n * including their object IDs, base assets, and available quote assets. It automatically handles\n * pagination to ensure all pools are retrieved, regardless of the total number. This provides\n * a complete overview of all trading possibilities within the protocol at once, making it more\n * efficient than querying individual pools.\n *\n * @param client - The BoltSuiClient instance that must be configured with:\n * - packageId: The Sui package ID containing the router module\n * - contracts.router: The router contract object ID\n * - suiClient: An active SuiClient for network communication\n *\n * @returns A promise that resolves to an array of Pool objects, each containing:\n * - poolAddress: The Sui object ID of the market/pool\n * - baseDenom: The type of the base asset for this pool (e.g., \"0x2::sui::SUI\")\n * - quoteDenoms: Array of types for available quote assets that can be traded\n *\n * @throws {TransactionFailedError} When the router contract query fails due to:\n * - Invalid router contract address\n * - Router not properly initialized\n * - Network connectivity issues\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format from the contract\n * - BCS deserialization failure\n * - Contract ABI mismatch\n *\n * @example\n * ```typescript\n * const client = new BoltSuiClient({\n * environment: 'mainnet'\n * });\n *\n * try {\n * const allPools = await getPools(client);\n *\n * console.log(`Total pools available: ${allPools.length}`);\n *\n * // Display all pools and their trading pairs\n * allPools.forEach((pool, index) => {\n * console.log(`\\nPool ${index + 1}: ${pool.poolAddress}`);\n * console.log(` Base asset: ${pool.baseDenom}`);\n * console.log(` Quote assets: ${pool.quoteDenoms.length}`);\n * pool.quoteDenoms.forEach(quote => {\n * console.log(` - ${quote}`);\n * });\n * });\n *\n * // Find all pools that support USDC as quote\n * const usdcType = \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\";\n * const poolsWithUsdc = allPools.filter(pool =>\n * pool.quoteDenoms.includes(usdcType)\n * );\n * console.log(`\\nPools supporting USDC: ${poolsWithUsdc.length}`);\n *\n * // Find pools for specific base asset\n * const suiPools = allPools.filter(pool =>\n * pool.baseDenom === \"0x2::sui::SUI\"\n * );\n * if (suiPools.length > 0) {\n * console.log(`\\nSUI pool found at: ${suiPools[0].poolAddress}`);\n * }\n *\n * // Count total unique trading pairs\n * const totalPairs = allPools.reduce((sum, pool) =>\n * sum + pool.quoteDenoms.length, 0\n * );\n * console.log(`\\nTotal trading pairs: ${totalPairs}`);\n *\n * } catch (error) {\n * console.error('Failed to fetch pools:', error);\n * }\n * ```\n *\n * @remarks\n * - In Sui, \"markets\" and \"pools\" are used interchangeably\n * - Each pool handles one base asset but can have multiple quote assets\n * - The function uses pagination internally to handle large numbers of pools\n * - DEFAULT_PAGINATION_LIMIT controls how many pools are fetched per query\n * - All queries are performed using devInspect, so no gas is consumed\n * - Pool addresses are Sui object IDs\n * - This function is useful for:\n * - Building a complete list of trading options\n * - Discovering all supported assets\n * - Creating market overview dashboards\n * - Finding pools for specific asset pairs\n * - Analyzing protocol liquidity distribution\n * - Results are returned in the order they exist on-chain\n *\n * @see {@link Pool} for the structure of pool objects\n * @see {@link getPoolForBase} to query a specific pool by base asset\n * @see {@link getPoolConfig} for detailed configuration of individual pools\n * @see {@link getAllBaseAssetsLiquidity} for liquidity information across pools\n */\nexport const getPools = async (client: BoltSuiClient): Promise<Pool[]> => {\n /**\n * The Move function name in the router module that returns paginated markets.\n * This function signature in Move:\n * public fun markets_paginated(\n * router: &Router,\n * limit: Option<u64>,\n * cursor: Option<String>\n * ): MarketsResponsePaginated\n */\n const MARKETS_PAGINATED_FUNCTION = 'markets_paginated';\n\n const result: Pool[] = [];\n\n let currentCursor = null;\n\n let hasNextPage = true;\n\n while (hasNextPage) {\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, ROUTER_MODULE, MARKETS_PAGINATED_FUNCTION],\n [\n client.contracts.router,\n bcs.option(bcs.u64()).serialize(DEFAULT_PAGINATION_LIMIT),\n bcs.option(bcs.string()).serialize(currentCursor),\n ]\n );\n\n const output = parseDevInspectResult(response, MarketsResponsePaginatedStruct);\n\n const pools = parseMarketsResponsePaginatedStructOutput(output);\n\n result.push(...pools);\n\n currentCursor = output.next_cursor;\n hasNextPage = output.has_next_page;\n }\n\n return result;\n};\n","import type { RouterConfig } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\nimport { ROUTER_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseRouterConfigStructOutput } from './parsers';\nimport { RouterConfigStruct } from '../../types';\n\n/**\n * Queries the router smart contract to retrieve its current configuration settings.\n *\n * This function fetches the router's configuration parameters which govern how\n * swaps are executed, fees are collected, and new pools are deployed. The router\n * is the central contract that coordinates all trading activities in the Bolt protocol\n * on Sui, managing markets and ensuring consistent behavior across all pools.\n *\n * @param client - The BoltSuiClient instance\n *\n * @returns A promise that resolves to a RouterConfig object containing:\n * - admin: The Sui address with administrative privileges over the router\n * - defaultPriceOracleContract: Object ID of the default price oracle used by pools\n * - defaultProtocolFeeRecipient: Sui address that receives protocol fees\n * - defaultProtocolFee: Protocol fee percentage as a decimal string (e.g., \"0.003\" = 0.3%)\n * - defaultLpFee: Liquidity provider fee percentage as a decimal string (e.g., \"0.002\" = 0.2%)\n *\n * @throws {TransactionFailedError} When the router contract query fails due to:\n * - Invalid router contract address\n * - Router not properly initialized\n * - Network connectivity issues\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format from the contract\n * - BCS deserialization failure\n * - Contract ABI mismatch\n * @throws {InvalidObjectError} When required configuration data is missing\n */\nexport const getRouterConfig = async (client: BoltSuiClient): Promise<RouterConfig> => {\n /**\n * The Move function name in the router module that returns configuration.\n * This function signature in Move:\n * public fun config(router: &Router): RouterConfig\n */\n const CONFIG_FUNCTION = 'config';\n\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, ROUTER_MODULE, CONFIG_FUNCTION],\n [client.contracts.router]\n );\n\n const output = parseDevInspectResult(response, RouterConfigStruct);\n\n return parseRouterConfigStructOutput(output);\n};\n","import type { SwapParams, SwapResult } from '@bolt-liquidity-hq/core';\nimport { bcs } from '@mysten/bcs';\nimport type { SuiTransactionBlockResponse } from '@mysten/sui/client';\nimport type { Signer } from '@mysten/sui/cryptography';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils';\n\nimport type { BoltSuiClient } from '../client';\nimport { ROUTER_MODULE } from '../constants';\nimport { signAndExecuteTx, CoinManager } from '../helpers';\n\n/**\n * Executes a token swap transaction on the Bolt protocol through the Sui Move router module.\n *\n * This function performs a \"swap exact in\" operation, where the user specifies exactly\n * how much of the input coin they want to swap, and receives a variable amount of the\n * output coin based on current liquidity pool conditions. The function automatically handles\n * coin selection, merging (if needed), and transaction building on the Sui blockchain.\n *\n * @param client - The BoltSuiClient instance\n * @param params - The swap configuration parameters\n * @param params.assetIn - The fully qualified type of the input coin being sold\n * (e.g., \"0x2::sui::SUI\", \"0x...::usdc::USDC\")\n * @param params.amountIn - The exact amount of input coin to swap (as string, in base units).\n * For example, \"1000000000\" for 1 SUI (9 decimals)\n * @param params.assetOut - The fully qualified type of the output coin being bought\n * (e.g., \"0x2::sui::SUI\", \"0x...::usdc::USDC\")\n * @param params.minimumAmountOut - Optional minimum acceptable amount of output coin.\n * Transaction will fail if the actual output would be less.\n * Protects against excessive slippage\n * @param params.receiver - Optional recipient address for the swapped coins.\n * If not provided, coins are sent to the signer's address\n * @param signer - The Sui signer (e.g., Ed25519Keypair) that will authorize the swap transaction.\n * Must have sufficient balance of the input coin type and SUI for gas fees\n *\n * @returns A promise that resolves to a SwapResult containing:\n * - txOutput: The complete SuiTransactionBlockResponse with transaction details\n * - txHash: The transaction digest for tracking on Sui explorers\n * - amountOut: The actual amount of output coin received (as string) - currently empty, TODO\n * - assetOut: The output coin type (echoes the input parameter)\n *\n * @throws {TransactionFailedError} Thrown when:\n * - The transaction fails on-chain (insufficient balance, slippage, etc.)\n * - The minimum output amount constraint is not satisfied\n * - The liquidity pool for the coin pair doesn't exist\n * @throws {UnexpectedError} Thrown when:\n * - Network connectivity issues occur\n * - Invalid coin types are provided\n * - Coin selection/preparation fails\n */\nexport const swapExactIn = async (\n client: BoltSuiClient,\n { assetIn, amountIn, assetOut, minimumAmountOut, receiver }: SwapParams,\n signer?: Signer\n): Promise<SwapResult<SuiTransactionBlockResponse>> => {\n const SWAP_EXACT_IN_FUNCTION = 'swap_exact_in';\n\n const finalSigner = client.getSigner(signer);\n\n const tx = new Transaction();\n\n const coinManager = new CoinManager(client.suiClient, finalSigner.toSuiAddress());\n\n const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);\n\n const txOutput = await signAndExecuteTx(\n client.suiClient,\n finalSigner,\n [client.packageId, ROUTER_MODULE, SWAP_EXACT_IN_FUNCTION],\n [\n client.contracts.router,\n bcs.string().serialize(assetOut),\n '', // TODO: pass correct pool when router can actually route to the pools depending on other arguments\n bcs.string().serialize(assetIn),\n bcs.option(bcs.string()).serialize(minimumAmountOut),\n bcs.option(bcs.string()).serialize(receiver),\n coinInput,\n SUI_CLOCK_OBJECT_ID,\n ],\n [assetIn, assetOut],\n tx,\n { showEffects: true, showEvents: true, showBalanceChanges: true }\n );\n\n return {\n txOutput,\n txHash: txOutput.digest,\n amountOut: '', // TODO: implement when contract emits event\n assetOut,\n };\n};\n","import type { Address, PoolConfig } from '@bolt-liquidity-hq/core';\nimport { SUI_TYPE_ARG } from '@mysten/sui/utils';\n\nimport type { BoltSuiClient } from '../client';\nimport { POOL_MODULE } from '../constants';\nimport { parseMultipleResults, queryDevInspect } from '../helpers';\nimport { parseSettlementConfigStructOutput } from './parsers';\nimport { GetFeesResponseStruct } from '../../types';\n\n/**\n * Retrieves the configuration settings and fee information for a liquidity pool.\n *\n * This function queries both the global pool configuration object and the specific pool's\n * fee structure on the Sui blockchain. It combines data from two sources: the global\n * configuration shared across pools and the pool-specific fee information. Pool contracts\n * in Sui manage the actual liquidity operations including swaps, fees, and liquidity\n * provider management.\n *\n * @param client - The BoltSuiClient instance\n * @param contractAddress - The Sui object ID of the pool contract to query.\n * Must be a valid pool address obtained from router queries.\n *\n * @returns A promise that resolves to a PoolConfig object containing:\n * - priceOracleContract: Object ID of the price oracle (from global config)\n * - protocolFeeRecipient: Address that receives protocol fees (from global config)\n * - protocolFee: The protocol fee percentage as decimal string (e.g., \"0.003\" = 0.3%)\n * - lpFee: The liquidity provider fee percentage as decimal string (e.g., \"0.002\" = 0.2%)\n * - allowanceMode: The allowance mode for LP operations (from global config)\n * - lps: Array of authorized liquidity provider addresses (from global config)\n * - minBaseOut: Minimum base asset output amount for trades (from global config)\n *\n * @throws {TransactionFailedError} When the queries fail due to:\n * - Invalid pool contract address\n * - Invalid global config ID\n * - Network connectivity issues\n * - Incorrect type arguments for the pool\n * @throws {ParseError} When the responses cannot be parsed, indicating:\n * - Unexpected response format from either query\n * - BCS deserialization failure\n * - Missing required fields in the response\n * @throws {Error} When the global config object cannot be fetched\n */\nexport const getPoolInfo = async (\n client: BoltSuiClient,\n contractAddress: Address\n): Promise<PoolConfig> => {\n /**\n * Move function to get fee configuration for the pool.\n * Function signature in Move:\n * public fun get_fees<X>(pool: &LiquidityPool<X>): (u64, u64, u64)\n *\n * Note: The function name in the constant doesn't match the comment above,\n * which incorrectly referenced get_pool_info\n */\n const GET_FEES_FUNCTION = 'get_fees';\n\n // Execute both queries in parallel for efficiency\n const [globalConfig, fees] = await Promise.all([\n // Fetch the global pool configuration object\n client.suiClient.getObject({\n id: client.poolGlobalConfigId,\n options: {\n showContent: true,\n showType: true,\n },\n }),\n // Query pool-specific fee structure\n queryDevInspect(\n client.suiClient,\n [client.packageId, POOL_MODULE, GET_FEES_FUNCTION],\n [contractAddress],\n // TODO: get the base token of the pool to pass it here instead of hardcoded SUI token\n [SUI_TYPE_ARG]\n ),\n ]);\n\n const feesOutput = parseMultipleResults(fees, GetFeesResponseStruct);\n\n return parseSettlementConfigStructOutput(globalConfig, feesOutput);\n};\n","import type { PoolConfig } from '@bolt-liquidity-hq/core';\nimport type { SuiObjectResponse } from '@mysten/sui/client';\n\nimport type { GetFeesResponseStructOutput } from '../../types';\n\n/**\n * Parses global pool configuration and fee responses from the Sui blockchain into a structured PoolConfig object.\n *\n * This function combines data from two sources: a global configuration object shared across pools\n * and pool-specific fee information. It transforms the data from Sui responses into the standardized\n * format used throughout the SDK. The implementation currently includes several hardcoded values\n * as the Sui contracts are still being finalized.\n *\n * @param globalConfig - The SuiObjectResponse containing the global pool configuration object.\n * This object should contain shared settings like protocol fee recipient.\n * Currently only the protocol_fee_recipient field is extracted.\n * @param feesOutput - The response from the `get_fees` Move function containing fee data as a tuple:\n * - [0]: Protocol fee as decimal string (e.g., \"0.003\" = 0.3%)\n * - [1]: Not used in current implementation\n * - [2]: LP fee as decimal string (e.g., \"0.002\" = 0.2%)\n *\n * @returns A parsed PoolConfig object with:\n * - priceOracleContract: Object ID of the price oracle (currently hardcoded to \"0x\")\n * - protocolFeeRecipient: Address from globalConfig.data.content.fields.protocol_fee_recipient\n * - protocolFee: The protocol fee percentage from feesOutput[0]\n * - lpFee: The liquidity provider fee percentage from feesOutput[2]\n * - allowanceMode: The allowance mode for pool operations (currently hardcoded to \"allow\")\n * - lps: Array of authorized LP addresses (currently hardcoded to [\"0x\"])\n * - minBaseOut: Minimum base asset output amount (currently hardcoded to \"1\")\n *\n * @example\n * ```typescript\n * // Example with actual data\n * const globalConfig: SuiObjectResponse = {\n * data: {\n * content: {\n * fields: {\n * protocol_fee_recipient: \"0xtreasury123...\",\n * // other fields...\n * }\n * }\n * }\n * // ... other response fields\n * };\n *\n * const feesResponse: GetFeesResponseStructOutput = [\n * \"0.003\", // protocol fee (0.3%)\n * \"0x...\", // unused\n * \"0.002\" // LP fee (0.2%)\n * ];\n *\n * const config = parseSettlementConfigStructOutput(globalConfig, feesResponse);\n * console.log(config.protocolFeeRecipient); // \"0xtreasury123...\"\n * console.log(config.protocolFee); // \"0.003\"\n * console.log(config.lpFee); // \"0.002\"\n *\n * // With missing global config data\n * const emptyGlobalConfig = { data: null };\n * const configWithDefaults = parseSettlementConfigStructOutput(emptyGlobalConfig, feesResponse);\n * console.log(configWithDefaults.protocolFeeRecipient); // \"\" (empty string default)\n * ```\n *\n * @remarks\n * - **Data Sources**:\n * - `globalConfig`: Provides protocol_fee_recipient (extracted via unsafe access)\n * - `feesOutput`: Provides protocol and LP fee percentages\n * - **TODO**: Several fields are currently hardcoded and should be updated:\n * - `priceOracleContract`: Hardcoded to \"0x\" (should come from global config)\n * - `allowanceMode`: Hardcoded to \"allow\" (should come from global config)\n * - `lps`: Hardcoded to [\"0x\"] (should come from global config)\n * - `minBaseOut`: Hardcoded to \"1\" (should come from global config)\n * - The function uses unsafe type assertions to access nested fields in globalConfig\n * - If globalConfig doesn't contain the expected structure, protocolFeeRecipient defaults to empty string\n * - Fee values (protocol and LP) are the most reliable data in the current implementation\n *\n * @see {@link PoolConfig} for the complete structure of pool configuration\n * @see {@link getPoolInfo} which calls this parser\n * @see {@link GetFeesResponseStructOutput} for the expected fees structure\n */\nexport const parseSettlementConfigStructOutput = (\n globalConfig: SuiObjectResponse,\n feesOutput: GetFeesResponseStructOutput\n): PoolConfig => {\n // TODO: update when contracts are completed\n // Currently using hardcoded values for most fields\n return {\n priceOracleContract: '0x', // Should come from pool config\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n protocolFeeRecipient: (globalConfig.data?.content as any)?.fields.protocol_fee_recipient || '',\n protocolFee: feesOutput[0], // Protocol fee percentage\n lpFee: feesOutput[2], // LP fee percentage\n allowanceMode: 'allow', // Should come from pool config\n lps: ['0x'], // Should come from pool config\n minBaseOut: '1', // Should come from pool config\n };\n};\n","export const TEST_USDT =\n '0xda2075ce382224b79131a753483bee667a7cec24024c5f8cfc80887362be280f::test_usdt::TEST_USDT';\nexport const TEST_POOL = '0xdd05c1caea7b6725da3f67e30e99872033fc5d3a610a4f72ac1c434bc81c3c0d';\n","import type { PoolConfig } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\nimport { getPoolInfo } from './get-pool-info';\nimport { getPoolForBase } from '../router';\nimport { TEST_POOL } from '../../tests/constants';\n\n/**\n * Retrieves the configuration settings for a settlement contract (liquidity pool)\n * identified by its base asset type.\n *\n * This is a convenience function that combines pool lookup and configuration retrieval.\n * It first finds the pool/market associated with the given base asset, then fetches that\n * pool's configuration parameters from its settlement contract. In Sui, settlement\n * contracts manage the actual liquidity and trading logic for each pool.\n *\n * @param client - The BoltSuiClient instance\n * @param baseDenom - The type of the base asset in Sui format\n * (e.g., \"0x2::sui::SUI\", \"0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5::coin::COIN\")\n *\n * @returns A promise that resolves to a PoolConfig object containing:\n * - priceOracleContract: Object ID of the price oracle used by this pool\n * - protocolFeeRecipient: Sui address that receives protocol fees\n * - protocolFee: The protocol fee percentage (as decimal string, e.g., \"0.003\" = 0.3%)\n * - lpFee: The liquidity provider fee percentage (as decimal string, e.g., \"0.002\" = 0.2%)\n * - allowanceMode: The allowance mode for pool operations (controls LP permissions)\n * - lps: Array of authorized liquidity provider Sui addresses\n * - minBaseOut: Minimum base asset output amount for trades (prevents dust trades)\n *\n * @throws {NotFoundError} When no pool exists for the specified base asset\n * @throws {TransactionFailedError} When the contract queries fail due to:\n * - Invalid router or settlement contract addresses\n * - Network connectivity issues\n * - Contract not properly initialized\n * @throws {ParseError} When the configuration response cannot be parsed\n */\nexport const getPoolInfoForBase = async (\n client: BoltSuiClient,\n baseDenom: string\n): Promise<PoolConfig> => {\n // TODO: use only baseDenom from arguments when the pool has baseDenom instead of symbol as id\n // Currently hardcoding 'SUI' due to contract limitations\n const pool = await getPoolForBase(client, baseDenom && 'SUI');\n\n // TODO: remove fallback when pool has address value\n // Using TEST_POOL as fallback until pool addresses are properly returned\n return await getPoolInfo(client, pool.poolAddress || TEST_POOL);\n};\n"],"mappings":"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","names":["import_core","import_utils","import_bcs","import_core","import_utils","import_core","import_core","import_transactions","import_utils","import_core","import_bignumber","import_bcs","import_bcs","import_bcs","import_bcs","import_bcs","import_utils","import_bcs","import_core","import_bcs","import_transactions","import_utils","import_bcs","import_core","import_bcs","import_bcs","import_bcs","import_bcs","import_transactions","import_utils","import_utils"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/client.ts","../src/config/mainnet.ts","../src/config/testnet.ts","../src/lib/constants/sui-objects.ts","../src/lib/helpers/bcs-parse.ts","../src/lib/helpers/coin-manager.ts","../src/lib/helpers/queries.ts","../src/lib/helpers/transactions.ts","../src/lib/oracle/parsers.ts","../src/types/bcs.ts","../src/types/oracle.ts","../src/types/router.ts","../src/types/pool.ts","../src/lib/oracle/get-asset-pairs.ts","../src/lib/oracle/get-assets.ts","../src/lib/oracle/get-oracle-config.ts","../src/lib/oracle/get-price.ts","../src/lib/oracle/get-prices.ts","../src/lib/router/estimate-swap-exact-in-gas-fees.ts","../src/lib/router/get-all-base-liquidity.ts","../src/lib/router/get-all-quotes-for-user.ts","../src/lib/router/get-pool-by-denom.ts","../src/lib/router/get-pools.ts","../src/lib/router/get-router-config.ts","../src/lib/router/router-client/RouterClient.ts","../src/lib/router/swap-exact-in.ts","../src/lib/settlement/get-pool-info.ts","../src/lib/settlement/parsers.ts","../src/lib/settlement/get-pool-info-by-denom.ts"],"sourcesContent":["export { BoltSuiClient } from './lib/client';\n\nexport * from './types';\n","import type {\n Address,\n BaseLiquidityDetails,\n Coin,\n InvertiblePrice,\n OracleAssetPair,\n OracleConfig,\n PoolConfig,\n Pool,\n Price,\n RouterConfig,\n SwapParams,\n SwapResult,\n Contracts,\n AssetsConfig,\n Asset,\n} from '@bolt-liquidity-hq/core';\nimport { BaseClient, MissingParameterError } from '@bolt-liquidity-hq/core';\nimport { SuiClient, type SuiTransactionBlockResponse } from '@mysten/sui/client';\nimport type { Signer } from '@mysten/sui/cryptography';\nimport { normalizeStructTag } from '@mysten/sui/utils';\nimport axios from 'axios';\n\nimport {\n MainnetAssets,\n MainnetChainConfig,\n MainnetContracts,\n MainnetPackageId,\n MainnetPoolGlobalConfigId,\n TestnetAssets,\n TestnetChainConfig,\n TestnetContracts,\n TestnetPoolGlobalConfigId,\n TestnetPackageId,\n MainnetNativeTokenDenom,\n TestnetNativeTokenDenom,\n TestnetHelperAssets,\n MainnetPools,\n TestnetConfigUrl,\n} from '../config';\nimport { getAssets, getAssetPairs, getOracleConfig, getPrice, getPrices } from './oracle';\nimport {\n RouterClient,\n estimateSwapExactInGasFees,\n getAllBaseLiquidity,\n getAllQuotesForUser,\n getPoolByDenom,\n getPools,\n getRouterConfig,\n swapExactIn,\n} from './router';\nimport { getPoolInfo, getPoolInfoByDenom } from './settlement';\nimport type { SuiChainConfig, SuiClientConfig } from '../types';\n\n/**\n * Client implementation for interacting with the Bolt Liquidity Outpost on Sui blockchain.\n *\n * This class extends the abstract {@link BaseClient} to provide Sui-specific functionality\n * for querying and executing transactions on Bolt Protocol's oracle and router smart contracts.\n * It uses SuiTransactionBlockResponse as the transaction output type, providing detailed transaction execution information.\n *\n * @extends {BaseClient<Signer, SuiTransactionBlockResponse>}\n *\n * @group Bolt API Clients\n *\n * @example\n * ```typescript\n * // Create a client for Sui mainnet\n * const client = new BoltSuiClient();\n *\n * // Query oracle prices\n * const price = await client.getPrice(\"0x2::sui::SUI\", \"0xusdcAddress...\");\n *\n * // Execute a swap (requires signer)\n * const signer = // ... get signer from wallet\n * const result = await client.swap({\n * assetIn: \"0x2::sui::SUI\",\n * amountIn: \"1000000000\", // 1 SUI (9 decimals)\n * assetOut: \"0xusdcAddress...\"\n * }, signer);\n * ```\n */\nexport class BoltSuiClient extends BaseClient<Signer, SuiTransactionBlockResponse> {\n /**\n * The Sui-specific chain configuration including RPC endpoint\n */\n public override chainConfig: SuiChainConfig;\n\n /**\n * Package Id for the deployed Bolt contracts on Sui\n */\n public packageId: string;\n\n /**\n * Object Id for the GlobalConfig of the deployed Pool contracts\n */\n public poolGlobalConfigId: string;\n\n /**\n * Cached instance of the Signer for transaction execution\n */\n public signer?: Signer;\n\n /**\n * Instance of the Sui client to interact with the blockchain\n */\n public suiClient: SuiClient;\n\n /**\n * URL for fetching testnet configuration dynamically.\n * Used to load package IDs, oracle addresses, and asset configurations for testnet environments.\n * @private\n */\n private configFileUrl?: string;\n\n /**\n * Router client instance for managing pool configurations and routing calculations.\n * Handles pool discovery and optimal path finding for swaps.\n */\n public routerClient: RouterClient;\n\n /**\n * Creates a new instance of the BoltSuiClient.\n *\n * The client automatically configures itself based on the specified environment,\n * loading the appropriate contract addresses, chain configuration, native token denomination,\n * and assets from configuration files. For testnet environments, the client can dynamically\n * fetch configuration from a remote URL.\n *\n * @param config - (Optional) Configuration for the client\n * @param config.environment - (Optional) The deployment environment ('mainnet' or 'testnet'). Defaults to 'mainnet'\n * @param config.customOverride - (Optional) Custom overrides for chain configuration, contracts, native token, and assets\n * @param config.customOverride.chainConfig - (Optional) Override chain configuration\n * @param config.customOverride.chainConfig.id - (Optional) Custom chain ID\n * @param config.customOverride.chainConfig.name - (Optional) Custom chain name\n * @param config.customOverride.chainConfig.rpcEndpoint - (Optional) Custom RPC endpoint URL\n * @param config.customOverride.packageId - (Optional) Custom package ID for Bolt contracts\n * @param config.customOverride.poolGlobalConfigId - (Optional) Custom Object ID for the Pool contracts' Global Config\n * @param config.customOverride.contracts - (Optional) Override contract addresses\n * @param config.customOverride.contracts.oracle - (Optional) Custom oracle contract address\n * @param config.customOverride.contracts.router - (Optional) Custom router contract address\n * @param config.customOverride.nativeTokenDenom - (Optional) Custom native token denomination (e.g., \"SUI\")\n * @param config.customOverride.assetsConfig - (Optional) Custom asset configurations indexed by denom\n * @param config.signer - (Optional) Pre-existing Signer for transaction signing\n * @param config.suiClient - (Optional) Pre-existing SuiClient to use for blockchain queries\n *\n * @throws {InvalidObjectError} Thrown when required configuration fields are missing\n *\n * @example\n * ```typescript\n * // Use default configuration (Sui mainnet)\n * const client = new BoltSuiClient();\n *\n * // Use testnet configuration (will fetch config dynamically)\n * const testnetClient = new BoltSuiClient({\n * environment: 'testnet'\n * });\n *\n * // Use custom chain configuration\n * const customClient = new BoltSuiClient({\n * customOverride: {\n * chainConfig: {\n * id: 'sui-custom',\n * name: 'Sui Custom',\n * rpcEndpoint: 'https://custom-rpc.example.com'\n * },\n * packageId: '0xcustom_package_id...',\n * poolGlobalConfigId: '0xcustom_global_config_id...',\n * contracts: {\n * oracle: '0xcustom_oracle...',\n * router: '0xcustom_router...'\n * },\n * nativeTokenDenom: 'SUI',\n * assetsConfig: {\n * '0x2::sui::SUI': {\n * symbol: 'SUI',\n * name: 'Sui',\n * chainId: 'sui-custom',\n * denom: '0x2::sui::SUI',\n * decimals: 9,\n * logo: 'https://example.com/sui.png',\n * coingeckoId: 'sui'\n * }\n * }\n * }\n * });\n *\n * // Use pre-existing Sui client and signer\n * const clientWithCustomClient = new BoltSuiClient({\n * suiClient: mySuiClient,\n * signer: mySigner\n * });\n * ```\n */\n constructor(config?: SuiClientConfig) {\n const { environment = 'mainnet', customOverride, signer, suiClient } = config ?? {};\n\n const isEnvironmentMainnet = environment === 'mainnet';\n const defaultChainConfig: SuiChainConfig = isEnvironmentMainnet\n ? MainnetChainConfig\n : TestnetChainConfig;\n const defaultContracts: Contracts = isEnvironmentMainnet ? MainnetContracts : TestnetContracts;\n const defaultPackageId = isEnvironmentMainnet ? MainnetPackageId : TestnetPackageId;\n const defaultPoolGlobalConfigId = isEnvironmentMainnet\n ? MainnetPoolGlobalConfigId\n : TestnetPoolGlobalConfigId;\n const defaultNativeTokenDenom = isEnvironmentMainnet\n ? MainnetNativeTokenDenom\n : TestnetNativeTokenDenom;\n const assetsConfig: AssetsConfig = isEnvironmentMainnet ? MainnetAssets : TestnetAssets;\n const pools = isEnvironmentMainnet ? MainnetPools : [];\n\n // Apply overrides\n const chainConfig: SuiChainConfig = {\n id: customOverride?.chainConfig?.id ?? defaultChainConfig.id,\n name: customOverride?.chainConfig?.name ?? defaultChainConfig.name,\n rpcEndpoint: customOverride?.chainConfig?.rpcEndpoint ?? defaultChainConfig.rpcEndpoint,\n };\n const packageId = customOverride?.packageId ?? defaultPackageId;\n const poolGlobalConfigId = customOverride?.poolGlobalConfigId ?? defaultPoolGlobalConfigId;\n const contracts: Contracts = {\n oracle: customOverride?.contracts?.oracle ?? defaultContracts.oracle,\n router: customOverride?.contracts?.router ?? defaultContracts.router,\n };\n const nativeTokenDenom = customOverride?.nativeTokenDenom ?? defaultNativeTokenDenom;\n\n for (const item of Object.values(customOverride?.assetsConfig ?? {})) {\n assetsConfig[item.denom] = item;\n }\n\n super({\n customOverride: {\n chainConfig,\n contracts,\n nativeTokenDenom,\n assetsConfig,\n },\n });\n\n this.chainConfig = chainConfig;\n this.packageId = packageId;\n this.poolGlobalConfigId = poolGlobalConfigId;\n this.signer = signer;\n this.suiClient = suiClient ?? new SuiClient({ url: chainConfig.rpcEndpoint });\n this.routerClient = new RouterClient(pools);\n this.configFileUrl = isEnvironmentMainnet ? undefined : TestnetConfigUrl;\n }\n\n /**\n * Gets or sets the signer for transaction execution.\n *\n * This method manages the signer instance used for signing transactions.\n * A signer must be provided either when creating the client, on first call,\n * or to replace the existing signer.\n *\n * @param newSigner - Optional new signer to replace the existing one\n *\n * @returns The current signer instance\n *\n * @throws {MissingParameterError} Thrown when no signer is available and none is provided\n *\n * @example\n * ```typescript\n * // Get the current signer (throws if none exists)\n * const currentSigner = client.getSigner();\n *\n * // Set a new signer\n * const newSigner = // ... obtain signer from wallet\n * const signer = client.getSigner(newSigner);\n * ```\n */\n public getSigner(newSigner?: Signer): Signer {\n this.signer = newSigner ?? this.signer;\n\n if (!this.signer) {\n throw new MissingParameterError('signer');\n }\n\n return this.signer;\n }\n\n // The following methods inherit their documentation from BaseClient\n // Only add documentation here if you need to override or add implementation-specific details\n\n /** @inheritdoc */\n public async getOracleConfig(): Promise<OracleConfig> {\n await this.loadConfigFromUrl();\n return await getOracleConfig(this);\n }\n\n /** @inheritdoc */\n async getAllOracleAssetPairs(): Promise<OracleAssetPair[]> {\n await this.loadConfigFromUrl();\n return await getAssetPairs(this);\n }\n\n /** @inheritdoc */\n async getPrice(baseDenom: string, quoteDenom: string): Promise<InvertiblePrice> {\n await this.loadConfigFromUrl();\n return await getPrice(this, baseDenom, quoteDenom);\n }\n\n /** @inheritdoc */\n async getAllPrices(): Promise<Price[]> {\n await this.loadConfigFromUrl();\n return await getPrices(this);\n }\n\n /** @inheritdoc */\n async getRouterConfig(): Promise<RouterConfig> {\n await this.loadConfigFromUrl();\n return await getRouterConfig(this);\n }\n\n /** @inheritdoc */\n async getAllBaseAssetsLiquidity(): Promise<Record<Address, BaseLiquidityDetails>> {\n await this.loadConfigFromUrl();\n return await getAllBaseLiquidity(this);\n }\n\n /** @inheritdoc */\n async getAllQuotesByUser(address: Address): Promise<Record<Address, Coin[]>> {\n await this.loadConfigFromUrl();\n return await getAllQuotesForUser(this, address);\n }\n\n /**\n * @inheritdoc\n *\n * @remarks\n * In the Sui implementation, both `baseDenom` and `quoteDenom` parameters are required.\n * The Sui architecture uses both asset types to uniquely identify pools for specific\n * trading pairs.\n *\n * @throws Will throw an error if no pool exists for the specified base/quote asset pair\n */\n async getPoolByDenom(baseDenom: string, quoteDenom: string): Promise<Pool> {\n await this.loadConfigFromUrl();\n return await getPoolByDenom(this, baseDenom, quoteDenom);\n }\n\n /** @inheritdoc */\n async getAllPools(): Promise<Pool[]> {\n await this.loadConfigFromUrl();\n return await getPools(this);\n }\n\n /** @inheritdoc */\n async getPoolConfig(poolContractAddress: string): Promise<PoolConfig> {\n await this.loadConfigFromUrl();\n return await getPoolInfo(this, poolContractAddress);\n }\n\n /** @inheritdoc */\n async getAssets(): Promise<Asset[]> {\n await this.loadConfigFromUrl();\n return await getAssets(this);\n }\n\n /**\n * @inheritdoc\n *\n * @remarks\n * In the Sui implementation, both `baseDenom` and `quoteDenom` parameters are required.\n * The Sui architecture uses both asset types to uniquely identify pools for specific\n * trading pairs.\n *\n * @throws Will throw an error if no pool exists for the specified base/quote asset pair\n */\n async getPoolConfigByDenom(baseDenom: string, quoteDenom: string): Promise<PoolConfig> {\n await this.loadConfigFromUrl();\n return await getPoolInfoByDenom(this, baseDenom, quoteDenom);\n }\n\n /**\n * @inheritdoc\n *\n * @example\n * ```typescript\n * // Get signer from wallet (e.g., Sui Wallet, Suiet, etc.)\n * const signer = // ... obtain signer from wallet\n *\n * // Execute swap: 1 SUI for USDC\n * const result = await client.swap({\n * assetIn: \"0x2::sui::SUI\",\n * amountIn: \"1000000000\", // 1 SUI (9 decimals)\n * assetOut: \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\", // USDC address\n * minimumAmountOut: \"1950000\", // Minimum 1.95 USDC expected (6 decimals)\n * receiver: \"0x...\" // Optional custom receiver address\n * }, signer);\n *\n * console.log(`Swap successful!`);\n * console.log(`Transaction digest: ${result.txHash}`);\n * console.log(`Received: ${result.amountOut} ${result.assetOut}`);\n * console.log(`Gas cost: ${result.txOutput.effects.gasUsed.computationCost}`);\n * console.log(`Status: ${result.txOutput.effects.status.status}`);\n * ```\n *\n * @remarks\n * This implementation returns a SuiTransactionBlockResponse as the transaction output,\n * which includes details like gas costs, transaction effects, object changes, and events.\n */\n async swap(\n params: SwapParams,\n signer?: Signer\n ): Promise<SwapResult<SuiTransactionBlockResponse>> {\n await this.loadConfigFromUrl();\n return await swapExactIn(this, params, signer);\n }\n\n /**\n * @inheritdoc\n *\n * @example\n * ```typescript\n * // Get signer from wallet (e.g., Sui Wallet, Suiet, etc.)\n * const signer = // ... obtain signer from wallet\n *\n * // Estimate gas for swapping 1 SUI to USDC\n * const gasEstimate = await client.estimateSwapGasFees({\n * assetIn: \"0x2::sui::SUI\",\n * amountIn: \"1000000000\", // 1 SUI (9 decimals)\n * assetOut: \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\", // USDC\n * minimumAmountOut: \"1950000\" // Min 1.95 USDC (6 decimals)\n * }, signer, 1.3); // 30% safety margin\n *\n * if (gasEstimate) {\n * console.log(`Estimated gas: ${gasEstimate.amount} ${gasEstimate.denom}`);\n * }\n * ```\n *\n * @remarks\n * - For Sui, gas is always paid in SUI tokens\n * - The returned amount is in MIST (smallest unit, 9 decimals)\n * - Gas estimation uses Sui's dry run transaction capability\n * - The gasAdjustment parameter helps account for variations in actual execution\n * - Sui's gas model includes computation, storage, and storage rebates\n */\n async estimateSwapGasFees(\n params: SwapParams,\n signer?: Signer,\n gasAdjustment?: number\n ): Promise<Coin | undefined> {\n await this.loadConfigFromUrl();\n return await estimateSwapExactInGasFees(this, params, signer, gasAdjustment);\n }\n\n /**\n * Loads configuration from a remote URL for testnet environments.\n *\n * This method fetches and applies dynamic configuration including:\n * - Package ID for Bolt contracts\n * - Oracle contract address\n * - Pool global configuration ID\n * - Asset mappings and metadata\n * - Pool configurations\n *\n * The method is called automatically before API operations when a config URL is set.\n * After successful loading, the config URL is cleared to prevent redundant fetches.\n *\n * @private\n * @remarks\n * - Only executes if `configFileUrl` is set (typically for testnet)\n * - Updates testnet-specific asset denoms with their actual deployed addresses\n * - Populates the router client's pool configurations\n * - Normalizes struct tags for consistency\n */\n private async loadConfigFromUrl() {\n if (!this.configFileUrl) {\n return;\n }\n\n const response = await axios.get(this.configFileUrl);\n const { package_id, oracle_id, global_config_id, assets, pools } =\n (response.data as {\n package_id: string;\n oracle_id: string;\n global_config_id: string;\n assets: Record<string, string>;\n pools: Array<{ base: string; pool_object_id: string }>;\n }) ?? {};\n\n if (!this.packageId && package_id) {\n this.packageId = package_id;\n }\n\n if (!this.contracts.oracle.trim() && oracle_id) {\n this.contracts.oracle = oracle_id;\n }\n\n if (!this.poolGlobalConfigId && global_config_id) {\n this.poolGlobalConfigId = global_config_id;\n }\n\n for (const item of Object.values(assets)) {\n for (const suffix of TestnetHelperAssets) {\n if (item.includes(suffix) && this.assetsConfig[suffix]) {\n this.assetsConfig[item] = {\n ...this.assetsConfig[suffix],\n denom: item,\n };\n delete this.assetsConfig[suffix];\n break;\n }\n }\n }\n\n if (this.routerClient.pools.length === 0) {\n for (const item of pools) {\n this.routerClient.pools.push({\n poolAddress: item.pool_object_id,\n baseDenom: normalizeStructTag(item.base),\n quoteDenoms: Object.values(assets)\n .map((auxAsset) => normalizeStructTag(auxAsset))\n .filter((auxAsset) => auxAsset !== normalizeStructTag(item.base)),\n });\n }\n }\n\n this.configFileUrl = undefined;\n }\n}\n","import type { AssetsConfig, Contracts, Pool } from '@bolt-liquidity-hq/core';\nimport { SUI_DECIMALS, SUI_TYPE_ARG } from '@mysten/sui/utils';\n\nimport type { SuiChainConfig } from '../types';\n\nexport const MainnetChainConfig: SuiChainConfig = {\n name: 'Sui',\n id: '101',\n rpcEndpoint: 'https://fullnode.mainnet.sui.io:443',\n};\n\nexport const MainnetContracts: Contracts = {\n oracle: '0x...',\n router: '0x...',\n};\n\nexport const MainnetPackageId: string = '0x...';\n\nexport const MainnetPoolGlobalConfigId: string = '0x...';\n\nexport const MainnetNativeTokenDenom: string = SUI_TYPE_ARG;\n\nexport const MainnetAssets: AssetsConfig = {\n [SUI_TYPE_ARG]: {\n symbol: 'SUI',\n name: 'Sui',\n chainId: '101',\n denom: SUI_TYPE_ARG,\n decimals: SUI_DECIMALS,\n logo: 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/sui/info/logo.png',\n coingeckoId: 'sui',\n },\n '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC': {\n symbol: 'USDC',\n name: 'Circle USDC',\n chainId: '101',\n denom: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n logo: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/USDCoin.png',\n coingeckoId: 'usd-coin',\n },\n};\n\nexport const MainnetPools: Pool[] = [];\n","import type { AssetsConfig, Contracts } from '@bolt-liquidity-hq/core';\nimport { SUI_DECIMALS, SUI_TYPE_ARG } from '@mysten/sui/utils';\n\nimport type { SuiChainConfig } from '../types';\n\nexport const TestnetConfigUrl = 'https://phi-labs-ltd.github.io/sui-outpost/testnet.json';\n\nexport const TestnetChainConfig: SuiChainConfig = {\n name: 'Sui Testnet',\n id: '103',\n rpcEndpoint: 'https://fullnode.testnet.sui.io:443',\n};\n\nexport const TestnetContracts: Contracts = {\n oracle: ' ',\n router: ' ',\n};\n\nexport const TestnetPackageId: string = '';\n\nexport const TestnetPoolGlobalConfigId: string = '';\n\nexport const TestnetNativeTokenDenom: string = SUI_TYPE_ARG;\n\nexport const TestnetHelperAssets = ['::test_btc::TEST_BTC', '::test_usdt::TEST_USDT'];\n\nexport const TestnetAssets: AssetsConfig = {\n [SUI_TYPE_ARG]: {\n symbol: 'SUI',\n name: 'Sui',\n chainId: '103',\n denom: SUI_TYPE_ARG,\n decimals: SUI_DECIMALS,\n logo: 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/sui/info/logo.png',\n coingeckoId: 'sui',\n },\n '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC': {\n symbol: 'USDC',\n name: 'Circle USDC',\n chainId: '103',\n denom: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',\n decimals: 6,\n logo: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/USDCoin.png',\n coingeckoId: 'usd-coin',\n },\n '::test_btc::TEST_BTC': {\n symbol: 'TEST_BTC',\n name: 'Test BTC',\n chainId: '103',\n denom: '::test_btc::TEST_BTC',\n decimals: 8,\n logo: 'https://github.com/cosmos/chain-registry/blob/master/_non-cosmos/bitcoin/images/btc.png',\n coingeckoId: 'bitcoin',\n },\n '::test_usdt::TEST_USDT': {\n symbol: 'TEST_USDT',\n name: 'Test USDT',\n chainId: '103',\n denom: '::test_usdt::TEST_USDT',\n decimals: 6,\n logo: 'https://github.com/cosmos/chain-registry/blob/master/_non-cosmos/ethereum/images/usdt.png',\n coingeckoId: 'tether',\n },\n};\n","export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000000000000000000000000000';\n\nexport const SUI_SYSTEM_CLOCK = '0x6';\n\nexport const PRICE_ORACLE_MODULE = 'price_oracle';\n\nexport const ROUTER_MODULE = 'router';\n\nexport const POOL_MODULE = 'pool';\n","import { InvalidObjectError, ParseError } from '@bolt-liquidity-hq/core';\nimport type { BcsType } from '@mysten/bcs';\nimport { bcs } from '@mysten/bcs';\nimport type { DevInspectResults } from '@mysten/sui/client';\n\nimport type { BcsParsed } from '../../types';\n\n/**\n * Extracts raw bytes from a DevInspectResults object at the specified indices.\n *\n * This utility function navigates the nested structure of Sui's DevInspectResults\n * to extract the raw byte array from a specific return value.\n *\n * @param result - The DevInspectResults object returned from a Sui devInspect call\n * @param resultIndex - The index of the result to extract from (defaults to 0)\n * @param returnValueIndex - The index of the return value within the result (defaults to 0)\n *\n * @returns The extracted bytes as a Uint8Array, or null if the specified indices don't exist\n *\n * @example\n * ```typescript\n * const result = await suiClient.devInspectTransactionBlock({...});\n * const bytes = extractBytes(result, 0, 0);\n * if (bytes) {\n * const parsedValue = bcs.u64().parse(bytes);\n * }\n * ```\n */\nexport const extractBytes = (\n result: DevInspectResults,\n resultIndex: number = 0,\n returnValueIndex: number = 0\n): Uint8Array | null => {\n const returnValues = result.results?.[resultIndex]?.returnValues;\n if (!returnValues || !returnValues[returnValueIndex]) {\n return null;\n }\n\n const [bytes] = returnValues[returnValueIndex];\n return new Uint8Array(bytes);\n};\n\n/**\n * A utility class providing static methods for parsing common BCS (Binary Canonical Serialization) types.\n *\n * BCS is the serialization format used by Sui for encoding Move types. This class\n * provides convenient wrappers around the @mysten/bcs library's parsing functions\n * for commonly used primitive and composite types.\n *\n * @example\n * ```typescript\n * // Parse a u64 value\n * const bytes = new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0]);\n * const value = BcsCommonParser.parseU64(bytes); // \"1\"\n *\n * // Parse a vector of strings\n * const vectorBytes = // ... bytes from Sui\n * const strings = BcsCommonParser.parseVector(vectorBytes, bcs.string());\n *\n * // Parse an optional value\n * const optionBytes = // ... bytes from Sui\n * const maybeValue = BcsCommonParser.parseOption(optionBytes, bcs.u32());\n * ```\n */\nexport class BcsCommonParser {\n /**\n * Parses a BCS-encoded unsigned 8-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u8 value as a number (0-255)\n */\n static parseU8(bytes: Uint8Array): number {\n return bcs.u8().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 16-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u16 value as a number (0-65535)\n */\n static parseU16(bytes: Uint8Array): number {\n return bcs.u16().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 32-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u32 value as a number (0-4294967295)\n */\n static parseU32(bytes: Uint8Array): number {\n return bcs.u32().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 64-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u64 value as a string (to preserve precision)\n *\n * @remarks\n * Returns a string because JavaScript numbers cannot safely represent\n * all 64-bit integer values without loss of precision.\n */\n static parseU64(bytes: Uint8Array): string {\n return bcs.u64().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 128-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u128 value as a string\n */\n static parseU128(bytes: Uint8Array): string {\n return bcs.u128().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded unsigned 256-bit integer.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed u256 value as a string\n */\n static parseU256(bytes: Uint8Array): string {\n return bcs.u256().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded boolean value.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed boolean value\n */\n static parseBool(bytes: Uint8Array): boolean {\n return bcs.bool().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded string.\n *\n * @param bytes - The BCS-encoded bytes to parse\n * @returns The parsed string value\n */\n static parseString(bytes: Uint8Array): string {\n return bcs.string().parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded vector (dynamic array) of elements.\n *\n * @template T - The type of elements in the vector\n * @param bytes - The BCS-encoded bytes to parse\n * @param elementParser - The BCS parser for individual vector elements\n * @returns An array of parsed elements\n *\n * @example\n * ```typescript\n * // Parse a vector of u64 values\n * const numbers = BcsCommonParser.parseVector(bytes, bcs.u64());\n *\n * // Parse a vector of custom structs\n * const customType = bcs.struct('MyStruct', {\n * id: bcs.u64(),\n * name: bcs.string()\n * });\n * const structs = BcsCommonParser.parseVector(bytes, customType);\n * ```\n */\n static parseVector<T>(bytes: Uint8Array, elementParser: BcsType<T>): T[] {\n return bcs.vector(elementParser).parse(bytes);\n }\n\n /**\n * Parses a BCS-encoded Option type (similar to Rust's Option or Move's Option).\n *\n * @template T - The type of the optional value\n * @param bytes - The BCS-encoded bytes to parse\n * @param elementParser - The BCS parser for the optional value if present\n * @returns The parsed value if Some, or null if None\n *\n * @example\n * ```typescript\n * // Parse an optional address\n * const maybeAddress = BcsCommonParser.parseOption(bytes, bcs.string());\n * if (maybeAddress) {\n * console.log(`Address: ${maybeAddress}`);\n * } else {\n * console.log('No address provided');\n * }\n * ```\n */\n static parseOption<T>(bytes: Uint8Array, elementParser: BcsType<T>): T | null {\n return bcs.option(elementParser).parse(bytes);\n }\n}\n\n/**\n * Parses a single return value from a DevInspectResults object using a specified BCS parser.\n *\n * This function combines byte extraction and BCS parsing into a single operation,\n * handling errors appropriately and providing detailed error context.\n *\n * @template T - The expected TypeScript type after parsing\n * @template Input - The input type for the BCS parser (usually the same as T)\n *\n * @param result - The DevInspectResults object from a Sui devInspect call\n * @param bcsType - The BCS parser to use for deserializing the bytes\n * @param resultIndex - The index of the result to parse (defaults to 0)\n * @param returnValueIndex - The index of the return value within the result (defaults to 0)\n *\n * @returns The parsed value of type T\n *\n * @throws {InvalidObjectError} When no bytes are found at the specified indices\n * @throws {ParseError} When BCS parsing fails due to malformed data\n *\n * @example\n * ```typescript\n * // Parse a u64 return value\n * const result = await suiClient.devInspectTransactionBlock({...});\n * const balance = parseDevInspectResult(result, bcs.u64());\n *\n * // Parse a custom struct\n * const PriceInfo = bcs.struct('PriceInfo', {\n * price: bcs.u64(),\n * timestamp: bcs.u64(),\n * });\n * const priceInfo = parseDevInspectResult(result, PriceInfo);\n *\n * // Parse from a specific return value\n * const secondReturnValue = parseDevInspectResult(result, bcs.string(), 0, 1);\n * ```\n */\nexport const parseDevInspectResult = <T, Input>(\n result: DevInspectResults,\n bcsType: BcsType<T, Input>,\n resultIndex: number = 0,\n returnValueIndex: number = 0\n): T => {\n const bytes = extractBytes(result, resultIndex, returnValueIndex);\n if (!bytes) {\n throw new InvalidObjectError('When trying to parse result, no bytes found', {\n bcsType,\n resultIndex,\n returnValueIndex,\n });\n }\n\n try {\n return bcsType.parse(bytes);\n } catch (error) {\n throw new ParseError('DevInspectResult', 'from bcs to a typescript type', {\n error,\n result,\n bcsType,\n resultIndex,\n returnValueIndex,\n });\n }\n};\n\n/**\n * Parses multiple return values from a DevInspectResults object using an array of BCS parsers.\n *\n * This function is useful when a Move function returns multiple values that need to be\n * parsed with different BCS types. It applies each parser in the schema array to the\n * corresponding return value index.\n *\n * @template T - A tuple type representing the array of BCS parsers\n *\n * @param info - The DevInspectResults object from a Sui devInspect call\n * @param schema - An array of BCS parsers, one for each expected return value\n *\n * @returns A tuple containing the parsed values, with types matching the schema\n *\n * @example\n * ```typescript\n * // Parse multiple return values of different types\n * const result = await suiClient.devInspectTransactionBlock({...});\n * const [balance, isActive, userName] = parseMultipleResults(\n * result,\n * [bcs.u64(), bcs.bool(), bcs.string()] as const\n * );\n *\n * // Parse multiple complex types\n * const TokenInfo = bcs.struct('TokenInfo', {\n * symbol: bcs.string(),\n * decimals: bcs.u8(),\n * });\n * const [tokenA, tokenB, liquidityAmount] = parseMultipleResults(\n * result,\n * [TokenInfo, TokenInfo, bcs.u128()] as const\n * );\n * ```\n *\n * @remarks\n * - The function assumes all return values are from the first result (index 0)\n * - Each parser in the schema array corresponds to a return value at the same index\n * - Type safety is preserved through TypeScript's tuple types\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const parseMultipleResults = <T extends readonly BcsType<any>[]>(\n info: DevInspectResults,\n schema: T\n): { [K in keyof T]: BcsParsed<T[K]> } => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return schema.map((bcsType, index) => parseDevInspectResult(info, bcsType, 0, index)) as {\n [K in keyof T]: BcsParsed<T[K]>;\n };\n};\n","import { InsufficientFundsError, MissingParameterError } from '@bolt-liquidity-hq/core';\nimport type { SuiClient, PaginatedCoins, CoinStruct } from '@mysten/sui/client';\nimport type { Argument, Transaction } from '@mysten/sui/transactions';\nimport { SUI_TYPE_ARG } from '@mysten/sui/utils';\n\n/**\n * Configuration options for coin selection algorithms.\n *\n * These options control how the CoinManager selects coins when preparing\n * transactions, allowing optimization for different scenarios.\n */\nexport interface CoinSelectionOptions {\n /**\n * Array of coin object IDs to exclude from selection.\n * Useful for avoiding coins that are locked or reserved for other transactions.\n *\n * @example [\"0x123...\", \"0x456...\"]\n */\n excludeIds?: string[];\n\n /**\n * When true, prefers merging multiple coins even if a single coin could cover the amount.\n * This can help consolidate fragmented coin holdings.\n *\n * @default false\n */\n preferMerge?: boolean;\n\n /**\n * When true, uses the minimum number of coins needed to cover the amount.\n * This preserves coin count but may use larger denominations.\n *\n * @default false\n */\n minimizeInputs?: boolean;\n\n /**\n * When true, allows returning a partial amount if insufficient funds.\n * The result will contain all available coins even if they don't meet the target.\n *\n * @default false\n */\n allowPartial?: boolean;\n}\n\n/**\n * Result of the coin selection process.\n *\n * Contains the selected coins and metadata about what operations\n * are needed to prepare them for the transaction.\n */\nexport interface CoinSelectionResult {\n /**\n * Array of selected coin objects that will be used in the transaction.\n */\n coins: CoinStruct[];\n\n /**\n * Total balance of all selected coins as a string.\n * May exceed the requested amount if exact change isn't available.\n */\n totalBalance: string;\n\n /**\n * Whether the selected coins need to be merged into a single coin.\n * True when multiple coins are selected.\n */\n requiresMerge: boolean;\n\n /**\n * Whether the resulting coin needs to be split to get the exact amount.\n * True when totalBalance exceeds the requested amount.\n */\n requiresSplit: boolean;\n}\n\n/**\n * Manages coin selection and preparation for Sui transactions.\n *\n * The CoinManager class provides utilities for working with coins on the Sui blockchain,\n * including fetching balances, selecting optimal coins for transactions, and preparing\n * coin inputs with automatic merging and splitting as needed.\n *\n * @example\n * ```typescript\n * const coinManager = new CoinManager(suiClient, userAddress);\n *\n * // Get total balance\n * const balance = await coinManager.getTotalBalance(\n * \"0x2::sui::SUI\"\n * );\n *\n * // Select coins for a transaction\n * const selection = await coinManager.selectCoins(\n * \"0x2::sui::SUI\",\n * \"1000000000\", // 1 SUI\n * { minimizeInputs: true }\n * );\n *\n * // Prepare coin input for transaction\n * const tx = new Transaction();\n * const coinInput = await coinManager.prepareCoinInput(\n * tx,\n * \"0x2::sui::SUI\",\n * \"1000000000\"\n * );\n * ```\n *\n * @group Helpers\n */\nexport class CoinManager {\n /**\n * Creates a new CoinManager instance.\n *\n * @param client - The SuiClient instance for blockchain interactions\n * @param defaultOwner - Optional default owner address for coin operations.\n * If not provided, owner must be specified in each method call.\n *\n * @example\n * ```typescript\n * // With default owner\n * const coinManager = new CoinManager(suiClient, \"0x123...\");\n *\n * // Without default owner (must specify in each call)\n * const coinManager = new CoinManager(suiClient);\n * ```\n */\n constructor(\n private client: SuiClient,\n private defaultOwner?: string\n ) {}\n\n /**\n * Fetches all coins of a specific type owned by an address.\n *\n * This method handles pagination automatically to retrieve all coins,\n * regardless of how many exist. Coins are returned in the order\n * provided by the blockchain.\n *\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @returns A promise that resolves to an array of all coins of the specified type\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n *\n * @example\n * ```typescript\n * // Get all SUI coins\n * const suiCoins = await coinManager.getAllCoins(\"0x2::sui::SUI\");\n * console.log(`Found ${suiCoins.length} SUI coins`);\n *\n * // Get all USDC coins for a specific owner\n * const usdcCoins = await coinManager.getAllCoins(\n * \"0x5d4b...::coin::COIN\",\n * \"0xowner...\"\n * );\n *\n * // Display coin details\n * suiCoins.forEach(coin => {\n * console.log(`Coin ID: ${coin.coinObjectId}`);\n * console.log(`Balance: ${coin.balance}`);\n * });\n * ```\n */\n async getAllCoins(coinType: string, owner?: string): Promise<CoinStruct[]> {\n const ownerAddress = this.getOwnerAddress(owner);\n\n // Fetch all coins with pagination\n const allCoins: CoinStruct[] = [];\n let cursor: string | undefined | null;\n\n do {\n const response: PaginatedCoins = await this.client.getCoins({\n owner: ownerAddress,\n coinType,\n cursor,\n });\n\n allCoins.push(...response.data);\n cursor = response.hasNextPage ? response.nextCursor : undefined;\n } while (cursor);\n\n return allCoins;\n }\n\n /**\n * Resolves the owner address from the provided parameter or default.\n *\n * This is a helper method used internally to ensure an owner address\n * is always available for coin operations.\n *\n * @param owner - Optional owner address to use\n *\n * @returns The resolved owner address\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n *\n * @example\n * ```typescript\n * // With default owner set\n * const address = coinManager.getOwnerAddress(); // Returns defaultOwner\n *\n * // With explicit owner\n * const address = coinManager.getOwnerAddress(\"0x123...\"); // Returns \"0x123...\"\n *\n * // Without default owner or parameter\n * const address = coinManager.getOwnerAddress(); // Throws MissingParameterError\n * ```\n */\n getOwnerAddress(owner?: string): string {\n const address = owner || this.defaultOwner;\n if (!address) throw new MissingParameterError('owner');\n\n return address;\n }\n\n /**\n * Gets the total balance of a specific coin type for an owner.\n *\n * This method returns the sum of all coins of the specified type,\n * providing a quick way to check if sufficient funds are available\n * without fetching all coin objects.\n *\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @returns A promise that resolves to the total balance as a string\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n *\n * @example\n * ```typescript\n * // Get SUI balance\n * const suiBalance = await coinManager.getTotalBalance(\"0x2::sui::SUI\");\n * console.log(`Total SUI: ${suiBalance}`);\n *\n * // Get USDC balance for specific owner\n * const usdcBalance = await coinManager.getTotalBalance(\n * \"0x5d4b...::coin::COIN\",\n * \"0xowner...\"\n * );\n *\n * // Convert to decimal for display (assuming 9 decimals for SUI)\n * const suiDecimal = Number(suiBalance) / 1e9;\n * console.log(`${suiDecimal} SUI`);\n * ```\n */\n async getTotalBalance(coinType: string, owner?: string): Promise<string> {\n const ownerAddress = this.getOwnerAddress(owner);\n\n const balance = await this.client.getBalance({\n owner: ownerAddress,\n coinType,\n });\n\n return balance.totalBalance;\n }\n\n /**\n * Asserts that the owner has sufficient balance for a transaction.\n *\n * This is a convenience method that checks the balance and throws\n * a descriptive error if insufficient. Useful for fail-fast validation\n * before attempting complex transaction preparation.\n *\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param amount - The required amount as a string\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n * @throws {InsufficientFundsError} When the balance is less than the required amount\n *\n * @example\n * ```typescript\n * try {\n * // Check if user has 1 SUI\n * await coinManager.assertEnoughBalance(\n * \"0x2::sui::SUI\",\n * \"1000000000\" // 1 SUI\n * );\n *\n * // Proceed with transaction\n * console.log(\"Sufficient balance confirmed\");\n * } catch (error) {\n * if (error instanceof InsufficientFundsError) {\n * console.error(`Need ${error.data.amount}, but only have ${error.data.available}`);\n * }\n * }\n * ```\n */\n async assertEnoughBalance(coinType: string, amount: string, owner?: string): Promise<void> {\n const ownerAddress = this.getOwnerAddress(owner);\n\n const totalBalance = await this.getTotalBalance(coinType, owner);\n\n if (BigInt(totalBalance) < BigInt(amount)) {\n throw new InsufficientFundsError(amount, totalBalance, { coinType, amount, ownerAddress });\n }\n }\n\n /**\n * Selects optimal coins to cover a specific amount.\n *\n * This method implements intelligent coin selection algorithms that consider\n * various factors like minimizing inputs, preserving large coins, and\n * avoiding fragmentation. It determines whether merging or splitting is needed.\n *\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param amount - The target amount to select for, as a string\n * @param options - Configuration options for the selection algorithm\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @returns A promise that resolves to a CoinSelectionResult with selected coins and metadata\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n * @throws {InsufficientFundsError} When available coins cannot cover the amount (unless allowPartial is true)\n *\n * @example\n * ```typescript\n * // Basic selection\n * const selection = await coinManager.selectCoins(\n * \"0x2::sui::SUI\",\n * \"1000000000\" // 1 SUI\n * );\n *\n * if (selection.requiresMerge) {\n * console.log(`Need to merge ${selection.coins.length} coins`);\n * }\n * if (selection.requiresSplit) {\n * console.log(`Need to split coin for exact amount`);\n * }\n *\n * // Minimize number of inputs\n * const minimalSelection = await coinManager.selectCoins(\n * \"0x2::sui::SUI\",\n * \"5000000000\",\n * { minimizeInputs: true }\n * );\n *\n * // Exclude specific coins and allow partial\n * const partialSelection = await coinManager.selectCoins(\n * \"0x2::sui::SUI\",\n * \"10000000000\",\n * {\n * excludeIds: [\"0x123...\"],\n * allowPartial: true\n * }\n * );\n * ```\n *\n * @remarks\n * The selection algorithm follows these priorities:\n * 1. Exact match - single coin with exact amount\n * 2. Single coin that covers amount (requires split)\n * 3. Multiple coins (requires merge, possibly split)\n *\n * When minimizeInputs is false, smaller coins are used first to preserve larger ones.\n */\n async selectCoins(\n coinType: string,\n amount: string,\n options: CoinSelectionOptions = {},\n owner?: string\n ): Promise<CoinSelectionResult> {\n const ownerAddress = this.getOwnerAddress(owner);\n const coins = await this.getAllCoins(coinType, owner);\n\n // Filter out excluded coins\n const availableCoins = options.excludeIds\n ? coins.filter((c) => !options.excludeIds?.includes(c.coinObjectId))\n : coins;\n\n if (availableCoins.length === 0) {\n throw new InsufficientFundsError(amount, '0', {\n availableCoins,\n coinType,\n ownerAddress,\n });\n }\n\n const targetAmount = BigInt(amount);\n\n // Sort by balance (largest first)\n availableCoins.sort((a, b) => {\n const diff = BigInt(b.balance) - BigInt(a.balance);\n return diff > 0n ? 1 : diff < 0n ? -1 : 0;\n });\n\n // Check for exact match\n const exactMatch = availableCoins.find((c) => BigInt(c.balance) === targetAmount);\n if (exactMatch) {\n return {\n coins: [exactMatch],\n totalBalance: amount,\n requiresMerge: false,\n requiresSplit: false,\n };\n }\n\n // Check for single coin that can cover amount\n const singleCoin = availableCoins.find((c) => BigInt(c.balance) > targetAmount);\n if (singleCoin && !options.preferMerge) {\n return {\n coins: [singleCoin],\n totalBalance: singleCoin.balance,\n requiresMerge: false,\n requiresSplit: true,\n };\n }\n\n // Need multiple coins\n const selectedCoins: CoinStruct[] = [];\n let totalBalance = 0n;\n\n if (options.minimizeInputs) {\n // Try to minimize number of coins used\n for (const coin of availableCoins) {\n selectedCoins.push(coin);\n totalBalance += BigInt(coin.balance);\n if (totalBalance >= targetAmount) break;\n }\n } else {\n // Use smallest coins first to preserve larger coins\n const sortedAsc = [...availableCoins].sort((a, b) => {\n const diff = BigInt(a.balance) - BigInt(b.balance);\n return diff > 0n ? 1 : diff < 0n ? -1 : 0;\n });\n\n for (const coin of sortedAsc) {\n if (totalBalance >= targetAmount) break;\n selectedCoins.push(coin);\n totalBalance += BigInt(coin.balance);\n }\n }\n\n // Check if we have enough\n if (totalBalance < targetAmount) {\n if (options.allowPartial) {\n return {\n coins: selectedCoins,\n totalBalance: totalBalance.toString(),\n requiresMerge: selectedCoins.length > 1,\n requiresSplit: false,\n };\n }\n\n throw new InsufficientFundsError(amount, totalBalance.toString(), {\n amount,\n coinType,\n totalBalance: totalBalance.toString(),\n ownerAddress,\n });\n }\n\n return {\n coins: selectedCoins,\n totalBalance: totalBalance.toString(),\n requiresMerge: selectedCoins.length > 1,\n requiresSplit: totalBalance > targetAmount,\n };\n }\n\n /**\n * Prepares a coin input for a transaction with automatic merging and splitting.\n *\n * This is the main method for transaction preparation. It handles all the complexity\n * of coin selection, merging multiple coins if needed, and splitting for exact amounts.\n * Special handling is provided for SUI gas coins.\n *\n * @param tx - The Transaction object to add coin operations to\n * @param coinType - The fully qualified type of the coin (e.g., \"0x2::sui::SUI\")\n * @param amount - The exact amount needed for the transaction, as a string\n * @param options - Configuration options for coin selection\n * @param owner - Optional owner address. Uses defaultOwner if not provided.\n *\n * @returns A promise that resolves to an Argument that can be used in Move calls\n *\n * @throws {MissingParameterError} When owner is not provided and no defaultOwner is set\n * @throws {InsufficientFundsError} When available coins cannot cover the amount\n *\n * @example\n * ```typescript\n * const tx = new Transaction();\n *\n * // Prepare exact SUI amount (uses gas coin)\n * const suiCoin = await coinManager.prepareCoinInput(\n * tx,\n * \"0x2::sui::SUI\",\n * \"1000000000\" // 1 SUI\n * );\n *\n * // Prepare custom coin with options\n * const customCoin = await coinManager.prepareCoinInput(\n * tx,\n * \"0x5d4b...::coin::COIN\",\n * \"1000000\", // 1 USDC\n * {\n * minimizeInputs: true,\n * excludeIds: [\"0x123...\"]\n * }\n * );\n *\n * // Use in a Move call\n * tx.moveCall({\n * target: `${packageId}::module::swap`,\n * arguments: [suiCoin, customCoin],\n * });\n * ```\n *\n * @remarks\n * - SUI coins are handled specially by splitting from the gas coin\n * - Single coins matching the exact amount are used directly\n * - Multiple coins are automatically merged\n * - Coins with excess balance are automatically split\n * - The resulting Argument can be used directly in Move calls\n */\n async prepareCoinInput(\n tx: Transaction,\n coinType: string,\n amount: string,\n options: CoinSelectionOptions = {},\n owner?: string\n ): Promise<Argument> {\n const ownerAddress = this.getOwnerAddress(owner);\n\n // Handle SUI specially\n if (coinType === SUI_TYPE_ARG) {\n const [coin] = tx.splitCoins(tx.gas, [amount]);\n return coin;\n }\n\n // Select coins\n const selection = await this.selectCoins(coinType, amount, options, owner);\n\n if (!selection.coins[0]) {\n throw new InsufficientFundsError(amount, '0', {\n coinType,\n amount,\n ownerAddress,\n });\n }\n\n // Single coin, exact amount\n if (selection.coins.length === 1 && !selection.requiresSplit) {\n return tx.object(selection.coins[0].coinObjectId);\n }\n\n // Single coin, needs split\n if (selection.coins.length === 1 && selection.requiresSplit) {\n const [split] = tx.splitCoins(tx.object(selection.coins[0].coinObjectId), [amount]);\n return split;\n }\n\n // Multiple coins, need merge\n const primaryCoin = tx.object(selection.coins[0].coinObjectId);\n const mergeCoins = selection.coins.slice(1).map((c) => tx.object(c.coinObjectId));\n\n tx.mergeCoins(primaryCoin, mergeCoins);\n\n // Split if needed\n if (selection.requiresSplit) {\n const [split] = tx.splitCoins(primaryCoin, [amount]);\n return split;\n }\n\n return primaryCoin;\n }\n}\n","import { type Address, TransactionFailedError, UnexpectedError } from '@bolt-liquidity-hq/core';\nimport type { SerializedBcs } from '@mysten/bcs';\nimport type { DevInspectResults, SuiClient } from '@mysten/sui/client';\nimport { Transaction } from '@mysten/sui/transactions';\n\nimport { ZERO_ADDRESS } from '../constants';\n\n/**\n * Executes a read-only query against a Sui Move function using devInspect.\n *\n * This function allows you to call Move functions without committing a transaction\n * to the blockchain. It's perfect for querying contract state, simulating transactions,\n * or getting computed values from view functions. The devInspect feature runs the\n * transaction in a sandboxed environment and returns the results without any state changes.\n *\n * @param suiClient - The SuiClient instance used to interact with the Sui network\n * @param target - The Move function to call, either as:\n * - A string in the format \"packageId::module::function\"\n * - A tuple of [packageId, module, function]\n * @param args - Optional array of arguments to pass to the Move function. Each argument can be:\n * - A string representing an object ID (will be passed as an object reference)\n * - A SerializedBcs object containing pre-serialized BCS data (will be passed as a pure value)\n * @param typeArguments - Optional array of type arguments for generic Move functions\n * @param senderAddress - Optional sender address for the simulated transaction.\n * Defaults to ZERO_ADDRESS if not provided. Some functions may require a specific\n * sender to check permissions or balances.\n *\n * @returns A promise that resolves to DevInspectResults containing:\n * - effects: Transaction effects showing gas costs and object changes\n * - events: Events that would be emitted by the transaction\n * - results: Array of results with return values from the Move function\n * - error: Any execution errors (if status is not 'success')\n *\n * @throws {TransactionFailedError} When the Move function execution fails\n * @throws {UnexpectedError} When there's a network error or other unexpected failure\n *\n * @example\n * ```typescript\n * // Query a simple getter function\n * const result = await queryDevInspect(\n * suiClient,\n * `${packageId}::oracle::get_price`,\n * [baseAssetId, quoteAssetId]\n * );\n *\n * // Query with type arguments\n * const balanceResult = await queryDevInspect(\n * suiClient,\n * [packageId, \"pool\", \"get_balance\"],\n * [poolObjectId],\n * [\"0x2::sui::SUI\"] // Type argument for the coin type\n * );\n *\n * // Query with serialized BCS arguments\n * const amountBcs = bcs.u64().serialize(1000000).toBytes();\n * const swapResult = await queryDevInspect(\n * suiClient,\n * `${packageId}::router::get_amount_out`,\n * [amountBcs, poolObjectId],\n * undefined,\n * userAddress // Use actual user address for more specific simulation\n * );\n *\n * // Parse the results\n * if (result.effects.status.status === 'success') {\n * const returnValue = result.results?.[0]?.returnValues?.[0];\n * if (returnValue) {\n * const price = bcs.u64().parse(new Uint8Array(returnValue[0]));\n * }\n * }\n * ```\n *\n * @remarks\n * - devInspect is read-only and cannot modify blockchain state\n * - Gas is still calculated but not charged\n * - Object modifications are simulated but not persisted\n * - Some functions may behave differently in devInspect vs actual execution\n * - The ZERO_ADDRESS default sender may not work for functions that check ownership\n */\nexport const queryDevInspect = async (\n suiClient: SuiClient,\n target: string | [string, string, string],\n args?: (SerializedBcs<unknown> | string)[],\n typeArguments?: string[],\n senderAddress?: Address\n): Promise<DevInspectResults> => {\n const tx = new Transaction();\n\n const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;\n\n const txArgs = args?.map((item) =>\n typeof item === 'string' ? tx.object(item) : tx.pure(item.toBytes())\n );\n\n tx.moveCall({\n target: targetString,\n arguments: txArgs,\n typeArguments,\n });\n\n try {\n // Use devInspectTransactionBlock to execute without submitting to chain\n const result = await suiClient.devInspectTransactionBlock({\n transactionBlock: tx,\n sender: senderAddress ?? ZERO_ADDRESS,\n });\n\n // Process the results\n if (result.effects.status.status === 'success') {\n return result;\n } else {\n throw new TransactionFailedError('N/A', 'Failed to query smart contract', { result });\n }\n } catch (error) {\n throw UnexpectedError.from(error, 'Failed to query smart contract', {\n target: targetString,\n args,\n typeArguments,\n });\n }\n};\n","import type { Address, Coin, SwapParams } from '@bolt-liquidity-hq/core';\nimport {\n DEFAULT_GAS_ADJUSTMENT,\n NotFoundError,\n TransactionFailedError,\n UnexpectedError,\n} from '@bolt-liquidity-hq/core';\nimport { bcs, type SerializedBcs } from '@mysten/bcs';\nimport type {\n SuiClient,\n SuiTransactionBlockResponse,\n SuiTransactionBlockResponseOptions,\n} from '@mysten/sui/client';\nimport type { Signer } from '@mysten/sui/cryptography';\nimport { Transaction, type TransactionArgument } from '@mysten/sui/transactions';\nimport { normalizeStructTag, SUI_CLOCK_OBJECT_ID, SUI_TYPE_ARG } from '@mysten/sui/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport type { BoltSuiClient } from '../client';\nimport { CoinManager } from './coin-manager';\nimport { ROUTER_MODULE } from '../constants';\n\n/**\n * Builds the transaction arguments for a swap operation on the Bolt protocol.\n *\n * This helper function prepares all necessary components for executing a swap transaction,\n * including pool discovery, swap direction determination, coin preparation, and argument\n * serialization. It abstracts the complexity of building swap transactions by handling\n * the differences between sell and buy operations automatically.\n *\n * @param client - The BoltSuiClient instance containing configuration and contracts\n * @param swapParams - The swap parameters\n * @param swapParams.assetIn - The type of the asset being sold (e.g., \"0x2::sui::SUI\")\n * @param swapParams.amountIn - The exact amount of input asset to swap (in minimal denomination)\n * @param swapParams.assetOut - The type of the asset being bought\n * @param swapParams.minimumAmountOut - Optional minimum acceptable amount of output asset\n * @param swapParams.receiver - Optional recipient address for the swapped assets\n * @param signer - Optional signer for the transaction. If not provided, uses the client's cached signer\n *\n * @returns A promise that resolves to an object containing:\n * - signer: The resolved Signer instance that will sign the transaction\n * - target: Tuple of [packageId, module, function] for the Move call\n * - args: Array of prepared transaction arguments\n * - typeArguments: Array of type arguments ordered based on swap direction\n * - tx: The Transaction object with prepared coin operations\n *\n * @throws {NotFoundError} When no pool exists for the specified asset pair\n * @throws {MissingParameterError} When no signer is available\n *\n * @example\n * ```typescript\n * const client = new BoltSuiClient();\n * const signer = // ... obtain signer from wallet\n *\n * // Build swap transaction arguments\n * const txArgs = await buildSwapTxArgs(\n * client,\n * {\n * assetIn: \"0x2::sui::SUI\",\n * amountIn: \"1000000000\", // 1 SUI\n * assetOut: \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\",\n * minimumAmountOut: \"1950000\" // Min 1.95 USDC\n * },\n * signer\n * );\n *\n * // Use the prepared arguments to execute the transaction\n * const result = await signAndExecuteTx(\n * client.suiClient,\n * txArgs.signer,\n * txArgs.target,\n * txArgs.args,\n * txArgs.typeArguments,\n * txArgs.tx\n * );\n * ```\n */\nexport const buildSwapTxArgs = async (\n client: BoltSuiClient,\n swapParams: SwapParams,\n signer?: Signer\n): Promise<{\n signer: Signer;\n target: [string, string, string];\n args?: (TransactionArgument | SerializedBcs<unknown> | string)[];\n typeArguments?: string[];\n tx?: Transaction;\n}> => {\n const { assetIn, amountIn, assetOut, minimumAmountOut, receiver } = swapParams;\n const pool = client.routerClient.getPool(assetIn, assetOut);\n\n if (!pool) {\n throw new NotFoundError(`Pool for the pair ${assetIn}/${assetOut}`);\n }\n\n const isSell = normalizeStructTag(assetIn) === pool.baseDenom;\n\n const FUNCTION_NAME = isSell ? 'swap_sell' : 'swap_buy';\n\n const finalSigner = client.getSigner(signer);\n\n const tx = new Transaction();\n\n const coinManager = new CoinManager(client.suiClient, finalSigner.toSuiAddress());\n\n const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);\n\n return {\n signer: finalSigner,\n target: [client.packageId, ROUTER_MODULE, FUNCTION_NAME],\n args: [\n pool.poolAddress,\n client.contracts.oracle,\n SUI_CLOCK_OBJECT_ID,\n coinInput,\n bcs.u64().serialize(amountIn),\n bcs.option(bcs.string()).serialize(minimumAmountOut),\n bcs.option(bcs.string()).serialize(receiver),\n ],\n typeArguments: [isSell ? assetIn : assetOut, isSell ? assetOut : assetIn],\n tx,\n };\n};\n\n/**\n * Signs and executes a transaction on the Sui blockchain.\n *\n * This function builds, signs, and submits a transaction to the Sui network. It provides\n * a convenient wrapper around the Sui SDK's transaction building and execution flow,\n * handling argument serialization and error cases. The function supports calling any\n * Move function on Sui with proper type arguments and parameters.\n *\n * @param suiClient - The SuiClient instance used to interact with the Sui network\n * @param signer - The Signer instance (e.g., Ed25519Keypair) used to sign the transaction\n * @param target - The Move function to call, either as:\n * - A string in the format \"packageId::module::function\"\n * - A tuple of [packageId, module, function]\n * @param args - Optional array of arguments to pass to the Move function. Each argument can be:\n * - A string representing an object ID (will be passed as an object reference)\n * - A SerializedBcs object containing pre-serialized BCS data (will be passed as a pure value)\n * - A TransactionArgument created by the Transaction builder\n * @param typeArguments - Optional array of type arguments for generic Move functions.\n * These are fully qualified type names like \"0x2::sui::SUI\"\n * @param transaction - Optional pre-existing Transaction object to add the Move call to.\n * If not provided, a new Transaction will be created.\n * @param options - Optional response options to specify what data to include in the response\n * (e.g., effects, events, object changes, balance changes)\n *\n * @returns A promise that resolves to SuiTransactionBlockResponse containing:\n * - digest: The transaction digest (hash)\n * - effects: Transaction effects showing gas costs, created/modified/deleted objects\n * - events: Events emitted during transaction execution\n * - objectChanges: Detailed changes to objects (if requested in options)\n * - balanceChanges: Changes to coin balances (if requested in options)\n *\n * @throws {TransactionFailedError} When the Move function execution fails on-chain\n * @throws {UnexpectedError} When there's a network error, signing error, or other unexpected failure\n *\n * @example\n * ```typescript\n * // Simple transfer\n * const result = await signAndExecuteTx(\n * suiClient,\n * keypair,\n * '0x2::coin::transfer',\n * [coinObjectId, recipientAddress],\n * ['0x2::sui::SUI']\n * );\n *\n * // Call a swap function with serialized amount\n * const amountBcs = bcs.u64().serialize(1000000).toBytes();\n * const swapResult = await signAndExecuteTx(\n * suiClient,\n * keypair,\n * [packageId, 'pool', 'swap'],\n * [poolObjectId, amountBcs],\n * ['0x2::sui::SUI', `${packageId}::usdc::USDC`],\n * undefined,\n * {\n * showEffects: true,\n * showEvents: true,\n * showObjectChanges: true\n * }\n * );\n *\n * // Build a complex transaction\n * const tx = new Transaction();\n * const [coin] = tx.splitCoins(tx.gas, [1000000]);\n * await signAndExecuteTx(\n * suiClient,\n * keypair,\n * `${packageId}::market::place_order`,\n * [marketId, coin, tx.pure.u64(price)],\n * undefined,\n * tx // Pass the existing transaction\n * );\n *\n * // Handle the response\n * if (result.effects?.status.status === 'success') {\n * console.log('Transaction successful:', result.digest);\n * console.log('Gas used:', result.effects.gasUsed);\n *\n * // Process created objects\n * result.effects.created?.forEach(obj => {\n * console.log('Created object:', obj.reference.objectId);\n * });\n * }\n * ```\n */\nexport const signAndExecuteTx = async (\n suiClient: SuiClient,\n signer: Signer,\n target: string | [string, string, string],\n args?: (TransactionArgument | SerializedBcs<unknown> | string)[],\n typeArguments?: string[],\n transaction?: Transaction,\n options?: SuiTransactionBlockResponseOptions\n): Promise<SuiTransactionBlockResponse> => {\n const tx = transaction ?? new Transaction();\n\n const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;\n\n const txArgs = args?.map((item) =>\n typeof item === 'string' ? tx.object(item) : 'toBytes' in item ? tx.pure(item.toBytes()) : item\n );\n\n tx.moveCall({\n target: targetString,\n arguments: txArgs,\n typeArguments,\n });\n\n try {\n const result = await suiClient.signAndExecuteTransaction({\n signer,\n transaction: tx,\n options,\n });\n\n if (result.effects?.status.status === 'success') {\n return result;\n } else {\n throw new TransactionFailedError(result.digest, result.effects?.status.error, { result });\n }\n } catch (error) {\n throw UnexpectedError.from(error, 'Failed to execute transaction', {\n target: targetString,\n args,\n typeArguments,\n });\n }\n};\n\n/**\n * Estimates the gas price for a transaction on the Sui blockchain.\n *\n * This function builds a transaction and performs a dry run to estimate gas costs\n * without actually executing the transaction on-chain. It returns the gas denomination\n * (always 'SUI' for Sui network) and the estimated amount including the gas adjustment\n * multiplier. The sender address is required for accurate gas estimation as it affects\n * object resolution and gas calculations.\n *\n * @param suiClient - The SuiClient instance used to interact with the Sui network\n * @param senderAddress - The Sui address that would send the transaction. This is used for:\n * - Resolving owned objects in the transaction\n * - Calculating accurate gas costs based on the sender's objects\n * - Setting the transaction sender for the dry run\n * @param target - The Move function to call, either as:\n * - A string in the format \"packageId::module::function\"\n * - A tuple of [packageId, module, function]\n * @param args - Optional array of arguments to pass to the Move function. Each argument can be:\n * - A string representing an object ID (will be passed as an object reference)\n * - A SerializedBcs object containing pre-serialized BCS data (will be passed as a pure value)\n * - A TransactionArgument created by the Transaction builder\n * @param typeArguments - Optional array of type arguments for generic Move functions.\n * These are fully qualified type names like \"0x2::sui::SUI\"\n * @param transaction - Optional pre-existing Transaction object to add the Move call to.\n * If not provided, a new Transaction will be created.\n * @param gasAdjustment - Optional multiplier for gas estimation (default: 1.5). Use higher values for\n * safety margin. For example, 1.5 means 50% buffer above estimated gas.\n *\n * @returns A promise that resolves to a Coin object containing:\n * - denom: The gas denomination (always 'SUI' for Sui network)\n * - amount: The estimated gas amount as a string, including the gas adjustment\n * Returns undefined if estimation fails\n *\n * @example\n * ```typescript\n * // Estimate gas for a simple transfer\n * const senderAddress = \"0x123...\";\n * const gasEstimate = await estimateTxGasPrice(\n * suiClient,\n * senderAddress,\n * '0x2::coin::transfer',\n * [coinObjectId, recipientAddress],\n * ['0x2::sui::SUI']\n * );\n * if (gasEstimate) {\n * console.log(`Estimated gas: ${gasEstimate.amount} ${gasEstimate.denom}`);\n * }\n *\n * // Estimate with higher safety margin\n * const safeGasEstimate = await estimateTxGasPrice(\n * suiClient,\n * senderAddress,\n * [packageId, 'pool', 'swap'],\n * [poolObjectId, amountBcs],\n * ['0x2::sui::SUI', `${packageId}::usdc::USDC`],\n * undefined,\n * 2.0 // 100% buffer for complex operations\n * );\n *\n * // Use with existing transaction\n * const tx = new Transaction();\n * const [coin] = tx.splitCoins(tx.gas, [1000000]);\n * const gasPrice = await estimateTxGasPrice(\n * suiClient,\n * senderAddress,\n * `${packageId}::market::place_order`,\n * [marketId, coin, tx.pure.u64(price)],\n * undefined,\n * tx,\n * 1.2\n * );\n * ```\n */\nexport const estimateTxGasPrice = async (\n suiClient: SuiClient,\n senderAddress: Address,\n target: string | [string, string, string],\n args?: (TransactionArgument | SerializedBcs<unknown> | string)[],\n typeArguments?: string[],\n transaction?: Transaction,\n gasAdjustment: number = DEFAULT_GAS_ADJUSTMENT\n): Promise<Coin | undefined> => {\n const tx = transaction ?? new Transaction();\n\n const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;\n\n const txArgs = args?.map((item) =>\n typeof item === 'string' ? tx.object(item) : 'toBytes' in item ? tx.pure(item.toBytes()) : item\n );\n\n tx.moveCall({\n target: targetString,\n arguments: txArgs,\n typeArguments,\n });\n\n tx.setSender(senderAddress);\n\n try {\n // Build the transaction\n const transactionBytes = await tx.build({ client: suiClient });\n\n // Perform dry run to estimate gas\n const dryRunResult = await suiClient.dryRunTransactionBlock({\n transactionBlock: transactionBytes,\n });\n\n if (dryRunResult.effects.status.status !== 'success') {\n throw new UnexpectedError(\n `Dry run failed: ${dryRunResult.effects.status.error}`,\n 'Failed to estimate gas',\n {\n target: targetString,\n args,\n typeArguments,\n error: dryRunResult.effects.status.error,\n }\n );\n }\n\n // Extract gas information from the dry run result\n const gasUsed = dryRunResult.effects.gasUsed;\n\n // Calculate total gas cost (computation + storage - storage rebate)\n const totalGasCost = BigNumber(gasUsed.computationCost)\n .plus(gasUsed.storageCost)\n .minus(gasUsed.storageRebate);\n\n // Apply gas adjustment multiplier\n const adjustedGasCost = totalGasCost.times(gasAdjustment);\n\n return {\n denom: SUI_TYPE_ARG,\n amount: adjustedGasCost.toFixed(0, BigNumber.ROUND_CEIL),\n };\n } catch {\n return;\n }\n};\n","import type {\n InvertiblePrice,\n OracleConfig,\n OracleAssetPair,\n Price,\n} from '@bolt-liquidity-hq/core';\nimport { InvalidObjectError } from '@bolt-liquidity-hq/core';\nimport { BigNumber } from 'bignumber.js';\n\nimport type {\n AssetPairsResponseStructOutput,\n AssetPairStructOutput,\n OracleConfigStructOutput,\n PriceDataStructOutput,\n PriceResponseStructOutput,\n PricesResponsePaginatedStructOutput,\n} from '../../types';\n\n/**\n * Parses a raw oracle configuration response from the Sui blockchain into a structured OracleConfig object.\n *\n * This function transforms the snake_case properties from the Sui Move contract response\n * into camelCase properties following TypeScript conventions. It also converts the\n * price expiry time from seconds to a structured format with seconds and nanoseconds.\n *\n * @param output - The raw oracle configuration response from the contract query\n * @param output.price_threshold_ratio - The maximum allowed price deviation ratio\n * @param output.default_price_expiry_seconds - The default time in seconds before prices expire\n *\n * @returns A parsed OracleConfig object with:\n * - admin: The admin address of the oracle contract\n * - priceThresholdRatio: The threshold ratio for price updates (e.g., \"0.01\" for 1%)\n * - priceExpireTime: Object with seconds and nanoseconds representing expiry duration\n *\n * @example\n * ```typescript\n * const output = {\n * price_threshold_ratio: \"0.01\",\n * default_price_expiry_seconds: \"3600\" // 1 hour\n * };\n *\n * const config = parseOracleConfigStructOutput(output);\n * console.log(config.admin); // \"0x1234...\"\n * console.log(config.priceThresholdRatio); // \"0.01\"\n * console.log(config.priceExpireTime.secs); // 3600\n * ```\n */\nexport const parseOracleConfigStructOutput = (output: OracleConfigStructOutput): OracleConfig => {\n return {\n // TODO: try to query admin somewhere else? to fill empty value\n admin: '',\n priceThresholdRatio: output.price_threshold_ratio,\n priceExpireTime: {\n secs: Number(output.default_price_expiry_seconds),\n nanos: 0,\n },\n };\n};\n\n/**\n * Parses a single asset pair structure from the Sui oracle contract into an OracleAssetPair object.\n *\n * This function converts the raw asset pair data containing base and quote asset information\n * into a structured format.\n *\n * @param output - The raw asset pair data from the contract\n * @param output.base_name - The name of the base asset (e.g., \"SUI\", \"USDC\")\n * @param output.base_precision - The decimal precision of the base asset (e.g., 9 for SUI)\n * @param output.quote_name - The name of the quote asset\n * @param output.quote_precision - The decimal precision of the quote asset\n *\n * @returns An OracleAssetPair object containing:\n * - base: Object with name, symbol, and precision for the base asset\n * - quote: Object with name, symbol, and precision for the quote asset\n *\n * @example\n * ```typescript\n * const rawPair = {\n * base_name: \"SUI\",\n * base_precision: 9,\n * quote_name: \"USDC\",\n * quote_precision: 6\n * };\n *\n * const pair = parseAssetPairStructOutput(rawPair);\n * console.log(pair.base.symbol); // \"SUI\"\n * console.log(pair.base.precision); // 9\n * console.log(pair.quote.name); // \"USDC\"\n * ```\n */\nexport const parseAssetPairStructOutput = (output: AssetPairStructOutput): OracleAssetPair => {\n return {\n base: {\n name: output.base_name,\n // TODO: map a different value for name/symbols\n symbol: output.base_name,\n precision: output.base_precision,\n },\n quote: {\n name: output.quote_name,\n // TODO: map a different value for name/symbols\n symbol: output.quote_name,\n precision: output.quote_precision,\n },\n };\n};\n\n/**\n * Parses a response containing multiple asset pairs from the oracle contract.\n *\n * This function processes an array of asset pairs returned by the oracle's\n * asset_pairs query, where each item contains an 'info' property with the\n * actual pair data.\n *\n * @param output - Array of objects containing asset pair info\n *\n * @returns An array of parsed OracleAssetPair objects\n *\n * @example\n * ```typescript\n * const output = [\n * { info: { base_name: \"SUI\", base_precision: 9, quote_name: \"USDC\", quote_precision: 6 } },\n * { info: { base_name: \"ETH\", base_precision: 18, quote_name: \"USDC\", quote_precision: 6 } }\n * ];\n *\n * const pairs = parseAssetPairsResponseStructOutput(output);\n * console.log(pairs.length); // 2\n * console.log(pairs[0].base.name); // \"SUI\"\n * ```\n */\nexport const parseAssetPairsResponseStructOutput = (\n output: AssetPairsResponseStructOutput\n): OracleAssetPair[] => {\n return output.map((item) => parseAssetPairStructOutput(item.info));\n};\n\n/**\n * Parses raw price data from the oracle contract into an InvertiblePrice object.\n *\n * This function converts the price information including the price value and expiry time.\n * The expiry time is converted from milliseconds to nanoseconds for consistency with\n * the broader system's time representation. The base and quote denominations are\n * provided as parameters rather than being included in the output data.\n *\n * @param output - The raw price data from the contract\n * @param output.price - Object containing the price details\n * @param output.price.price - The price value as a string (to maintain precision)\n * @param output.price.expiry - The price expiry time in milliseconds since Unix epoch\n * @param baseDenom - The denomination of the base asset (e.g., \"0x2::sui::SUI\")\n * @param quoteDenom - The denomination of the quote asset (e.g., \"0xusdcAddress...\")\n *\n * @returns An InvertiblePrice object containing:\n * - baseDenom: The denom of the base token (from parameter)\n * - quoteDenom: The denom of the quote token (from parameter)\n * - price: The price value as a string\n * - expiryTime: The expiry time in nanoseconds as a string\n * - isInverse: Always false (price is not inverted)\n *\n * @example\n * ```typescript\n * const priceData = {\n * price: {\n * price: \"2.5\",\n * expiry: \"1700000000000\" // milliseconds\n * }\n * };\n *\n * const price = parsePriceDataStructOutput(\n * priceData,\n * \"0x2::sui::SUI\",\n * \"0xusdcAddress...\"\n * );\n * console.log(price.price); // \"2.5\"\n * console.log(price.baseDenom); // \"0x2::sui::SUI\"\n * console.log(price.quoteDenom); // \"0xusdcAddress...\"\n * console.log(price.expiryTime); // \"1700000000000000000\" (nanoseconds)\n * ```\n */\nexport const parsePriceDataStructOutput = (\n output: PriceDataStructOutput,\n baseDenom: string,\n quoteDenom: string\n): InvertiblePrice => {\n return {\n baseDenom: baseDenom,\n quoteDenom: quoteDenom,\n price: output.price.price,\n expiryTime: BigNumber(output.price.expiry).times(1_000_000).toFixed(),\n isInverse: false,\n };\n};\n\n/**\n * Parses a price response from the oracle contract, extracting the price data if available.\n *\n * This function handles the response from price queries which may or may not contain\n * valid price data. It checks for the presence of pair_data and throws an error\n * if the price is not available. The base and quote denominations must be provided\n * as they are not included in the response data.\n *\n * @param output - The price response from the oracle contract\n * @param output.pair_data - Optional price data for the requested pair\n * @param baseDenom - The denomination of the base asset\n * @param quoteDenom - The denomination of the quote asset\n *\n * @returns An InvertiblePrice object with the parsed price information\n *\n * @throws {InvalidObjectError} When pair_data is not present in the response,\n * indicating that no price is available for the requested pair\n *\n * @example\n * ```typescript\n * // Successful response with price data\n * const output = {\n * pair_data: {\n * price: {\n * price: \"2.5\",\n * expiry: \"1700000000000\"\n * }\n * }\n * };\n *\n * const price = parsePriceResponseStructOutput(\n * output,\n * \"0x2::sui::SUI\",\n * \"0xusdcAddress...\"\n * );\n * console.log(price.price); // \"2.5\"\n *\n * // Response without price data\n * const emptyOutput = { pair_data: null };\n * // This will throw InvalidObjectError\n * ```\n */\nexport const parsePriceResponseStructOutput = (\n output: PriceResponseStructOutput,\n baseDenom: string,\n quoteDenom: string\n): InvertiblePrice => {\n if (!output.pair_data) {\n throw new InvalidObjectError(\"Can't find pair data price\");\n }\n\n return parsePriceDataStructOutput(output.pair_data, baseDenom, quoteDenom);\n};\n\n/**\n * Parses a paginated response containing multiple prices from the oracle contract.\n *\n * This function processes bulk price data that may be returned from queries\n * for all available prices in the oracle.\n *\n * @param output - The paginated response containing price data\n * @param output.prices - Array of raw price data objects\n *\n * @returns An array of parsed Price objects\n *\n * @example\n * ```typescript\n * const paginatedPrices = {\n * prices: [\n * { price: { price: \"2.5\", expiry: \"1700000000000\" } },\n * { price: { price: \"1800\", expiry: \"1700000000000\" } }\n * ],\n * // Additional pagination fields would be here\n * };\n *\n * const prices = parsePricesResponsePaginatedStructOutput(paginatedPrices);\n * console.log(prices.length); // 2\n * console.log(prices[0].price); // \"2.5\"\n * ```\n */\nexport const parsePricesResponsePaginatedStructOutput = (\n output: PricesResponsePaginatedStructOutput\n): Price[] => {\n // TODO: Fix when we have a way to test getting all the prices\n return output.prices.map((item) => parsePriceDataStructOutput(item, '', ''));\n};\n","import { bcs, BcsType } from '@mysten/bcs';\n\nexport const PaginationStruct = {\n total_count: bcs.u64(),\n has_next_page: bcs.bool(),\n next_cursor: bcs.option(bcs.string()),\n};\n\nexport const BcsAddressType = new BcsType({\n name: 'address',\n\n read(reader) {\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) {\n bytes[i] = reader.read8();\n }\n return (\n '0x' +\n Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n );\n },\n\n write(value, writer) {\n // Remove 0x prefix if present\n const hex = value.startsWith('0x') ? value.slice(2) : value;\n // Pad to 64 characters (32 bytes)\n const paddedHex = hex.padStart(64, '0');\n\n for (let i = 0; i < 32; i++) {\n const byte = parseInt(paddedHex.substr(i * 2, 2), 16);\n writer.write8(byte);\n }\n },\n});\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type BcsParsed<T extends BcsType<any, any>> = ReturnType<T['parse']>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type BcsParsedMultiple<T extends readonly BcsType<any>[]> = {\n [K in keyof T]: BcsParsed<T[K]>;\n};\n","import { bcs } from '@mysten/bcs';\n\nimport { BcsAddressType, PaginationStruct, type BcsParsed } from './bcs';\n\nexport const OracleConfigStruct = bcs.struct('Config', {\n price_threshold_ratio: bcs.u64(),\n default_price_expiry_seconds: bcs.u64(),\n});\nexport type OracleConfigStructOutput = BcsParsed<typeof OracleConfigStruct>;\n\nexport const AssetPairStruct = bcs.struct('AssetPair', {\n base_name: bcs.string(),\n quote_name: bcs.string(),\n base_precision: bcs.u8(),\n quote_precision: bcs.u8(),\n});\nexport type AssetPairStructOutput = BcsParsed<typeof AssetPairStruct>;\n\nexport const TypeNameStruct = bcs.struct('TypeName', {\n name: bcs.string(),\n});\nexport type TypeNameStructOutput = BcsParsed<typeof TypeNameStruct>;\n\nexport const RawPairStruct = bcs.struct('RawPair', {\n base: TypeNameStruct,\n quote: TypeNameStruct,\n});\nexport type RawPairStructOutput = BcsParsed<typeof RawPairStruct>;\n\nexport const AssetPairResponseStruct = bcs.struct('AssetPairResponse', {\n pair: RawPairStruct,\n info: AssetPairStruct,\n});\nexport type AssetPairResponseStructOutput = BcsParsed<typeof AssetPairResponseStruct>;\n\nexport const AssetPairsResponseStruct = bcs.vector(AssetPairResponseStruct);\nexport type AssetPairsResponseStructOutput = BcsParsed<typeof AssetPairsResponseStruct>;\n\nexport const RawPriceStruct = bcs.struct('RawPrice', {\n price: bcs.u128(),\n expiry: bcs.u64(),\n});\nexport type RawPriceStructOutput = BcsParsed<typeof RawPriceStruct>;\n\nexport const PriceDataStruct = bcs.struct('PriceData', {\n price: RawPriceStruct,\n last_updated_ms: bcs.u64(),\n updater: BcsAddressType,\n});\nexport type PriceDataStructOutput = BcsParsed<typeof PriceDataStruct>;\n\nexport const PriceResponseStruct = bcs.struct('PriceResponse', {\n pair_data: bcs.option(PriceDataStruct),\n});\nexport type PriceResponseStructOutput = BcsParsed<typeof PriceResponseStruct>;\n\nexport const PricesResponsePaginatedStruct = bcs.struct('PricesResponsePaginated', {\n prices: bcs.vector(PriceDataStruct),\n ...PaginationStruct,\n});\nexport type PricesResponsePaginatedStructOutput = BcsParsed<typeof PricesResponsePaginatedStruct>;\n","import { bcs } from '@mysten/bcs';\n\nimport { BcsAddressType, type BcsParsed, PaginationStruct } from './bcs';\n\nexport const RouterConfigStruct = bcs.struct('Config', {\n admin: BcsAddressType,\n default_price_oracle_contract: BcsAddressType,\n default_protocol_fee_recipient: BcsAddressType,\n default_protocol_fee: bcs.u64(),\n default_lp_fee: bcs.u64(),\n});\nexport type RouterConfigStructOutput = BcsParsed<typeof RouterConfigStruct>;\n\nexport const MarketStruct = bcs.struct('Market', {\n base_asset_symbol: bcs.string(),\n quote_assets_symbols: bcs.vector(bcs.string()),\n market_address: bcs.string(),\n is_permissioned: bcs.bool(),\n created_at_ms: bcs.u64(),\n});\nexport type MarketStructOutput = BcsParsed<typeof MarketStruct>;\n\nexport const MarketResponseStruct = bcs.struct('MarketResponse', {\n market: bcs.option(MarketStruct),\n});\nexport type MarketResponseStructOutput = BcsParsed<typeof MarketResponseStruct>;\n\nexport const MarketsResponseStruct = bcs.struct('MarketsResponse', {\n markets: bcs.vector(MarketStruct),\n});\nexport type MarketsResponseStructOutput = BcsParsed<typeof MarketsResponseStruct>;\n\nexport const MarketsResponsePaginatedStruct = bcs.struct('MarketsResponsePaginated', {\n markets: bcs.vector(MarketStruct),\n ...PaginationStruct,\n});\nexport type MarketsResponsePaginatedStructOutput = BcsParsed<typeof MarketsResponsePaginatedStruct>;\n\nexport const BaseLiquidityInfoStruct = bcs.struct('BaseLiquidityInfo', {\n denom: bcs.string(),\n amount: bcs.u64(),\n});\nexport type BaseLiquidityInfoStructOutput = BcsParsed<typeof BaseLiquidityInfoStruct>;\n\nexport const BaseLiquidityResponseStruct = bcs.struct('BaseLiquidityResponse', {\n base_assets: bcs.vector(BaseLiquidityInfoStruct),\n ...PaginationStruct,\n});\nexport type BaseLiquidityResponseStructOutput = BcsParsed<typeof BaseLiquidityResponseStruct>;\n","import { bcs } from '@mysten/bcs';\n\nimport { BcsAddressType, type BcsParsed } from './bcs';\n\nexport const PoolInfoStruct = bcs.struct('PoolInfo', {\n base_liquidity: bcs.u64(),\n total_lp_shares: bcs.u64(),\n admin: BcsAddressType,\n is_paused: bcs.bool(),\n});\nexport type PoolInfoStructOutput = BcsParsed<typeof PoolInfoStruct>;\n\nexport const PoolFeesInfoStruct = bcs.struct('PoolFeesInfo', {\n swap_fee_pct: bcs.u64(),\n lp_withdrawal_fee_pct: bcs.u64(),\n lp_fee_pct: bcs.u64(),\n});\nexport type PoolFeesInfoStructOutput = BcsParsed<typeof PoolFeesInfoStruct>;\n\nexport const ProtocolFeesInfoStruct = bcs.struct('ProtocolFeesInfo', {\n bolt_fee_addr: BcsAddressType,\n swap_fee_pct: bcs.u64(),\n lp_withdrawal_fee_pct: bcs.u64(),\n});\nexport type ProtocolFeesInfoStructOutput = BcsParsed<typeof ProtocolFeesInfoStruct>;\n","import type { OracleAssetPair } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\nimport { PRICE_ORACLE_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseAssetPairsResponseStructOutput } from './parsers';\nimport { AssetPairsResponseStruct } from '../../types';\n\n/**\n * Queries the oracle smart contract to retrieve all supported asset pairs.\n *\n * This function fetches the complete list of trading pairs that the oracle contract\n * supports for price feeds. Each asset pair represents a base/quote relationship\n * that can be used for price queries and swaps within the Bolt protocol.\n *\n * @param client - The BoltSuiClient instance.\n *\n * @returns A promise that resolves to an array of OracleAssetPair objects, each containing:\n * - base: Information about the base asset\n * - name: The full name of the base asset (currently same as symbol)\n * - symbol: The trading symbol (e.g., \"SUI\", \"ETH\")\n * - precision: The number of decimal places for the base asset\n * - quote: Information about the quote asset\n * - name: The full name of the quote asset (currently same as symbol)\n * - symbol: The trading symbol (e.g., \"USDC\", \"USDT\")\n * - precision: The number of decimal places for the quote asset\n *\n * @throws {TransactionFailedError} When the oracle contract query fails, which could happen if:\n * - The oracle contract is not properly initialized\n * - The contract address is incorrect\n * - Network connection issues occur\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - The contract returned data in an unexpected format\n * - The BCS deserialization failed\n * - The contract ABI has changed\n */\nexport const getAssetPairs = async (client: BoltSuiClient): Promise<OracleAssetPair[]> => {\n /**\n * The Move function name in the oracle module that returns all asset pairs.\n * This function signature in Move:\n * public fun asset_pairs(oracle: &Oracle): AssetPairsResponse\n */\n const ASSET_PAIRS_FUNCTION = 'asset_pairs';\n\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, PRICE_ORACLE_MODULE, ASSET_PAIRS_FUNCTION],\n [client.contracts.oracle]\n );\n\n const output = parseDevInspectResult(response, AssetPairsResponseStruct);\n\n return parseAssetPairsResponseStructOutput(output);\n};\n","import type { Asset, OracleAsset } from '@bolt-liquidity-hq/core';\nimport { normalizeStructTag } from '@mysten/sui/utils';\n\nimport type { BoltSuiClient } from '../client';\n\n/**\n * Retrieves all unique assets available in the Bolt protocol by querying oracle asset pairs\n * and enriching them with additional metadata from the client's asset configuration.\n *\n * This function performs the following operations:\n * 1. Fetches all oracle asset pairs from the blockchain\n * 2. Extracts unique assets from both base and quote positions\n * 3. Maps oracle assets to full Asset objects using client configuration\n * 4. Provides fallback values for assets not found in the configuration\n *\n * @param client - The BoltSuiClient instance used to query the blockchain\n * and access asset configuration.\n *\n * @returns A promise that resolves to an array of Asset objects, each containing:\n * - symbol: The asset's trading symbol (e.g., \"SUI\", \"USDC\")\n * - name: The full name of the asset (e.g., \"Sui\", \"USD Coin\")\n * - chainId: The blockchain network identifier (e.g., \"sui-mainnet\")\n * - denom: The chain-specific denomination (e.g., \"0x2::sui::SUI\")\n * - decimals: The number of decimal places for precision\n * - logo: Optional URL to the asset's logo image\n * - coingeckoId: Optional CoinGecko identifier for market data integration\n *\n * @throws {TransactionFailedError} When the oracle contract query fails\n * @throws {ParseError} When the oracle response cannot be properly parsed\n * @throws {UnexpectedError} When network issues prevent the query from completing\n */\nexport const getAssets = async (client: BoltSuiClient): Promise<Asset[]> => {\n // Fetch all trading pairs from the oracle to discover available assets\n const assetPairs = await client.getAllOracleAssetPairs();\n\n /**\n * Map to store unique assets by symbol.\n * This ensures each asset appears only once in the final result,\n * even if it appears in multiple trading pairs.\n */\n const uniqueOracleAssets: Record<string, OracleAsset> = {};\n\n // Extract unique assets from all trading pairs\n for (const item of assetPairs) {\n uniqueOracleAssets[item.base.symbol] = item.base;\n uniqueOracleAssets[item.quote.symbol] = item.quote;\n }\n\n return Object.values(uniqueOracleAssets).map(\n (item) =>\n client.assetsConfig[item.symbol] ??\n // Fallback to minimal asset data from oracle\n {\n symbol: item.name,\n name: item.name,\n chainId: client.chainConfig.id,\n denom: normalizeStructTag(item.symbol),\n decimals: item.precision,\n logo: undefined,\n coingeckoId: undefined,\n }\n );\n};\n","import type { OracleConfig } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\nimport { PRICE_ORACLE_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseOracleConfigStructOutput } from './parsers';\nimport { OracleConfigStruct } from '../../types';\n\n/**\n * Queries the oracle smart contract to retrieve its current configuration settings.\n *\n * This function fetches the oracle's configuration parameters which govern how\n * price feeds are managed, including expiration times, update thresholds, and\n * administrative settings. The configuration is essential for understanding\n * oracle behavior and constraints when working with price feeds.\n *\n * @param client - The BoltSuiClient instance\n *\n * @returns A promise that resolves to an OracleConfig object containing:\n * - admin: The Sui address authorized to update oracle settings and prices\n * - priceThresholdRatio: The minimum price change ratio required for updates\n * (e.g., \"0.01\" means 1% minimum change required)\n * - priceExpireTime: Object with time duration for price validity:\n * - secs: Number of seconds before a price is considered stale\n * - nanos: Additional nanoseconds (always 0 in current implementation)\n *\n * @throws {TransactionFailedError} When the oracle contract query fails, possibly due to:\n * - Invalid oracle contract address\n * - Oracle contract not initialized\n * - Network connectivity issues\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format from the contract\n * - BCS deserialization failure\n * - Contract ABI mismatch\n * @throws {InvalidObjectError} When required data is missing from the response\n */\nexport const getOracleConfig = async (client: BoltSuiClient): Promise<OracleConfig> => {\n /**\n * The Move function name in the oracle module that returns configuration.\n * This function signature in Move:\n * public fun config(oracle: &Oracle): OracleConfig\n */\n const CONFIG_FUNCTION = 'config';\n\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, PRICE_ORACLE_MODULE, CONFIG_FUNCTION],\n [client.contracts.oracle]\n );\n\n const output = parseDevInspectResult(response, OracleConfigStruct);\n\n return parseOracleConfigStructOutput(output);\n};\n","import type { InvertiblePrice } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\nimport { PRICE_ORACLE_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parsePriceResponseStructOutput } from './parsers';\nimport { PriceResponseStruct } from '../../types';\n\n/**\n * Queries the oracle smart contract to retrieve the current price for a specific asset pair.\n *\n * This function fetches the latest price feed for a given base/quote asset combination\n * from the Bolt oracle. The oracle maintains price feeds that are updated by authorized\n * price feeders and validated against configured thresholds.\n *\n * @param client - The BoltSuiClient instance\n * @param baseDenom - The denomination/type of the base asset in Sui format\n * (e.g., \"0x2::sui::SUI\", \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\")\n * @param quoteDenom - The denomination/type of the quote asset in Sui format\n * Price will be expressed as: 1 base = X quote\n *\n * @returns A promise that resolves to an InvertiblePrice object containing:\n * - baseDenom: The denom of the base token\n * - quoteDenom: The denom of the quote token\n * - price: The current price as a decimal string (e.g., \"2.5\" means 1 base = 2.5 quote)\n * - expiryTime: Unix timestamp in nanoseconds when this price becomes stale\n * - isInverse: Always false in current implementation (price is not inverted)\n *\n * @throws {InvalidObjectError} When the requested asset pair has no price data available,\n * which can occur if:\n * - The pair is not registered in the oracle\n * - The oracle has never received a price for this pair\n * @throws {TransactionFailedError} When the oracle contract query fails due to:\n * - Invalid oracle contract address\n * - Network connectivity issues\n * - Contract execution errors\n * @throws {ParseError} When the response cannot be parsed, indicating:\n * - Unexpected response format\n * - BCS deserialization failure\n */\nexport const getPrice = async (\n client: BoltSuiClient,\n baseDenom: string,\n quoteDenom: string\n): Promise<InvertiblePrice> => {\n /**\n * The Move function name in the oracle module that returns a price for a pair.\n * This function signature in Move:\n * public fun get_price<BaseAsset, QuoteAsset>(\n * oracle: &Oracle\n * ): PriceResponse\n */\n const GET_PRICE_FUNCTION = 'get_price';\n\n const response = await queryDevInspect(\n client.suiClient,\n [client.packageId, PRICE_ORACLE_MODULE, GET_PRICE_FUNCTION],\n [client.contracts.oracle],\n [baseDenom, quoteDenom]\n );\n\n const output = parseDevInspectResult(response, PriceResponseStruct);\n\n return parsePriceResponseStructOutput(output, baseDenom, quoteDenom);\n};\n","import { NotFoundError, type Price } from '@bolt-liquidity-hq/core';\nimport { normalizeStructTag } from '@mysten/sui/utils';\n\nimport type { BoltSuiClient } from '../client';\nimport type { RawPairStructOutput, RawPriceStructOutput } from '../../types';\n\n/**\n * Queries the oracle smart contract to retrieve all available price feeds.\n *\n * This function fetches the current prices for all asset pairs supported by the oracle\n * by directly reading the oracle's dynamic fields. It iterates through all stored price\n * entries in the oracle's prices table.\n *\n * @param client - The BoltSuiClient instance\n *\n * @returns A promise that resolves to an array of Price objects, each containing:\n * - baseDenom: The normalized denom of the base token\n * - quoteDenom: The normalized denom of the quote token\n * - price: The current price as a decimal string\n * - expiryTime: Unix timestamp in milliseconds when this price expires\n *\n * @throws {NotFoundError} When:\n * - The oracle object cannot be found at the configured address\n * - The oracle object exists but is not a valid Move object\n * - The prices table cannot be found within the oracle object\n * @throws {TransactionFailedError} When the Sui queries fail due to:\n * - Network connectivity issues\n * - Invalid oracle contract address\n */\nexport const getPrices = async (client: BoltSuiClient): Promise<Price[]> => {\n const oracleObject = await client.suiClient.getObject({\n id: client.contracts.oracle,\n options: { showContent: true },\n });\n\n if (!oracleObject.data?.content || oracleObject.data.content.dataType !== 'moveObject') {\n throw new NotFoundError('Oracle object');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n const pricesTableId: string | undefined = (oracleObject.data.content.fields as any)?.prices\n ?.fields?.id?.id;\n\n if (!pricesTableId) {\n throw new NotFoundError('Prices table in the Oracle contract');\n }\n\n // Get all prices\n const prices: Price[] = [];\n let cursor = null;\n\n while (true) {\n const dynamicFields = await client.suiClient.getDynamicFields({\n parentId: pricesTableId,\n cursor,\n limit: 50, // Max limit per request\n });\n\n // Batch fetch all field objects in this page\n const fieldPromises = dynamicFields.data.map((field) =>\n client.suiClient.getDynamicFieldObject({\n parentId: pricesTableId,\n name: field.name,\n })\n );\n\n const fieldObjects = await Promise.all(fieldPromises);\n fieldObjects.forEach((obj, index) => {\n if (obj.data?.content?.dataType === 'moveObject') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n const fields = (obj.data.content.fields as any)?.value?.fields?.price?.fields as\n | RawPriceStructOutput\n | undefined;\n const pairKey = dynamicFields.data[index]?.name?.value as RawPairStructOutput | undefined;\n\n if (fields && pairKey) {\n prices.push({\n baseDenom: normalizeStructTag(pairKey.base.name),\n quoteDenom: normalizeStructTag(pairKey.quote.name),\n price: fields.price,\n expiryTime: fields.expiry,\n });\n }\n }\n });\n\n if (!dynamicFields.hasNextPage) break;\n cursor = dynamicFields.nextCursor;\n }\n\n return prices;\n};\n","import { type Coin, DEFAULT_GAS_ADJUSTMENT, type SwapParams } from '@bolt-liquidity-hq/core';\nimport type { Signer } from '@mysten/sui/cryptography';\n\nimport type { BoltSuiClient } from '../client';\nimport { buildSwapTxArgs, estimateTxGasPrice } from '../helpers';\n\n/**\n * Estimates the gas fees required for executing a swap transaction on the Sui blockchain.\n *\n * This function simulates a swap transaction to calculate the required gas fees without\n * actually executing the swap. It leverages the buildSwapTxArgs helper to prepare all\n * transaction components, then uses Sui's dry run capability to estimate gas costs in SUI tokens.\n *\n * @param client - The BoltSuiClient instance containing configuration and contracts\n * @param swapParams - The swap parameters\n * @param swapParams.assetIn - The type of the asset being sold (e.g., \"0x2::sui::SUI\")\n * @param swapParams.amountIn - The exact amount of input asset to swap (in minimal denomination)\n * @param swapParams.assetOut - The type of the asset being bought (e.g., \"0x5d...::coin::COIN\")\n * @param swapParams.minimumAmountOut - Optional minimum acceptable amount of output asset.\n * Used for slippage protection in the swap simulation.\n * @param swapParams.receiver - Optional recipient address for the swapped assets.\n * If not provided, defaults to the signer's address.\n * @param signer - Optional signer for the transaction. If not provided,\n * uses the client's cached signer. Required on first call if no cached signer exists.\n * @param gasAdjustment - Multiplier for gas estimation to add safety margin.\n * Defaults to DEFAULT_GAS_ADJUSTMENT (typically 1.5 for 50% buffer).\n *\n * @returns A promise that resolves to:\n * - A Coin object with `amount` (gas fee in MIST) and `denom` (\"0x2::sui::SUI\")\n * - `undefined` if the simulation fails or gas estimation is not supported\n *\n * @throws {NotFoundError} When no pool exists for the specified asset pair\n * @throws {MissingParameterError} When no signer is available\n */\nexport const estimateSwapExactInGasFees = async (\n client: BoltSuiClient,\n swapParams: SwapParams,\n signer?: Signer,\n gasAdjustment: number = DEFAULT_GAS_ADJUSTMENT\n): Promise<Coin | undefined> => {\n const swapArgs = await buildSwapTxArgs(client, swapParams, signer);\n\n return await estimateTxGasPrice(\n client.suiClient,\n swapArgs.signer.toSuiAddress(),\n swapArgs.target,\n swapArgs.args,\n swapArgs.typeArguments,\n swapArgs.tx,\n gasAdjustment\n );\n};\n","import {\n NotImplementedError,\n type Address,\n type BaseLiquidityDetails,\n} from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\n\n/**\n * Queries the router smart contract to retrieve the total base asset liquidity across all pools with automatic pagination.\n *\n * Currently not implemented on Sui Client\n *\n * @param client - The BoltSuiClient instance\n */\nexport const getAllBaseLiquidity = async (\n _client: BoltSuiClient\n // eslint-disable-next-line @typescript-eslint/require-await\n): Promise<Record<Address, BaseLiquidityDetails>> => {\n throw new NotImplementedError('getRouterConfig on Sui Client');\n};\n","import { NotImplementedError, type Address, type Coin } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\n\n/**\n * Queries the router smart contract to retrieve all quote asset positions for a specific liquidity provider.\n *\n *\n * Currently not implemented on Sui Client\n *\n * @param client - The BoltSuiClient instance\n */\nexport const getAllQuotesForUser = async (\n _client: BoltSuiClient,\n _lpAddress: Address\n // eslint-disable-next-line @typescript-eslint/require-await\n): Promise<Record<Address, Coin[]>> => {\n throw new NotImplementedError('getRouterConfig on Sui Client');\n};\n","import { NotFoundError, type Pool } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\n\n/**\n * Queries the router client to retrieve pool information for a specific asset pair.\n *\n * This function fetches the market/pool details for a given base/quote asset pair from the client's\n * router instance. In the Bolt protocol on Sui, pools are uniquely identified by both base and quote\n * asset types, allowing for multiple pools with the same base asset but different quote assets.\n * This query returns the pool's object ID and configuration for the specified trading pair.\n *\n * @param client - The BoltSuiClient instance.\n * @param baseDenom - The type of the base asset in Sui format\n * (e.g., \"0x2::sui::SUI\", \"0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5::coin::COIN\")\n * @param quoteDenom - The type of the quote asset in Sui format\n * (e.g., \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\")\n *\n * @returns A promise that resolves to a Pool object containing:\n * - poolAddress: The Sui object ID of the market/pool\n * - baseDenom: The type of the base asset\n * - quoteDenoms: Array of types for available quote assets (will include the requested quote asset)\n *\n * @throws {NotFoundError} When no pool exists for the specified base/quote asset pair, with a message\n * indicating which assets were requested. This occurs if:\n * - No pool has been created for this specific trading pair\n * - The asset types are not recognized by the router\n * - The pool was removed or not initialized\n */\nexport const getPoolByDenom = async (\n client: BoltSuiClient,\n baseDenom: string,\n quoteDenom: string\n): Promise<Pool> => {\n // eslint-disable-next-line @typescript-eslint/await-thenable\n const result = await client.routerClient.getPool(baseDenom, quoteDenom);\n\n if (!result) {\n throw new NotFoundError('Pool', `Didn't find a pool to swap ${baseDenom} for ${quoteDenom}`);\n }\n\n return result;\n};\n","import type { Pool } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\n\n/**\n * Retrieves information about all available pools from the router client.\n *\n * This function fetches a comprehensive list of all markets/pools configured in the Bolt protocol\n * on Sui through the client's router instance. It provides a complete overview of all trading\n * possibilities within the protocol at once, making it more efficient than querying individual pools.\n *\n * @param client - The BoltSuiClient instance.\n *\n * @returns A promise that resolves to an array of Pool objects, each containing:\n * - poolAddress: The Sui object ID of the market/pool\n * - baseDenom: The type of the base asset for this pool (e.g., \"0x2::sui::SUI\")\n * - quoteDenoms: Array of types for available quote assets that can be traded\n * ```\n */\nexport const getPools = async (client: BoltSuiClient): Promise<Pool[]> => {\n // eslint-disable-next-line @typescript-eslint/await-thenable\n return await client.routerClient.getPools();\n};\n","import { NotImplementedError, type RouterConfig } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\n\n/**\n * Queries the router smart contract to retrieve its current configuration settings.\n *\n * Currently not implemented on Sui Client\n *\n * @param client - The BoltSuiClient instance\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport const getRouterConfig = async (_client: BoltSuiClient): Promise<RouterConfig> => {\n throw new NotImplementedError('getRouterConfig on Sui Client');\n};\n","import type { Pool } from '@bolt-liquidity-hq/core';\n\nimport { normalizeStructTag } from '@mysten/sui/utils';\n\nexport class RouterClient {\n constructor(public pools: Pool[]) {}\n\n getPool(denomIn: string, denomOut: string): Pool | undefined {\n const normalizedDenomIn = normalizeStructTag(denomIn);\n const normalizedDenomOut = normalizeStructTag(denomOut);\n\n // Search by pair\n const directPairPool: Pool | undefined = this.pools.find(\n (item) =>\n item.baseDenom === normalizedDenomIn && item.quoteDenoms.includes(normalizedDenomOut)\n );\n\n if (directPairPool) {\n return directPairPool;\n }\n\n // Search by inverse pair\n const inversePairPool: Pool | undefined = this.pools.find(\n (item) =>\n item.baseDenom === normalizedDenomOut && item.quoteDenoms.includes(normalizedDenomIn)\n );\n\n if (inversePairPool) {\n return inversePairPool;\n }\n\n return;\n }\n\n getPools(): Pool[] {\n return this.pools;\n }\n}\n","import type { SwapParams, SwapResult } from '@bolt-liquidity-hq/core';\nimport type { SuiTransactionBlockResponse } from '@mysten/sui/client';\nimport type { Signer } from '@mysten/sui/cryptography';\n\nimport type { BoltSuiClient } from '../client';\nimport { signAndExecuteTx, buildSwapTxArgs } from '../helpers';\n\n/**\n * Executes a token swap transaction on the Bolt protocol through the Sui Move router module.\n *\n * This function performs a \"swap exact in\" operation, where the user specifies exactly\n * how much of the input coin they want to swap, and receives a variable amount of the\n * output coin based on current liquidity pool conditions. The function leverages the\n * buildSwapTxArgs helper to prepare the transaction, then executes it on-chain.\n *\n * @param client - The BoltSuiClient instance containing configuration and contracts\n * @param swapParams - The swap configuration parameters\n * @param swapParams.assetIn - The fully qualified type of the input coin being sold\n * (e.g., \"0x2::sui::SUI\", \"0x...::usdc::USDC\")\n * @param swapParams.amountIn - The exact amount of input coin to swap (as string, in base units).\n * For example, \"1000000000\" for 1 SUI (9 decimals)\n * @param swapParams.assetOut - The fully qualified type of the output coin being bought\n * (e.g., \"0x2::sui::SUI\", \"0x...::usdc::USDC\")\n * @param swapParams.minimumAmountOut - Optional minimum acceptable amount of output coin.\n * Transaction will fail if the actual output would be less.\n * Protects against excessive slippage\n * @param swapParams.receiver - Optional recipient address for the swapped coins.\n * If not provided, coins are sent to the signer's address\n * @param signer - Optional Sui signer (e.g., Ed25519Keypair) that will authorize the swap transaction.\n * If not provided, uses the client's cached signer. Must have sufficient balance\n * of the input coin type and SUI for gas fees\n *\n * @returns A promise that resolves to a SwapResult containing:\n * - txOutput: The complete SuiTransactionBlockResponse with transaction details\n * - txHash: The transaction digest for tracking on Sui explorers\n * - amountOut: The actual amount of output coin received (extracted from events, or \"0\" if not found)\n * - assetOut: The output coin type (from the swap parameters)\n *\n * @throws {NotFoundError} When no pool exists for the specified asset pair\n * @throws {TransactionFailedError} When:\n * - The transaction fails on-chain (insufficient balance, slippage, etc.)\n * - The minimum output amount constraint is not satisfied\n * @throws {UnexpectedError} When:\n * - Network connectivity issues occur\n * - Invalid coin types are provided\n * - Coin selection/preparation fails\n * @throws {MissingParameterError} When no signer is available\n */\nexport const swapExactIn = async (\n client: BoltSuiClient,\n swapParams: SwapParams,\n signer?: Signer\n): Promise<SwapResult<SuiTransactionBlockResponse>> => {\n const swapArgs = await buildSwapTxArgs(client, swapParams, signer);\n\n const txOutput = await signAndExecuteTx(\n client.suiClient,\n swapArgs.signer,\n swapArgs.target,\n swapArgs.args,\n swapArgs.typeArguments,\n swapArgs.tx,\n { showEffects: true, showEvents: true, showBalanceChanges: true }\n );\n\n return {\n txOutput,\n txHash: txOutput.digest,\n amountOut:\n (txOutput.events?.at(0)?.parsedJson as Record<string, string> | undefined)?.['amount_out'] ??\n '0',\n assetOut: swapParams.assetOut,\n };\n};\n","import type { Address, PoolConfig } from '@bolt-liquidity-hq/core';\nimport { SUI_TYPE_ARG } from '@mysten/sui/utils';\n\nimport type { BoltSuiClient } from '../client';\nimport { POOL_MODULE } from '../constants';\nimport { parseDevInspectResult, queryDevInspect } from '../helpers';\nimport { parseSettlementConfigStructOutput } from './parsers';\nimport { PoolFeesInfoStruct, ProtocolFeesInfoStruct } from '../../types';\n\n/**\n * Retrieves the configuration settings and fee information for a liquidity pool.\n *\n * This function combines pool-specific fee information with\n * protocol fee data to provide complete pool configuration.\n *\n * @param client - The BoltSuiClient instance.\n * @param contractAddress - The Sui object ID of the pool contract to query.\n * Must be a valid pool address obtained from router queries.\n *\n * @returns A promise that resolves to a PoolConfig object containing:\n * - priceOracleContract: Object ID of the price oracle\n * - protocolFeeRecipient: Address that receives protocol fees\n * - protocolFee: The protocol fee percentage as decimal string (e.g., \"0.003\" = 0.3%)\n * - lpFee: The liquidity provider fee percentage as decimal string (e.g., \"0.002\" = 0.2%)\n * - allowanceMode: The allowance mode for LP operations\n * - lps: Array of authorized liquidity provider addresses\n * - minBaseOut: Minimum base asset output amount for trades\n *\n * @throws {TransactionFailedError} When the queries fail due to:\n * - Invalid pool contract address\n * - Network connectivity issues\n * - Incorrect type arguments for the pool\n * @throws {ParseError} When the responses cannot be parsed, indicating:\n * - Unexpected response format from either query\n * - BCS deserialization failure\n * - Missing required fields in the response\n */\nexport const getPoolInfo = async (\n client: BoltSuiClient,\n contractAddress: Address\n): Promise<PoolConfig> => {\n /**\n * Move function to get pool fee information.\n * Function signature in Move:\n * public fun get_pool_fees_info<X>(pool: &LiquidityPool<X>): PoolFeesInfo\n */\n const GET_POOL_FEES_INFO_FUNCTION = 'get_pool_fees_info';\n\n /**\n * Move function to get protocol fee information.\n * Function signature in Move:\n * public fun get_protocol_fees_info<X>(pool: &LiquidityPool<X>): ProtocolFeesInfo\n */\n const GET_PROTOCOL_FEES_INFO_FUNCTION = 'get_protocol_fees_info';\n\n // Execute both queries in parallel for efficiency\n const [poolFeesInfo, protocolFeesInfo] = await Promise.all([\n // Query pool fee information\n queryDevInspect(\n client.suiClient,\n [client.packageId, POOL_MODULE, GET_POOL_FEES_INFO_FUNCTION],\n [contractAddress],\n // TODO: get the base token of the pool to pass it here instead of hardcoded SUI token\n [SUI_TYPE_ARG]\n ),\n // Query protocol fee information\n queryDevInspect(\n client.suiClient,\n [client.packageId, POOL_MODULE, GET_PROTOCOL_FEES_INFO_FUNCTION],\n [contractAddress],\n // TODO: get the base token of the pool to pass it here instead of hardcoded SUI token\n [SUI_TYPE_ARG]\n ),\n ]);\n\n const poolFeesInfoOutput = parseDevInspectResult(poolFeesInfo, PoolFeesInfoStruct);\n const protocolFeesInfoOutput = parseDevInspectResult(protocolFeesInfo, ProtocolFeesInfoStruct);\n\n return parseSettlementConfigStructOutput(\n client.routerClient,\n poolFeesInfoOutput,\n protocolFeesInfoOutput,\n client.contracts.oracle\n );\n};\n","import type { PoolConfig } from '@bolt-liquidity-hq/core';\n\nimport type { RouterClient } from '../router';\nimport type { PoolFeesInfoStructOutput, ProtocolFeesInfoStructOutput } from '../../types';\n\n/**\n * Parses pool fee information and protocol fee information from the Sui blockchain into a structured PoolConfig object.\n *\n * This function combines data from two Move function responses: pool fee information from `get_pool_fees_info`\n * and protocol fee information from `get_protocol_fees_info`. It transforms the data from these responses\n * into the standardized format used throughout the SDK.\n *\n * @param routerClient - The RouterClient instance\n * @param poolFeesInfo - The response from the `get_pool_fees_info` Move function containing:\n * - swap_fee_pct: The total swap fee percentage (used as protocol fee)\n * - lp_fee_pct: The liquidity provider fee percentage\n * @param protocolFeesInfo - The response from the `get_protocol_fees_info` Move function containing:\n * - bolt_fee_addr: The address that receives protocol fees\n * @param priceOracleContract - The address of the price oracle contract\n *\n * @returns A parsed PoolConfig object with:\n * - priceOracleContract: Object ID of the price oracle (from parameter)\n * - protocolFeeRecipient: Address that receives protocol fees\n * - protocolFee: The protocol fee percentage as decimal string\n * - lpFee: The liquidity provider fee percentage as decimal string\n * - allowanceMode: The allowance mode for pool operations (currently hardcoded to 'allow')\n * - lps: Array of pool addresses from the router client\n * - minBaseOut: Minimum base asset output amount (currently hardcoded to '0')\n *\n * @example\n * ```typescript\n * // Example with actual data\n * const routerClient = new RouterClient(pools);\n *\n * const poolFeesInfoResponse: PoolFeesInfoStructOutput = {\n * swap_fee_pct: \"0.003\", // 0.3%\n * lp_fee_pct: \"0.002\" // 0.2%\n * };\n *\n * const protocolFeesInfoResponse: ProtocolFeesInfoStructOutput = {\n * bolt_fee_addr: \"0xtreasury123...\"\n * };\n *\n * const oracleAddress = \"0xoracle456...\";\n *\n * const config = parseSettlementConfigStructOutput(\n * routerClient,\n * poolFeesInfoResponse,\n * protocolFeesInfoResponse,\n * oracleAddress\n * );\n * console.log(config.priceOracleContract); // \"0xoracle456...\"\n * console.log(config.protocolFeeRecipient); // \"0xtreasury123...\"\n * console.log(config.protocolFee); // \"0.003\"\n * console.log(config.lpFee); // \"0.002\"\n * console.log(config.lps); // Array of pool addresses from router client\n * console.log(config.minBaseOut); // \"0\"\n * ```\n */\nexport const parseSettlementConfigStructOutput = (\n routerClient: RouterClient,\n poolFeesInfo: PoolFeesInfoStructOutput,\n protocolFeesInfo: ProtocolFeesInfoStructOutput,\n priceOracleContract: string\n): PoolConfig => {\n // TODO: update when contracts are completed\n // Currently using hardcoded values for most fields\n return {\n priceOracleContract,\n protocolFeeRecipient: protocolFeesInfo.bolt_fee_addr,\n protocolFee: poolFeesInfo.swap_fee_pct,\n lpFee: poolFeesInfo.lp_fee_pct,\n allowanceMode: 'allow', // Should come from pool config\n lps: routerClient.getPools().map((item) => item.poolAddress),\n minBaseOut: '0', // Should come from pool config\n };\n};\n","import type { PoolConfig } from '@bolt-liquidity-hq/core';\n\nimport type { BoltSuiClient } from '../client';\nimport { getPoolInfo } from './get-pool-info';\nimport { getPoolByDenom } from '../router';\n\n/**\n * Retrieves the configuration settings for a settlement contract (liquidity pool)\n * identified by its base and quote asset types.\n *\n * This is a convenience function that combines pool lookup and configuration retrieval.\n * It first finds the pool/market associated with the given base/quote asset pair, then fetches that\n * pool's configuration parameters from its settlement contract. In Sui, settlement\n * contracts manage the actual liquidity and trading logic for each pool, and pools are\n * uniquely identified by both base and quote assets.\n *\n * @param client - The BoltSuiClient instance\n * @param baseDenom - The type of the base asset in Sui format\n * (e.g., \"0x2::sui::SUI\", \"0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5::coin::COIN\")\n * @param quoteDenom - The type of the quote asset in Sui format\n * (e.g., \"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN\")\n *\n * @returns A promise that resolves to a PoolConfig object containing:\n * - priceOracleContract: Object ID of the price oracle used by this pool\n * - protocolFeeRecipient: Sui address that receives protocol fees\n * - protocolFee: The protocol fee percentage (as decimal string, e.g., \"0.003\" = 0.3%)\n * - lpFee: The liquidity provider fee percentage (as decimal string, e.g., \"0.002\" = 0.2%)\n * - allowanceMode: The allowance mode for pool operations (controls LP permissions)\n * - lps: Array of authorized liquidity provider Sui addresses\n * - minBaseOut: Minimum base asset output amount for trades (prevents dust trades)\n *\n * @throws {NotFoundError} When no pool exists for the specified base/quote asset pair\n * @throws {TransactionFailedError} When the contract queries fail due to:\n * - Invalid router or settlement contract addresses\n * - Network connectivity issues\n * - Contract not properly initialized\n * @throws {ParseError} When the configuration response cannot be parsed\n */\nexport const getPoolInfoByDenom = async (\n client: BoltSuiClient,\n baseDenom: string,\n quoteDenom: string\n): Promise<PoolConfig> => {\n const pool = await getPoolByDenom(client, baseDenom, quoteDenom);\n\n return await getPoolInfo(client, pool.poolAddress);\n};\n"],"mappings":"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","names":["import_core","import_utils","import_utils","import_core","import_utils","import_core","import_core","import_bcs","import_transactions","import_utils","import_core","import_bignumber","import_bcs","import_bcs","import_bcs","import_bcs","import_utils","import_core","import_utils","import_core","import_core","import_core","import_core","import_core","import_utils","import_utils","axios"]}
|