UNPKG

@orca-so/tx-sender

Version:

Send transactions to the Solana blockchain with auto priority fees.

1 lines 41.4 kB
{"version":3,"sources":["../src/index.ts","../src/compatibility.ts","../src/config.ts","../src/buildTransaction.ts","../src/priorityFees.ts","../src/jito.ts","../src/computeBudget.ts","../src/sendTransaction.ts"],"sourcesContent":["export * from \"./config\";\nexport * from \"./buildTransaction\";\nexport * from \"./sendTransaction\";\n\nexport { rpcFromUrl } from \"./compatibility\";\n","import { createSolanaRpcApi, createRpc } from \"@solana/rpc\";\nimport type { Address, Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { createDefaultRpcTransport, address } from \"@solana/kit\";\n\n/**\n * Creates an RPC client instance for interacting with the SVM blockchains using the provided RPC URL.\n *\n * @param {string} url - The RPC endpoint URL.\n * @returns {Rpc<SolanaRpcApi>} An RPC client configured with the Solana RPC API.\n *\n * @example\n * ```ts\n * const rpc = rpcFromUrl(\"https://api.mainnet-beta.solana.com\");\n * const slot = await rpc.getSlot().send();\n * console.log(slot);\n * ```\n */\nexport function rpcFromUrl(url: string): Rpc<SolanaRpcApi> {\n const api = createSolanaRpcApi({\n defaultCommitment: \"confirmed\",\n });\n const transport = createDefaultRpcTransport({ url });\n const rpc = createRpc({ api, transport });\n return rpc;\n}\n\nexport function normalizeAddresses(\n addresses?: (string | Address)[],\n): Address[] {\n return addresses?.map((addr) => address(addr)) ?? [];\n}\n","import type { Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { rpcFromUrl } from \"./compatibility\";\n\nlet globalConfig: {\n rpcConfig?: RpcConfig;\n transactionConfig?: TransactionConfig;\n} = {};\n\n/**\n * Default compute unit margin multiplier used to ensure sufficient compute budget.\n */\nexport const DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER = 1.1;\n\n/**\n * Default prioritization settings, including priority fees and Jito tips.\n */\nexport const DEFAULT_PRIORITIZATION: TransactionConfig = {\n priorityFee: {\n type: \"dynamic\",\n maxCapLamports: BigInt(4_000_000), // 0.004 SOL\n priorityFeePercentile: \"50\",\n },\n jito: {\n type: \"dynamic\",\n maxCapLamports: BigInt(4_000_000), // 0.004 SOL\n priorityFeePercentile: \"50\",\n },\n computeUnitMarginMultiplier: DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER,\n jitoBlockEngineUrl: \"https://bundles.jito.wtf\",\n};\n\n/**\n * Retrieves the current RPC configuration.\n *\n * @throws {Error} If the RPC connection has not been initialized using `setRpc()`.\n * @returns {RpcConfig} The RPC configuration including the RPC URL, support for percentile-based fees, and the chain ID.\n */\nexport const getRpcConfig = (): RpcConfig => {\n const rpcConfig = globalConfig.rpcConfig;\n if (!rpcConfig?.rpcUrl) {\n throw new Error(\"Connection not initialized. Call setRpc() first\");\n }\n return rpcConfig;\n};\n\nconst getPriorityConfig = (): TransactionConfig => {\n if (!globalConfig.transactionConfig) {\n return DEFAULT_PRIORITIZATION;\n }\n return globalConfig.transactionConfig;\n};\n\n/**\n * Retrieves the current Jito fee settings.\n *\n * @returns {JitoFeeSetting} The Jito fee configuration, including fee type, max cap, and percentile.\n */\nexport const getJitoConfig = (): JitoFeeSetting => {\n return getPriorityConfig().jito;\n};\n\n/**\n * Retrieves the current priority fee configuration.\n *\n * @returns {PriorityFeeSetting} The priority fee settings, which include dynamic, exact or none fee settings and priority fee percentile.\n */\nexport const getPriorityFeeConfig = (): PriorityFeeSetting => {\n return getPriorityConfig().priorityFee;\n};\n\n/**\n * Retrieves the compute unit margin multiplier.\n *\n * @returns {number} The multiplier applied to compute units for transaction execution.\n */\nexport const getComputeUnitMarginMultiplier = (): number => {\n return getPriorityConfig().computeUnitMarginMultiplier;\n};\n\n/**\n * Retrieves the current Jito block engine URL.\n *\n * @returns {string} The Jito block engine URL.\n */\nexport const getJitoBlockEngineUrl = (): string => {\n return getPriorityConfig().jitoBlockEngineUrl;\n};\n\nconst setGlobalConfig = (config: {\n transactionConfig?: TransactionConfig;\n rpcConfig?: RpcConfig;\n}) => {\n globalConfig = {\n transactionConfig: config.transactionConfig || DEFAULT_PRIORITIZATION,\n rpcConfig: config.rpcConfig,\n };\n};\n\n/**\n * Initializes the global RPC configuration and returns an RPC instance.\n *\n * @param {string} url - The Solana RPC endpoint URL.\n * @param {object} [options] - Optional RPC configuration\n * @param {boolean} [options.supportsPriorityFeePercentile=false] - Whether the RPC supports percentile-based priority fees. Set this to true if the RPC provider is Triton.\n * @param {number} [options.pollIntervalMs=0] - Milliseconds between confirmation status checks. Set to 0 for continuous polling (default).\n * @param {boolean} [options.resendOnPoll=true] - Whether to resend the transaction on each poll attempt (default: true).\n * @returns {Promise<Rpc<SolanaRpcApi>>} A Promise that resolves to an RPC instance configured for the specified endpoint.\n *\n * @example\n * ```ts\n * // Premium RPC: Use defaults for maximum landing rate\n * const rpc = await setRpc(\"https://mainnet.helius-rpc.com/?api-key=...\");\n *\n * // Lower tier RPCs: Configure to reduce RPC usage\n * const rpc = await setRpc(\"https://api.devnet.solana.com\", {\n * pollIntervalMs: 1000,\n * resendOnPoll: false,\n * });\n * ```\n */\nexport async function setRpc(\n url: string,\n options: {\n supportsPriorityFeePercentile?: boolean;\n pollIntervalMs?: number;\n resendOnPoll?: boolean;\n } = {},\n): Promise<Rpc<SolanaRpcApi>> {\n const rpc = rpcFromUrl(url);\n const chainId = await getChainIdFromGenesisHash(rpc);\n\n setGlobalConfig({\n ...globalConfig,\n rpcConfig: {\n rpcUrl: url,\n supportsPriorityFeePercentile:\n options.supportsPriorityFeePercentile ?? false,\n chainId,\n pollIntervalMs: options.pollIntervalMs ?? 0,\n resendOnPoll: options.resendOnPoll ?? true,\n },\n });\n\n // Create a wrapper Proxy that makes the RPC non-thenable\n // This prevents the RPC's .then from interfering with Promise resolution\n const nonThenableRpc = new Proxy(rpc, {\n get(target, prop, receiver) {\n if (prop === \"then\") {\n return undefined; // Make it non-thenable\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n\n return nonThenableRpc;\n}\n\nasync function getChainIdFromGenesisHash(\n rpc: Rpc<SolanaRpcApi>,\n): Promise<ChainId> {\n // not all rpc endpoints support getGenesisHash\n try {\n const genesisHash = await rpc.getGenesisHash().send();\n const genesisHashToChainId: Record<string, ChainId> = {\n \"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d\": \"solana\",\n EAQLJCV2mh23BsK2P9oYpV5CHVLDNHTxYss3URrNmg3s: \"eclipse\",\n EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG: \"solana-devnet\",\n CX4huckiV9QNAkKNVKi5Tj8nxzBive5kQimd94viMKsU: \"eclipse-testnet\",\n };\n return genesisHashToChainId[genesisHash] || \"unknown\";\n } catch (error) {\n console.warn(\"Error getting chain ID from genesis hash\", error);\n return \"unknown\";\n }\n}\n\n/**\n * Sets the Jito block engine URL.\n *\n * @param {string} url - The Jito block engine URL.\n */\nexport async function setJitoBlockEngineUrl(url: string) {\n setGlobalConfig({\n ...globalConfig,\n transactionConfig: {\n ...getPriorityConfig(),\n jitoBlockEngineUrl: url,\n },\n });\n}\n\n/**\n * Updates the priority fee settings.\n *\n * @param {FeeSetting} priorityFee - The new priority fee configuration.\n */\nexport function setPriorityFeeSetting(priorityFee: FeeSetting) {\n setGlobalConfig({\n ...globalConfig,\n transactionConfig: {\n ...getPriorityConfig(),\n priorityFee,\n },\n });\n}\n\n/**\n * Updates the Jito tip settings.\n *\n * @param {FeeSetting} jito - The new Jito fee configuration.\n */\nexport function setJitoTipSetting(jito: FeeSetting) {\n setGlobalConfig({\n ...globalConfig,\n transactionConfig: {\n ...getPriorityConfig(),\n jito,\n },\n });\n}\n\n/**\n * Updates the compute unit margin multiplier.\n *\n * @param {number} multiplier - The new compute unit margin multiplier.\n */\nexport function setComputeUnitMarginMultiplier(multiplier: number) {\n setGlobalConfig({\n ...globalConfig,\n transactionConfig: {\n ...getPriorityConfig(),\n computeUnitMarginMultiplier: multiplier,\n },\n });\n}\n\n/**\n * Sets the percentile used for Jito fee calculations.\n *\n * @param {Percentile | \"50ema\"} percentile - The new percentile setting for Jito fees. \"50ema\" is the exponential moving average of the 50th percentile.\n */\nexport function setJitoFeePercentile(percentile: Percentile | \"50ema\") {\n const jito = getPriorityConfig().jito;\n setGlobalConfig({\n ...globalConfig,\n transactionConfig: {\n ...getPriorityConfig(),\n jito: {\n ...jito,\n priorityFeePercentile: percentile,\n },\n },\n });\n}\n\n/**\n * Sets the percentile used for priority fee calculations.\n *\n * @param {Percentile} percentile - The new percentile setting for priority fees.\n */\nexport function setPriorityFeePercentile(percentile: Percentile) {\n const priorityConfig = getPriorityConfig();\n const priorityFee = priorityConfig.priorityFee;\n setGlobalConfig({\n ...globalConfig,\n transactionConfig: {\n ...priorityConfig,\n priorityFee: {\n ...priorityFee,\n priorityFeePercentile: percentile,\n },\n },\n });\n}\n\ntype FeeSetting =\n | {\n type: \"dynamic\";\n maxCapLamports?: bigint;\n }\n | {\n type: \"exact\";\n amountLamports: bigint;\n }\n | {\n type: \"none\";\n };\n\n/**\n * Configuration for transaction fees, including Jito and priority fee settings.\n */\nexport type JitoFeeSetting = FeeSetting & {\n priorityFeePercentile?: Percentile | \"50ema\";\n};\n\nexport type PriorityFeeSetting = FeeSetting & {\n priorityFeePercentile?: Percentile;\n};\n\nexport type TransactionConfig = {\n jito: JitoFeeSetting;\n priorityFee: PriorityFeeSetting;\n computeUnitMarginMultiplier: number;\n jitoBlockEngineUrl: string;\n};\n\n/**\n * Defines a percentile value for priority fee selection.\n */\nexport type Percentile = \"25\" | \"50\" | \"75\" | \"95\" | \"99\";\n\n/**\n * Represents a supported blockchain network chain ID.\n */\nexport type ChainId =\n | \"solana\"\n | \"eclipse\"\n | \"solana-devnet\"\n | \"eclipse-testnet\"\n | \"unknown\";\n\n/**\n * Configuration for RPC settings and transaction sending strategy.\n *\n * The transaction sending strategy should be configured based on your RPC tier:\n * - **Premium RPC** (e.g., Helius, Triton): Can use default aggressive settings with resend enabled\n * - **Public/Free RPC**: Should use conservative settings to avoid rate limits\n *\n * @property {string} rpcUrl - The RPC endpoint URL\n * @property {boolean} supportsPriorityFeePercentile - Whether the RPC supports percentile-based priority fee estimation\n * @property {ChainId} chainId - The blockchain network chain ID\n * @property {number} [pollIntervalMs=0] - Milliseconds between confirmation status checks.\n * Set to 0 for continuous polling (no delay).\n * @property {boolean} [resendOnPoll=true] - Whether to resend the transaction on each poll attempt.\n * - `true` (default): Resend transaction on every poll. Higher RPC usage, best for premium RPCs.\n * - `false`: Send once, then only poll for status. Lower RPC usage, recommended for public RPCs.\n *\n * @example\n * ```ts\n * // Premium RPC: Use defaults for maximum landing rate\n * setRpc(\"https://mainnet.helius-rpc.com/?api-key=...\");\n *\n * // Public/Free RPC: Conservative settings to control RPC usage\n * setRpc(\"https://api.devnet.solana.com\", {\n * pollIntervalMs: 1000,\n * resendOnPoll: false,\n * });\n * ```\n */\nexport type RpcConfig = {\n rpcUrl: string;\n supportsPriorityFeePercentile: boolean;\n chainId: ChainId;\n pollIntervalMs: number;\n resendOnPoll: boolean;\n};\n","import type {\n Instruction,\n Address,\n Rpc,\n SolanaRpcApi,\n NoopSigner,\n KeyPairSigner,\n Transaction,\n TransactionWithLifetime,\n} from \"@solana/kit\";\nimport {\n compressTransactionMessageUsingAddressLookupTables,\n assertAccountDecoded,\n appendTransactionMessageInstructions,\n createTransactionMessage,\n pipe,\n setTransactionMessageLifetimeUsingBlockhash,\n partiallySignTransactionMessageWithSigners,\n setTransactionMessageFeePayerSigner,\n} from \"@solana/kit\";\nimport { normalizeAddresses, rpcFromUrl } from \"./compatibility\";\nimport { fetchAllMaybeAddressLookupTable } from \"@solana-program/address-lookup-table\";\nimport { addPriorityInstructions } from \"./priorityFees\";\nimport { getRpcConfig } from \"./config\";\n\n/**\n * Builds and signs a transaction from the given instructions and configuration.\n *\n * @param {Instruction[]} instructions - Array of instructions to include in the transaction\n * @param {KeyPairSigner | NoopSigner} feePayer - The signer that will pay for the transaction (must be the SAME instance used to build instructions)\n * @param {(Address | string)[]} [lookupTableAddresses] - Optional array of address lookup table addresses to compress the transaction\n *\n * @returns {Promise<Readonly<Transaction & TransactionWithLifetime>>}\n *\n * @example\n * // Node.js with KeyPairSigner - fully signed automatically\n * const { instructions } = await swapInstructions(rpc, params, pool, 100, keypairSigner);\n * const tx = await buildTransaction(instructions, keypairSigner);\n * await sendTransaction(tx);\n *\n * // Browser with NoopSigner - partially signed, wallet signs separately\n * const noopSigner = createNoopSigner(walletAddress);\n * const { instructions } = await swapInstructions(rpc, params, pool, 100, noopSigner);\n * const partialTx = await buildTransaction(instructions, noopSigner); // Same instance!\n * const [signedTx] = await wallet.modifyAndSignTransactions([partialTx]);\n * await sendTransaction(signedTx);\n */\nexport async function buildTransaction(\n instructions: Instruction[],\n feePayer: KeyPairSigner | NoopSigner,\n lookupTableAddresses?: (Address | string)[],\n): Promise<Readonly<Transaction & TransactionWithLifetime>> {\n return buildTransactionMessage(\n instructions,\n feePayer,\n normalizeAddresses(lookupTableAddresses),\n );\n}\n\nasync function buildTransactionMessage(\n instructions: Instruction[],\n feePayer: KeyPairSigner | NoopSigner,\n lookupTableAddresses?: Address[],\n) {\n const { rpcUrl } = getRpcConfig();\n const rpc = rpcFromUrl(rpcUrl);\n\n let message = await prepareTransactionMessage(instructions, rpc, feePayer);\n\n if (lookupTableAddresses?.length) {\n const lookupTableAccounts = await fetchAllMaybeAddressLookupTable(\n rpc,\n lookupTableAddresses,\n );\n const tables = lookupTableAccounts.reduce(\n (prev, account) => {\n if (account.exists) {\n assertAccountDecoded(account);\n prev[account.address] = account.data.addresses;\n }\n return prev;\n },\n {} as { [address: Address]: Address[] },\n );\n message = compressTransactionMessageUsingAddressLookupTables(\n message,\n tables,\n );\n }\n\n const messageWithPriorityFees = await addPriorityInstructions(\n message,\n feePayer,\n );\n\n return await partiallySignTransactionMessageWithSigners(\n messageWithPriorityFees,\n );\n}\n\nasync function prepareTransactionMessage(\n instructions: Instruction[],\n rpc: Rpc<SolanaRpcApi>,\n feePayer: KeyPairSigner | NoopSigner,\n) {\n const { value: blockhash } = await rpc\n .getLatestBlockhash({\n commitment: \"confirmed\",\n })\n .send();\n return pipe(\n createTransactionMessage({ version: 0 }),\n (tx) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),\n (tx) => setTransactionMessageFeePayerSigner(feePayer, tx),\n (tx) => appendTransactionMessageInstructions(instructions, tx),\n );\n}\n","import type {\n Instruction,\n Rpc,\n SolanaRpcApi,\n TransactionSigner,\n AccountLookupMeta,\n AccountMeta,\n TransactionMessageWithFeePayerSigner,\n BaseTransactionMessage,\n TransactionMessageWithBlockhashLifetime,\n TransactionMessageWithFeePayer,\n TransactionVersion,\n} from \"@solana/kit\";\nimport { estimateComputeUnitLimitFactory } from \"@solana-program/compute-budget\";\nimport { getJitoConfig, getRpcConfig } from \"./config\";\nimport { rpcFromUrl } from \"./compatibility\";\nimport { processJitoTipForTxMessage } from \"./jito\";\nimport { processComputeBudgetForTxMessage } from \"./computeBudget\";\n\nexport type TxMessage = TransactionMessageWithFeePayerSigner<\n string,\n TransactionSigner<string>\n> &\n Omit<\n TransactionMessageWithBlockhashLifetime &\n Readonly<{\n instructions: readonly Instruction<\n string,\n readonly (AccountLookupMeta<string, string> | AccountMeta<string>)[]\n >[];\n version: TransactionVersion;\n }>,\n \"feePayer\"\n >;\n\nexport async function addPriorityInstructions(\n message: TxMessage,\n signer: TransactionSigner,\n) {\n const { rpcUrl, chainId } = getRpcConfig();\n const jito = getJitoConfig();\n const rpc = rpcFromUrl(rpcUrl);\n\n if (jito.type !== \"none\") {\n message = await processJitoTipForTxMessage(message, signer, jito, chainId);\n }\n let computeUnits = await getComputeUnitsForTxMessage(rpc, message);\n\n return processComputeBudgetForTxMessage(message, computeUnits);\n}\n\nasync function getComputeUnitsForTxMessage(\n rpc: Rpc<SolanaRpcApi>,\n txMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n) {\n const estimator = estimateComputeUnitLimitFactory({\n rpc,\n });\n\n try {\n const estimate = await estimator(txMessage);\n return estimate;\n } catch {\n console.warn(\n \"Transaction simulation failed, using 1,400,000 compute units\",\n );\n return 1_400_000;\n }\n}\n","import { getTransferSolInstruction } from \"@solana-program/system\";\nimport type { Address, TransactionSigner } from \"@solana/kit\";\nimport {\n address,\n lamports,\n prependTransactionMessageInstruction,\n} from \"@solana/kit\";\nimport {\n getJitoBlockEngineUrl,\n type JitoFeeSetting,\n type Percentile,\n} from \"./config\";\nimport type { TxMessage } from \"./priorityFees\";\n\nexport async function processJitoTipForTxMessage(\n message: TxMessage,\n signer: TransactionSigner,\n jito: JitoFeeSetting,\n chainId: string,\n) {\n if (chainId !== \"solana\") {\n console.warn(\"Jito tip is not supported on this chain. Skipping jito tip.\");\n return message;\n }\n let jitoTipLamports = BigInt(0);\n\n if (jito.type === \"exact\") {\n jitoTipLamports = jito.amountLamports;\n } else if (jito.type === \"dynamic\") {\n jitoTipLamports = await recentJitoTip(jito.priorityFeePercentile);\n }\n if (jitoTipLamports > 0) {\n return prependTransactionMessageInstruction(\n getTransferSolInstruction({\n source: signer,\n destination: getJitoTipAddress(),\n amount: jitoTipLamports,\n }),\n message,\n );\n } else {\n return message;\n }\n}\n\n// returns recent jito tip in lamports\nexport async function recentJitoTip(\n priorityFeePercentile?: Percentile | \"50ema\",\n) {\n const blockEngineUrl = getJitoBlockEngineUrl();\n const response = await fetch(`${blockEngineUrl}/api/v1/bundles/tip_floor`);\n if (!response.ok) {\n return BigInt(0);\n }\n const data = await response.json().then((res) => res[0]);\n\n const percentileToKey: Record<Percentile | \"50ema\", string> = {\n \"25\": \"landed_tips_25th_percentile\",\n \"50\": \"landed_tips_50th_percentile\",\n \"75\": \"landed_tips_75th_percentile\",\n \"95\": \"landed_tips_95th_percentile\",\n \"99\": \"landed_tips_99th_percentile\",\n \"50ema\": \"ema_landed_tips_50th_percentile\",\n };\n\n const key = percentileToKey[priorityFeePercentile ?? \"50\"];\n if (!key || !data[key]) {\n return BigInt(0);\n }\n return lamports(BigInt(Math.floor(Number(data[key]) * 10 ** 9))).valueOf();\n}\n\n// should we add an argument that dictates if we should use cached value in case fetch fails ?\n\n// below is taken from legacy sdk (no need to add the whole library)\n// https://jito-foundation.gitbook.io/mev/mev-payment-and-distribution/on-chain-addresses\nconst jitoTipAddresses = [\n \"96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5\",\n \"HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe\",\n \"Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY\",\n \"ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49\",\n \"DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh\",\n \"ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt\",\n \"DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL\",\n \"3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT\",\n];\n\nfunction getJitoTipAddress(): Address {\n // just pick a random one from the list. There are multiple addresses so that no single one\n // can cause local congestion.\n return address(\n jitoTipAddresses[Math.floor(Math.random() * jitoTipAddresses.length)],\n );\n}\n","import {\n getSetComputeUnitPriceInstruction,\n getSetComputeUnitLimitInstruction,\n} from \"@solana-program/compute-budget\";\nimport type { Address, Instruction, MicroLamports, Slot } from \"@solana/kit\";\nimport {\n prependTransactionMessageInstruction,\n isWritableRole,\n} from \"@solana/kit\";\nimport { rpcFromUrl } from \"./compatibility\";\nimport type { Percentile } from \"./config\";\nimport {\n DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER,\n getPriorityFeeConfig,\n getComputeUnitMarginMultiplier,\n getRpcConfig,\n} from \"./config\";\nimport type { TxMessage } from \"./priorityFees\";\n\nexport async function processComputeBudgetForTxMessage(\n message: TxMessage,\n computeUnits: number,\n) {\n const { rpcUrl, supportsPriorityFeePercentile } = getRpcConfig();\n const priorityFee = getPriorityFeeConfig();\n const computeUnitMarginMultiplier = getComputeUnitMarginMultiplier();\n let priorityFeeMicroLamports = BigInt(0);\n if (priorityFee.type === \"exact\") {\n priorityFeeMicroLamports =\n (priorityFee.amountLamports * BigInt(1_000_000)) / BigInt(computeUnits);\n } else if (priorityFee.type === \"dynamic\") {\n const estimatedPriorityFee = await calculateDynamicPriorityFees(\n message.instructions,\n rpcUrl,\n supportsPriorityFeePercentile,\n priorityFee.priorityFeePercentile ?? \"50\",\n );\n\n if (!priorityFee.maxCapLamports) {\n priorityFeeMicroLamports = estimatedPriorityFee;\n } else {\n const maxCapMicroLamports =\n (priorityFee.maxCapLamports * BigInt(1_000_000)) / BigInt(computeUnits);\n\n priorityFeeMicroLamports =\n maxCapMicroLamports > estimatedPriorityFee\n ? estimatedPriorityFee\n : maxCapMicroLamports;\n }\n }\n\n if (priorityFeeMicroLamports > 0) {\n message = prependTransactionMessageInstruction(\n getSetComputeUnitPriceInstruction({\n microLamports: priorityFeeMicroLamports,\n }),\n message,\n );\n }\n message = prependTransactionMessageInstruction(\n getSetComputeUnitLimitInstruction({\n units: Math.ceil(\n computeUnits *\n (computeUnitMarginMultiplier ??\n DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER),\n ),\n }),\n message,\n );\n\n return message;\n}\n\nfunction getWritableAccounts(ixs: readonly Instruction[]) {\n const writable = new Set<Address>();\n ixs.forEach((ix) => {\n if (ix.accounts) {\n ix.accounts.forEach((acc) => {\n if (isWritableRole(acc.role)) writable.add(acc.address);\n });\n }\n });\n return Array.from(writable);\n}\n\nasync function calculateDynamicPriorityFees(\n instructions: readonly Instruction[],\n rpcUrl: string,\n supportsPercentile: boolean,\n percentile: Percentile,\n) {\n const writableAccounts = getWritableAccounts(instructions);\n if (supportsPercentile) {\n return await getRecentPrioritizationFeesWithPercentile(\n rpcUrl,\n writableAccounts,\n percentile,\n );\n } else {\n const rpc = rpcFromUrl(rpcUrl);\n const recent = await rpc\n .getRecentPrioritizationFees(writableAccounts)\n .send();\n const nonZero = recent\n .filter((pf) => pf.prioritizationFee > 0)\n .map((pf) => pf.prioritizationFee);\n const sorted = nonZero.sort((a, b) => Number(a - b));\n return (\n sorted[Math.floor(sorted.length * (parseInt(percentile) / 100))] ||\n BigInt(0)\n );\n }\n}\n\nasync function getRecentPrioritizationFeesWithPercentile(\n rpcEndpoint: string,\n writableAccounts: Address[],\n percentile: Percentile,\n) {\n const response = await fetch(rpcEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"getRecentPrioritizationFees\",\n params: [\n {\n lockedWritableAccounts: writableAccounts,\n percentile: parseInt(percentile) * 100,\n },\n ],\n }),\n });\n const data = await response.json();\n if (data.error) {\n throw new Error(`RPC error: ${data.error.message}`);\n }\n const last150Slots = data.result as RecentPrioritizationFee[];\n last150Slots.sort((a, b) => Number(a.slot - b.slot));\n const last50Slots = last150Slots.slice(-50);\n const nonZeroFees = last50Slots.filter((slot) => slot.prioritizationFee > 0);\n if (nonZeroFees.length === 0) return BigInt(0);\n const sorted = nonZeroFees\n .map((slot) => slot.prioritizationFee)\n .sort((a, b) => Number(a - b));\n const medianIndex = Math.floor(sorted.length / 2);\n return sorted[medianIndex];\n}\n\ntype RecentPrioritizationFee = {\n /**\n * The per-compute-unit fee paid by at least one successfully\n * landed transaction, specified in increments of\n * micro-lamports (0.000001 lamports).\n */\n prioritizationFee: MicroLamports;\n /** Slot in which the fee was observed */\n slot: Slot;\n};\n","import { getRpcConfig } from \"./config\";\nimport type {\n Address,\n Instruction,\n FullySignedTransaction,\n Signature,\n Commitment,\n Transaction,\n TransactionWithLifetime,\n KeyPairSigner,\n NoopSigner,\n} from \"@solana/kit\";\nimport {\n assertIsFullySignedTransaction,\n getBase64EncodedWireTransaction,\n getBase58Decoder,\n} from \"@solana/kit\";\nimport { rpcFromUrl } from \"./compatibility\";\nimport { buildTransaction } from \"./buildTransaction\";\n\n/**\n * Builds and sends a transaction with the given instructions, signers, and commitment level.\n *\n * @param {Instruction[]} instructions - Array of instructions to include in the transaction.\n * @param {KeyPairSigner | NoopSigner} payer - The fee payer for the transaction.\n * @param {(Address | string)[]} [lookupTableAddresses] - Optional array of address lookup table addresses to use.\n * @param {Commitment} [commitment=\"confirmed\"] - The commitment level for transaction confirmation.\n *\n * @returns {Promise<Signature>} A promise that resolves to the transaction signature.\n *\n * @throws {Error} If transaction building or sending fails.\n *\n * @example\n * ```ts\n * // With KeyPairSigner (Node.js) - fully signed and sent\n * const { instructions } = await swapInstructions(rpc, params, pool, 100, keypairSigner);\n * const signature = await buildAndSendTransaction(instructions, keypairSigner);\n * ```\n */\nexport async function buildAndSendTransaction(\n instructions: Instruction[],\n payer: KeyPairSigner | NoopSigner,\n lookupTableAddresses?: (Address | string)[],\n commitment: Commitment = \"confirmed\",\n): Promise<Signature> {\n const tx = await buildTransaction(instructions, payer, lookupTableAddresses);\n assertIsFullySignedTransaction(tx);\n return sendTransaction(tx, commitment);\n}\n\n/**\n * Sends a signed transaction message to the Solana network with a specified commitment level.\n * Asserts that the transaction is fully signed before sending.\n *\n * @param {Transaction & TransactionWithLifetime} transaction - The transaction to send (will be asserted as fully signed).\n * @param {Commitment} [commitment=\"confirmed\"] - The commitment level for transaction confirmation.\n *\n * @returns {Promise<Signature>} A promise that resolves to the transaction signature.\n *\n * @throws {Error} If transaction is missing signatures, sending fails, the RPC connection fails, or the transaction expires.\n *\n * @example\n * ```ts\n * // With KeyPairSigner (Node.js) - already fully signed\n * const tx = await buildTransaction(instructions, keypairSigner);\n * const signature = await sendTransaction(tx, \"confirmed\");\n *\n * // With wallet signature (browser)\n * const partialTx = await buildTransaction(instructions, noopSigner);\n * const [signedTx] = await wallet.modifyAndSignTransactions([partialTx]);\n * const signature = await sendTransaction(signedTx, \"confirmed\");\n * ```\n */\nexport async function sendTransaction(\n transaction: Readonly<Transaction & TransactionWithLifetime>,\n commitment: Commitment = \"confirmed\",\n): Promise<Signature> {\n assertIsFullySignedTransaction(transaction);\n\n const { rpcUrl, pollIntervalMs, resendOnPoll } = getRpcConfig();\n const rpc = rpcFromUrl(rpcUrl);\n const txHash = getTxHash(transaction);\n const encodedTransaction = getBase64EncodedWireTransaction(transaction);\n\n // Simulate transaction first\n const simResult = await rpc\n .simulateTransaction(encodedTransaction, {\n encoding: \"base64\",\n })\n .send();\n\n if (simResult.value.err) {\n throw new Error(\n `Transaction simulation failed: ${JSON.stringify(\n simResult.value.err,\n (key, value) => (typeof value === \"bigint\" ? value.toString() : value),\n )}`,\n );\n }\n\n // Send the transaction (skip preflight since we already simulated)\n const sendTx = async () => {\n await rpc\n .sendTransaction(encodedTransaction, {\n skipPreflight: true,\n encoding: \"base64\",\n ...(resendOnPoll && { maxRetries: BigInt(0) }),\n })\n .send();\n };\n\n try {\n await sendTx();\n } catch (error) {\n throw new Error(`Failed to send transaction: ${error}`);\n }\n\n const expiryTime = Date.now() + 90_000;\n\n while (Date.now() < expiryTime) {\n const iterationStart = Date.now();\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash]).send();\n const status = value[0];\n\n if (status?.confirmationStatus === commitment) {\n if (status.err) {\n throw new Error(`Transaction failed: ${JSON.stringify(status.err)}`);\n }\n return txHash;\n }\n } catch {\n // Continue polling even on RPC errors\n }\n\n if (resendOnPoll) {\n try {\n await sendTx();\n } catch {\n // Ignore resend errors, continue polling\n }\n }\n\n if (pollIntervalMs > 0) {\n const elapsed = Date.now() - iterationStart;\n const remainingDelay = pollIntervalMs - elapsed;\n if (remainingDelay > 0) {\n await new Promise((resolve) => setTimeout(resolve, remainingDelay));\n }\n }\n }\n\n throw new Error(\"Transaction confirmation timeout\");\n}\n\nfunction getTxHash(transaction: Transaction & FullySignedTransaction) {\n const [signature] = Object.values(transaction.signatures);\n const txHash = getBase58Decoder().decode(signature!) as Signature;\n return txHash;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAA8C;AAE9C,iBAAmD;AAe5C,SAAS,WAAW,KAAgC;AACzD,QAAM,UAAM,+BAAmB;AAAA,IAC7B,mBAAmB;AAAA,EACrB,CAAC;AACD,QAAM,gBAAY,sCAA0B,EAAE,IAAI,CAAC;AACnD,QAAM,UAAM,sBAAU,EAAE,KAAK,UAAU,CAAC;AACxC,SAAO;AACT;AAEO,SAAS,mBACd,WACW;AACX,SAAO,WAAW,IAAI,CAAC,aAAS,oBAAQ,IAAI,CAAC,KAAK,CAAC;AACrD;;;AC3BA,IAAI,eAGA,CAAC;AAKE,IAAM,yCAAyC;AAK/C,IAAM,yBAA4C;AAAA,EACvD,aAAa;AAAA,IACX,MAAM;AAAA,IACN,gBAAgB,OAAO,GAAS;AAAA;AAAA,IAChC,uBAAuB;AAAA,EACzB;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,gBAAgB,OAAO,GAAS;AAAA;AAAA,IAChC,uBAAuB;AAAA,EACzB;AAAA,EACA,6BAA6B;AAAA,EAC7B,oBAAoB;AACtB;AAQO,IAAM,eAAe,MAAiB;AAC3C,QAAM,YAAY,aAAa;AAC/B,MAAI,CAAC,WAAW,QAAQ;AACtB,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AACA,SAAO;AACT;AAEA,IAAM,oBAAoB,MAAyB;AACjD,MAAI,CAAC,aAAa,mBAAmB;AACnC,WAAO;AAAA,EACT;AACA,SAAO,aAAa;AACtB;AAOO,IAAM,gBAAgB,MAAsB;AACjD,SAAO,kBAAkB,EAAE;AAC7B;AAOO,IAAM,uBAAuB,MAA0B;AAC5D,SAAO,kBAAkB,EAAE;AAC7B;AAOO,IAAM,iCAAiC,MAAc;AAC1D,SAAO,kBAAkB,EAAE;AAC7B;AAOO,IAAM,wBAAwB,MAAc;AACjD,SAAO,kBAAkB,EAAE;AAC7B;AAEA,IAAM,kBAAkB,CAAC,WAGnB;AACJ,iBAAe;AAAA,IACb,mBAAmB,OAAO,qBAAqB;AAAA,IAC/C,WAAW,OAAO;AAAA,EACpB;AACF;AAwBA,eAAsB,OACpB,KACA,UAII,CAAC,GACuB;AAC5B,QAAM,MAAM,WAAW,GAAG;AAC1B,QAAM,UAAU,MAAM,0BAA0B,GAAG;AAEnD,kBAAgB;AAAA,IACd,GAAG;AAAA,IACH,WAAW;AAAA,MACT,QAAQ;AAAA,MACR,+BACE,QAAQ,iCAAiC;AAAA,MAC3C;AAAA,MACA,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,cAAc,QAAQ,gBAAgB;AAAA,IACxC;AAAA,EACF,CAAC;AAID,QAAM,iBAAiB,IAAI,MAAM,KAAK;AAAA,IACpC,IAAI,QAAQ,MAAM,UAAU;AAC1B,UAAI,SAAS,QAAQ;AACnB,eAAO;AAAA,MACT;AACA,aAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAAA,IAC3C;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEA,eAAe,0BACb,KACkB;AAElB,MAAI;AACF,UAAM,cAAc,MAAM,IAAI,eAAe,EAAE,KAAK;AACpD,UAAM,uBAAgD;AAAA,MACpD,gDAAgD;AAAA,MAChD,8CAA8C;AAAA,MAC9C,8CAA8C;AAAA,MAC9C,8CAA8C;AAAA,IAChD;AACA,WAAO,qBAAqB,WAAW,KAAK;AAAA,EAC9C,SAAS,OAAO;AACd,YAAQ,KAAK,4CAA4C,KAAK;AAC9D,WAAO;AAAA,EACT;AACF;AAOA,eAAsB,sBAAsB,KAAa;AACvD,kBAAgB;AAAA,IACd,GAAG;AAAA,IACH,mBAAmB;AAAA,MACjB,GAAG,kBAAkB;AAAA,MACrB,oBAAoB;AAAA,IACtB;AAAA,EACF,CAAC;AACH;AAOO,SAAS,sBAAsB,aAAyB;AAC7D,kBAAgB;AAAA,IACd,GAAG;AAAA,IACH,mBAAmB;AAAA,MACjB,GAAG,kBAAkB;AAAA,MACrB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAOO,SAAS,kBAAkB,MAAkB;AAClD,kBAAgB;AAAA,IACd,GAAG;AAAA,IACH,mBAAmB;AAAA,MACjB,GAAG,kBAAkB;AAAA,MACrB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAOO,SAAS,+BAA+B,YAAoB;AACjE,kBAAgB;AAAA,IACd,GAAG;AAAA,IACH,mBAAmB;AAAA,MACjB,GAAG,kBAAkB;AAAA,MACrB,6BAA6B;AAAA,IAC/B;AAAA,EACF,CAAC;AACH;AAOO,SAAS,qBAAqB,YAAkC;AACrE,QAAM,OAAO,kBAAkB,EAAE;AACjC,kBAAgB;AAAA,IACd,GAAG;AAAA,IACH,mBAAmB;AAAA,MACjB,GAAG,kBAAkB;AAAA,MACrB,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,uBAAuB;AAAA,MACzB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAOO,SAAS,yBAAyB,YAAwB;AAC/D,QAAM,iBAAiB,kBAAkB;AACzC,QAAM,cAAc,eAAe;AACnC,kBAAgB;AAAA,IACd,GAAG;AAAA,IACH,mBAAmB;AAAA,MACjB,GAAG;AAAA,MACH,aAAa;AAAA,QACX,GAAG;AAAA,QACH,uBAAuB;AAAA,MACzB;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACvQA,IAAAA,cASO;AAEP,kCAAgD;;;ACRhD,IAAAC,yBAAgD;;;ACbhD,oBAA0C;AAE1C,IAAAC,cAIO;AAQP,eAAsB,2BACpB,SACA,QACA,MACA,SACA;AACA,MAAI,YAAY,UAAU;AACxB,YAAQ,KAAK,6DAA6D;AAC1E,WAAO;AAAA,EACT;AACA,MAAI,kBAAkB,OAAO,CAAC;AAE9B,MAAI,KAAK,SAAS,SAAS;AACzB,sBAAkB,KAAK;AAAA,EACzB,WAAW,KAAK,SAAS,WAAW;AAClC,sBAAkB,MAAM,cAAc,KAAK,qBAAqB;AAAA,EAClE;AACA,MAAI,kBAAkB,GAAG;AACvB,eAAO;AAAA,UACL,yCAA0B;AAAA,QACxB,QAAQ;AAAA,QACR,aAAa,kBAAkB;AAAA,QAC/B,QAAQ;AAAA,MACV,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,cACpB,uBACA;AACA,QAAM,iBAAiB,sBAAsB;AAC7C,QAAM,WAAW,MAAM,MAAM,GAAG,cAAc,2BAA2B;AACzE,MAAI,CAAC,SAAS,IAAI;AAChB,WAAO,OAAO,CAAC;AAAA,EACjB;AACA,QAAM,OAAO,MAAM,SAAS,KAAK,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;AAEvD,QAAM,kBAAwD;AAAA,IAC5D,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAEA,QAAM,MAAM,gBAAgB,yBAAyB,IAAI;AACzD,MAAI,CAAC,OAAO,CAAC,KAAK,GAAG,GAAG;AACtB,WAAO,OAAO,CAAC;AAAA,EACjB;AACA,aAAO,sBAAS,OAAO,KAAK,MAAM,OAAO,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ;AAC3E;AAMA,IAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,oBAA6B;AAGpC,aAAO;AAAA,IACL,iBAAiB,KAAK,MAAM,KAAK,OAAO,IAAI,iBAAiB,MAAM,CAAC;AAAA,EACtE;AACF;;;AC7FA,4BAGO;AAEP,IAAAC,cAGO;AAWP,eAAsB,iCACpB,SACA,cACA;AACA,QAAM,EAAE,QAAQ,8BAA8B,IAAI,aAAa;AAC/D,QAAM,cAAc,qBAAqB;AACzC,QAAM,8BAA8B,+BAA+B;AACnE,MAAI,2BAA2B,OAAO,CAAC;AACvC,MAAI,YAAY,SAAS,SAAS;AAChC,+BACG,YAAY,iBAAiB,OAAO,GAAS,IAAK,OAAO,YAAY;AAAA,EAC1E,WAAW,YAAY,SAAS,WAAW;AACzC,UAAM,uBAAuB,MAAM;AAAA,MACjC,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,YAAY,yBAAyB;AAAA,IACvC;AAEA,QAAI,CAAC,YAAY,gBAAgB;AAC/B,iCAA2B;AAAA,IAC7B,OAAO;AACL,YAAM,sBACH,YAAY,iBAAiB,OAAO,GAAS,IAAK,OAAO,YAAY;AAExE,iCACE,sBAAsB,uBAClB,uBACA;AAAA,IACR;AAAA,EACF;AAEA,MAAI,2BAA2B,GAAG;AAChC,kBAAU;AAAA,UACR,yDAAkC;AAAA,QAChC,eAAe;AAAA,MACjB,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACA,gBAAU;AAAA,QACR,yDAAkC;AAAA,MAChC,OAAO,KAAK;AAAA,QACV,gBACG,+BACC;AAAA,MACN;AAAA,IACF,CAAC;AAAA,IACD;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,KAA6B;AACxD,QAAM,WAAW,oBAAI,IAAa;AAClC,MAAI,QAAQ,CAAC,OAAO;AAClB,QAAI,GAAG,UAAU;AACf,SAAG,SAAS,QAAQ,CAAC,QAAQ;AAC3B,gBAAI,4BAAe,IAAI,IAAI,EAAG,UAAS,IAAI,IAAI,OAAO;AAAA,MACxD,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACD,SAAO,MAAM,KAAK,QAAQ;AAC5B;AAEA,eAAe,6BACb,cACA,QACA,oBACA,YACA;AACA,QAAM,mBAAmB,oBAAoB,YAAY;AACzD,MAAI,oBAAoB;AACtB,WAAO,MAAM;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,MAAM,WAAW,MAAM;AAC7B,UAAM,SAAS,MAAM,IAClB,4BAA4B,gBAAgB,EAC5C,KAAK;AACR,UAAM,UAAU,OACb,OAAO,CAAC,OAAO,GAAG,oBAAoB,CAAC,EACvC,IAAI,CAAC,OAAO,GAAG,iBAAiB;AACnC,UAAM,SAAS,QAAQ,KAAK,CAAC,GAAG,MAAM,OAAO,IAAI,CAAC,CAAC;AACnD,WACE,OAAO,KAAK,MAAM,OAAO,UAAU,SAAS,UAAU,IAAI,IAAI,CAAC,KAC/D,OAAO,CAAC;AAAA,EAEZ;AACF;AAEA,eAAe,0CACb,aACA,kBACA,YACA;AACA,QAAM,WAAW,MAAM,MAAM,aAAa;AAAA,IACxC,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,QAAQ;AAAA,QACN;AAAA,UACE,wBAAwB;AAAA,UACxB,YAAY,SAAS,UAAU,IAAI;AAAA,QACrC;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,MAAI,KAAK,OAAO;AACd,UAAM,IAAI,MAAM,cAAc,KAAK,MAAM,OAAO,EAAE;AAAA,EACpD;AACA,QAAM,eAAe,KAAK;AAC1B,eAAa,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACnD,QAAM,cAAc,aAAa,MAAM,GAAG;AAC1C,QAAM,cAAc,YAAY,OAAO,CAAC,SAAS,KAAK,oBAAoB,CAAC;AAC3E,MAAI,YAAY,WAAW,EAAG,QAAO,OAAO,CAAC;AAC7C,QAAM,SAAS,YACZ,IAAI,CAAC,SAAS,KAAK,iBAAiB,EACpC,KAAK,CAAC,GAAG,MAAM,OAAO,IAAI,CAAC,CAAC;AAC/B,QAAM,cAAc,KAAK,MAAM,OAAO,SAAS,CAAC;AAChD,SAAO,OAAO,WAAW;AAC3B;;;AFnHA,eAAsB,wBACpB,SACA,QACA;AACA,QAAM,EAAE,QAAQ,QAAQ,IAAI,aAAa;AACzC,QAAM,OAAO,cAAc;AAC3B,QAAM,MAAM,WAAW,MAAM;AAE7B,MAAI,KAAK,SAAS,QAAQ;AACxB,cAAU,MAAM,2BAA2B,SAAS,QAAQ,MAAM,OAAO;AAAA,EAC3E;AACA,MAAI,eAAe,MAAM,4BAA4B,KAAK,OAAO;AAEjE,SAAO,iCAAiC,SAAS,YAAY;AAC/D;AAEA,eAAe,4BACb,KACA,WACA;AACA,QAAM,gBAAY,wDAAgC;AAAA,IAChD;AAAA,EACF,CAAC;AAED,MAAI;AACF,UAAM,WAAW,MAAM,UAAU,SAAS;AAC1C,WAAO;AAAA,EACT,QAAQ;AACN,YAAQ;AAAA,MACN;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;ADrBA,eAAsB,iBACpB,cACA,UACA,sBAC0D;AAC1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,mBAAmB,oBAAoB;AAAA,EACzC;AACF;AAEA,eAAe,wBACb,cACA,UACA,sBACA;AACA,QAAM,EAAE,OAAO,IAAI,aAAa;AAChC,QAAM,MAAM,WAAW,MAAM;AAE7B,MAAI,UAAU,MAAM,0BAA0B,cAAc,KAAK,QAAQ;AAEzE,MAAI,sBAAsB,QAAQ;AAChC,UAAM,sBAAsB,UAAM;AAAA,MAChC;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS,oBAAoB;AAAA,MACjC,CAAC,MAAM,YAAY;AACjB,YAAI,QAAQ,QAAQ;AAClB,gDAAqB,OAAO;AAC5B,eAAK,QAAQ,OAAO,IAAI,QAAQ,KAAK;AAAA,QACvC;AACA,eAAO;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IACH;AACA,kBAAU;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,0BAA0B,MAAM;AAAA,IACpC;AAAA,IACA;AAAA,EACF;AAEA,SAAO,UAAM;AAAA,IACX;AAAA,EACF;AACF;AAEA,eAAe,0BACb,cACA,KACA,UACA;AACA,QAAM,EAAE,OAAO,UAAU,IAAI,MAAM,IAChC,mBAAmB;AAAA,IAClB,YAAY;AAAA,EACd,CAAC,EACA,KAAK;AACR,aAAO;AAAA,QACL,sCAAyB,EAAE,SAAS,EAAE,CAAC;AAAA,IACvC,CAAC,WAAO,yDAA4C,WAAW,EAAE;AAAA,IACjE,CAAC,WAAO,iDAAoC,UAAU,EAAE;AAAA,IACxD,CAAC,WAAO,kDAAqC,cAAc,EAAE;AAAA,EAC/D;AACF;;;AIxGA,IAAAC,cAIO;AAuBP,eAAsB,wBACpB,cACA,OACA,sBACA,aAAyB,aACL;AACpB,QAAM,KAAK,MAAM,iBAAiB,cAAc,OAAO,oBAAoB;AAC3E,kDAA+B,EAAE;AACjC,SAAO,gBAAgB,IAAI,UAAU;AACvC;AAyBA,eAAsB,gBACpB,aACA,aAAyB,aACL;AACpB,kDAA+B,WAAW;AAE1C,QAAM,EAAE,QAAQ,gBAAgB,aAAa,IAAI,aAAa;AAC9D,QAAM,MAAM,WAAW,MAAM;AAC7B,QAAM,SAAS,UAAU,WAAW;AACpC,QAAM,yBAAqB,6CAAgC,WAAW;AAGtE,QAAM,YAAY,MAAM,IACrB,oBAAoB,oBAAoB;AAAA,IACvC,UAAU;AAAA,EACZ,CAAC,EACA,KAAK;AAER,MAAI,UAAU,MAAM,KAAK;AACvB,UAAM,IAAI;AAAA,MACR,kCAAkC,KAAK;AAAA,QACrC,UAAU,MAAM;AAAA,QAChB,CAAC,KAAK,UAAW,OAAO,UAAU,WAAW,MAAM,SAAS,IAAI;AAAA,MAClE,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,SAAS,YAAY;AACzB,UAAM,IACH,gBAAgB,oBAAoB;AAAA,MACnC,eAAe;AAAA,MACf,UAAU;AAAA,MACV,GAAI,gBAAgB,EAAE,YAAY,OAAO,CAAC,EAAE;AAAA,IAC9C,CAAC,EACA,KAAK;AAAA,EACV;AAEA,MAAI;AACF,UAAM,OAAO;AAAA,EACf,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,+BAA+B,KAAK,EAAE;AAAA,EACxD;AAEA,QAAM,aAAa,KAAK,IAAI,IAAI;AAEhC,SAAO,KAAK,IAAI,IAAI,YAAY;AAC9B,UAAM,iBAAiB,KAAK,IAAI;AAEhC,QAAI;AACF,YAAM,EAAE,MAAM,IAAI,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,KAAK;AAChE,YAAM,SAAS,MAAM,CAAC;AAEtB,UAAI,QAAQ,uBAAuB,YAAY;AAC7C,YAAI,OAAO,KAAK;AACd,gBAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,QACrE;AACA,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,QAAI,cAAc;AAChB,UAAI;AACF,cAAM,OAAO;AAAA,MACf,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI,iBAAiB,GAAG;AACtB,YAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,YAAM,iBAAiB,iBAAiB;AACxC,UAAI,iBAAiB,GAAG;AACtB,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,cAAc,CAAC;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,kCAAkC;AACpD;AAEA,SAAS,UAAU,aAAmD;AACpE,QAAM,CAAC,SAAS,IAAI,OAAO,OAAO,YAAY,UAAU;AACxD,QAAM,aAAS,8BAAiB,EAAE,OAAO,SAAU;AACnD,SAAO;AACT;","names":["import_kit","import_compute_budget","import_kit","import_kit","import_kit"]}