@forevermoney/sdk 0.5.3 → 0.5.4

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chains/deployment.ts","../src/core/amounts.ts","../src/core/errors.ts","../src/core/validation.ts","../src/bridge/stake-rounding.ts","../src/core/addresses.ts","../src/abis/index.ts","../src/bridge/plans.ts","../src/core/plans.ts","../src/core/transport.ts","../src/core/provider-errors.ts","../src/vaults/plans.ts","../src/bridge/tracking.ts","../src/bridge/receipts.ts","../src/core/receipts.ts","../src/client.ts","../src/vaults/receipts.ts","../src/core/transactions.ts"],"sourcesContent":["import { getAddress } from 'viem'\n\nexport const BASE_CHAIN_ID = 8453\nexport const ROBINHOOD_CHAIN_ID = 4663\nexport const SUBTENSOR_CHAIN_ID = 964\nexport const BASE_CCIP_SELECTOR = 15_971_525_489_660_198_786n\nexport const ROBINHOOD_CCIP_SELECTOR = 6_180_753_054_346_818_345n\nexport const SUBTENSOR_CCIP_SELECTOR = 2_135_107_236_357_186_872n\nexport const RAO_PER_TAO = 1_000_000_000n\nexport const EVM_WEI_PER_RAO = 1_000_000_000n\nexport const SN80_NETUID = 80n\nexport const FOREVERMONEY_DEPLOYMENT_VERSION = '1.3.0' as const\n\nexport const foreverMoneyDeployment = Object.freeze({\n version: FOREVERMONEY_DEPLOYMENT_VERSION,\n base: Object.freeze({\n key: 'base',\n name: 'Base',\n chainId: BASE_CHAIN_ID,\n ccipSelector: BASE_CCIP_SELECTOR,\n contracts: Object.freeze({\n gateway: getAddress('0x1da2415229b614C787e145D1D7346eb496319C52'),\n // Retired gateways, oldest first; kept only to track transfers sent\n // through them.\n legacyGateways: [\n getAddress('0x5EF3d7D19e4b233a1A169DA0d5CB02ec6b160a2C'),\n ] as readonly `0x${string}`[],\n wrappedTao: getAddress(\n '0xf3081494b87e8d5fb7960f066e931d1d0e6e3d67'\n ),\n wrappedSn80: getAddress(\n '0x6f63d869011f95274498023b4abfc00b30c34378'\n ),\n ccipRouter: getAddress(\n '0x881e3A65B4d4a04dD529061dd0071cf975F58bCD'\n ),\n ccipOffRampFromSubtensor: getAddress(\n '0xf09AFe78d3c7d359b334d7cB88995751F7eC5E13'\n ),\n vaultFactory: getAddress(\n '0x9b7F3c7aa335D8BF9f91741E541820466735F868'\n ),\n vaultManagerImplementation: getAddress(\n '0x235Ad8654fe3a1619a9892eBCaD9361F416168da'\n ),\n batchLiquidityManagerQuery: getAddress(\n '0xd117176C5E6809b68500995F59589A8c081565A5'\n ),\n weth: getAddress('0x4200000000000000000000000000000000000006'),\n }),\n deploymentBlock: 50_098_800,\n }),\n robinhood: Object.freeze({\n key: 'robinhood',\n name: 'Robinhood',\n chainId: ROBINHOOD_CHAIN_ID,\n ccipSelector: ROBINHOOD_CCIP_SELECTOR,\n contracts: Object.freeze({\n gateway: getAddress('0xf27fdA637131E25B2A1b4865ED9597d881980c7E'),\n legacyGateways: [\n getAddress('0x53Dcc4FE04193e489BE537F722F65317DB1E65d8'),\n ] as readonly `0x${string}`[],\n wrappedTao: getAddress(\n '0xf3081494B87e8D5fb7960f066E931D1D0e6E3d67'\n ),\n ccipRouter: getAddress(\n '0x06fC836cf9839B1cd891C440A0a45242DA6Ae1c9'\n ),\n ccipOffRampFromSubtensor: getAddress(\n '0xcDca5D374e46A6DDDab50bD2D9acB8c796eC35C3'\n ),\n }),\n }),\n subtensor: Object.freeze({\n chainId: SUBTENSOR_CHAIN_ID,\n ccipSelector: SUBTENSOR_CCIP_SELECTOR,\n contracts: Object.freeze({\n // V5.1 AlphaGateway: multi-validator staked input (tao-bridge 485c898).\n gateway: getAddress('0xd5Fa238aa4177f6c1341491969d9cBeec94EEd69'),\n // V4 and V5 hubs. The spokes still deliver to the V5 hub (their hub\n // pointer is immutable), so it stays here for delivery tracking.\n legacyGateways: [\n getAddress('0x998f20Fea90bF7792774dECc7f994716442B1705'),\n getAddress('0xcd0C6d98D0A126B1c113d15b4c28F38321437787'),\n ] as readonly `0x${string}`[],\n alphaVault: getAddress(\n '0x11837459896D96F821a8D88eC93a3C8D152033D4'\n ),\n wrappedTao: getAddress(\n '0xC5b6C1632d34901239396F5E1BDe54B342900256'\n ),\n wrappedSn80: getAddress(\n '0xfD628dE75EF96f0A5C59659159C6cA81E0DC2222'\n ),\n ccipRouter: getAddress(\n '0xD941fBEcD2b971d0F54b4C34286C95faB52B60B8'\n ),\n ccipOffRampFromBase: getAddress(\n '0x51a6150400ed9F0Ae240F5D1b15E3b45Fc4339C7'\n ),\n ccipOffRampFromRobinhood: getAddress(\n '0x51a6150400ed9F0Ae240F5D1b15E3b45Fc4339C7'\n ),\n stakingPrecompile: getAddress(\n '0x0000000000000000000000000000000000000805'\n ),\n }),\n }),\n})\n\nexport type ForeverMoneyDeployment = typeof foreverMoneyDeployment\nexport type ForeverMoneyEvmChain = 'base' | 'robinhood'\n\nexport function getForeverMoneyEvmDeployment(\n chain: ForeverMoneyEvmChain = 'base'\n): ForeverMoneyDeployment['base'] | ForeverMoneyDeployment['robinhood'] {\n return foreverMoneyDeployment[chain]\n}\n","import { maxUint256, formatUnits, parseUnits } from 'viem'\nimport { EVM_WEI_PER_RAO } from '../chains/deployment.js'\nimport { ForeverMoneyError } from './errors.js'\n\nexport const BASIS_POINTS = 10_000n\nexport const NETWORK_FEE_BUFFER_BPS = 200n\nexport const GAS_LIMIT_BUFFER_BPS = 5_000n\n\nexport function parseTaoAmount(value: string): bigint {\n if (typeof value !== 'string') {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must be decimal strings.'\n )\n }\n const decimalPlaces = value.includes('.')\n ? (value.split('.')[1]?.length ?? 0)\n : 0\n if (decimalPlaces > 9) {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must be positive decimal strings with at most nine decimal places.'\n )\n }\n let amount: bigint\n try {\n amount = parseUnits(value, 18)\n } catch {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must be positive decimal strings with at most nine decimal places.'\n )\n }\n assertWholeRao(amount)\n return amount\n}\n\nexport function assertWholeRao(amountWei: bigint): void {\n if (typeof amountWei !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The amount must be a bigint.'\n )\n }\n if (amountWei === 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_ZERO',\n 'The amount must be greater than zero.'\n )\n }\n if (amountWei < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The amount cannot be negative.'\n )\n }\n if (amountWei > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The amount exceeds uint256.'\n )\n }\n if (amountWei % EVM_WEI_PER_RAO !== 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must resolve to a whole RAO.'\n )\n }\n}\n\nexport function formatTaoAmount(amountWei: bigint): string {\n if (typeof amountWei !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The TAO amount must be a bigint.'\n )\n }\n if (amountWei < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'A TAO amount cannot be negative.'\n )\n }\n if (amountWei > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The TAO amount exceeds uint256.'\n )\n }\n if (amountWei % EVM_WEI_PER_RAO !== 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must resolve to a whole RAO.'\n )\n }\n const formatted = formatUnits(amountWei, 18)\n return formatted.includes('.') ? formatted : `${formatted}.0`\n}\n\nfunction mulDivCeil(\n value: bigint,\n numerator: bigint,\n denominator: bigint\n): bigint {\n return (value * numerator + denominator - 1n) / denominator\n}\n\nexport function feeWithBuffer(fee: bigint): bigint {\n if (typeof fee !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The network fee must be a bigint.'\n )\n }\n if (fee < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'A network fee cannot be negative.'\n )\n }\n const buffered = mulDivCeil(\n fee,\n BASIS_POINTS + NETWORK_FEE_BUFFER_BPS,\n BASIS_POINTS\n )\n if (buffered > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The buffered network fee exceeds uint256.'\n )\n }\n return buffered\n}\n\nexport function gasLimitWithBuffer(gasLimit: bigint): bigint {\n if (typeof gasLimit !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The gas limit must be a bigint.'\n )\n }\n if (gasLimit <= 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'A gas limit must be greater than zero.'\n )\n }\n const buffered = mulDivCeil(\n gasLimit,\n BASIS_POINTS + GAS_LIMIT_BUFFER_BPS,\n BASIS_POINTS\n )\n if (buffered > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The buffered gas limit exceeds uint256.'\n )\n }\n return buffered\n}\n","export type ForeverMoneyErrorCode =\n | 'AMOUNT_BELOW_MINIMUM'\n | 'AMOUNT_NOT_WHOLE_RAO'\n | 'AMOUNT_ZERO'\n | 'CHAIN_MISMATCH'\n | 'INVALID_ADDRESS'\n | 'INVALID_BYTES32'\n | 'INVALID_PARTNER_FEE'\n | 'INVALID_PROVIDER_RESPONSE'\n | 'INVALID_SS58'\n | 'INVALID_TRANSACTION_PLAN'\n | 'MISSING_TRANSPORT'\n | 'RPC_ERROR'\n | 'SIMULATION_REVERTED'\n\nexport class ForeverMoneyError extends Error {\n readonly code: ForeverMoneyErrorCode\n readonly details: Readonly<Record<string, unknown>> | undefined\n\n constructor(\n code: ForeverMoneyErrorCode,\n message: string,\n details?: Readonly<Record<string, unknown>>\n ) {\n super(message)\n this.name = 'ForeverMoneyError'\n this.code = code\n this.details =\n details === undefined ? undefined : Object.freeze({ ...details })\n }\n}\n","import { maxUint256, zeroHash, isHex, type Hex } from 'viem'\nimport { ForeverMoneyError } from './errors.js'\n\nfunction assertBigInt(\n amount: unknown,\n label: string\n): asserts amount is bigint {\n if (typeof amount !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be a bigint.`\n )\n }\n}\n\nexport function assertPositiveAmount(\n amount: unknown,\n label: string\n): asserts amount is bigint {\n assertBigInt(amount, label)\n if (amount === 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_ZERO',\n `${label} must be greater than zero.`\n )\n }\n if (amount < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} cannot be negative.`\n )\n }\n if (amount > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} exceeds uint256.`\n )\n }\n}\n\nexport function assertNonNegativeAmount(\n amount: unknown,\n label: string\n): asserts amount is bigint {\n assertBigInt(amount, label)\n if (amount < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} cannot be negative.`\n )\n }\n if (amount > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} exceeds uint256.`\n )\n }\n}\n\nexport function assertBoolean(\n value: unknown,\n label: string\n): asserts value is boolean {\n if (typeof value !== 'boolean') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be a boolean.`\n )\n }\n}\n\nexport function assertArray(\n value: unknown,\n label: string\n): asserts value is readonly unknown[] {\n if (!Array.isArray(value)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be an array.`\n )\n }\n}\n\nexport function assertRecord(\n value: unknown,\n label: string\n): asserts value is Readonly<Record<string, unknown>> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be an object.`\n )\n }\n}\n\nexport function normalizeBytes32(value: string, label: string): Hex {\n if (!isHex(value, { strict: true }) || value.length !== 66) {\n throw new ForeverMoneyError(\n 'INVALID_BYTES32',\n `${label} must be a 32-byte hex value.`\n )\n }\n return value.toLowerCase() as Hex\n}\n\nexport function normalizeOptionalBytes32(\n value: string | undefined,\n label: string\n): Hex {\n return value === undefined ? zeroHash : normalizeBytes32(value, label)\n}\n","import { EVM_WEI_PER_RAO } from '../chains/deployment.js'\nimport { assertWholeRao } from '../core/amounts.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport {\n assertBoolean,\n assertNonNegativeAmount,\n assertPositiveAmount,\n normalizeBytes32,\n} from '../core/validation.js'\nimport type { StakePull } from './plans.js'\n\nexport interface StakePosition {\n readonly hotkey: string\n readonly stakeRao: bigint\n}\nexport interface StakeRoundingOptions {\n readonly enabled: boolean\n /** Current source balances, including any partner fee headroom. */\n readonly positions: readonly StakePosition[]\n /** Minimum positive remainder to leave on any source. Defaults to zero. */\n readonly minStakeRao?: bigint\n}\nexport interface StakeRoundingResult {\n readonly requestedAmountWei: bigint\n readonly amountWei: bigint\n readonly minAmountOutWei: bigint\n readonly pulls: readonly StakePull[]\n /** False when approval is still required; prepare again after approval. */\n readonly simulationComplete: boolean\n}\nexport interface EstimateRoundedStakeRequest<T> {\n readonly amountWei: bigint\n readonly minAmountOutWei: bigint\n readonly pulls: readonly StakePull[]\n readonly positions: readonly StakePosition[]\n readonly minStakeRao?: bigint\n /** Defaults to true. False estimates the exact input once, without adjustments. */\n readonly adjustRounding?: boolean\n readonly partnerFeeBps?: number\n readonly isActive?: () => boolean\n readonly quoteAndEstimate: (\n amountWei: bigint,\n pulls: readonly StakePull[],\n minAmountOutWei: bigint\n ) => Promise<T>\n}\nexport type RoundedStakeEstimate<T> = T & {\n readonly amountWei: bigint\n readonly minAmountOutWei: bigint\n readonly pulls: readonly StakePull[]\n}\n\nfunction invalid(message: string): never {\n throw new ForeverMoneyError('INVALID_TRANSACTION_PLAN', message)\n}\n\n/** Small explicit output tolerance for stake transfer/deposit dust. Never returns zero. */\nexport function stakedMinimumOutput(\n amountWei: bigint,\n sourceCount = 1\n): bigint {\n assertWholeRao(amountWei)\n if (!Number.isInteger(sourceCount) || sourceCount < 1 || sourceCount > 16)\n invalid('Source count must be between 1 and 16.')\n const rao = amountWei / EVM_WEI_PER_RAO\n const dust = 2n * BigInt(sourceCount) + 2n\n return (rao > dust ? rao - dust : rao) * EVM_WEI_PER_RAO\n}\n\n/** Supports raw RPC, ethers and viem nested errors. Ignores unrelated revert data. */\nexport function strandedStakeSource(error: unknown): string | null {\n const queue: unknown[] = [error]\n const seen = new Set<object>()\n while (queue.length && seen.size < 20) {\n const entry = queue.shift()\n if (\n typeof entry === 'string' &&\n /^0x5408a598[0-9a-f]{128}$/i.test(entry)\n )\n return `0x${entry.slice(10, 74)}`.toLowerCase()\n if (entry && typeof entry === 'object' && !seen.has(entry)) {\n seen.add(entry)\n for (const key of [\n 'data',\n 'error',\n 'info',\n 'cause',\n 'details',\n 'rpcData',\n ]) {\n const nested = (entry as Record<string, unknown>)[key]\n if (nested != null) queue.push(nested)\n }\n }\n }\n return null\n}\n\n/** SDK-owned, read-only candidate search. Never lowers minAmountOutWei or broadcasts.\n * At most eight reductions of one alpha base unit; only StrandedStake triggers retries.\n * quoteAndEstimate must quote and simulate the exact candidate, and must never sign/send.\n */\nexport async function estimateRoundedStake<T>({\n amountWei,\n minAmountOutWei,\n pulls,\n positions,\n minStakeRao = 0n,\n adjustRounding = true,\n partnerFeeBps = 0,\n quoteAndEstimate,\n isActive = () => true,\n}: EstimateRoundedStakeRequest<T>): Promise<RoundedStakeEstimate<T>> {\n assertWholeRao(amountWei)\n assertPositiveAmount(minAmountOutWei, 'Minimum output')\n if (minAmountOutWei > amountWei)\n invalid('Minimum output cannot exceed input.')\n assertBoolean(adjustRounding, 'adjustRounding')\n assertNonNegativeAmount(minStakeRao, 'Minimum remaining stake')\n if (\n !Number.isInteger(partnerFeeBps) ||\n partnerFeeBps < 0 ||\n partnerFeeBps > 10000\n )\n invalid('Invalid partner fee basis points.')\n if (!Array.isArray(pulls) || pulls.length < 1 || pulls.length > 16)\n invalid('Provide between 1 and 16 stake pulls.')\n const keys = new Set<string>()\n const originalPulls = pulls.map((pull) => {\n const hotkey = normalizeBytes32(pull.hotkey, 'Validator').toLowerCase()\n if (keys.has(hotkey)) invalid('Duplicate stake source.')\n keys.add(hotkey)\n assertPositiveAmount(pull.amountRao, 'Stake pull')\n return { hotkey, amountRao: pull.amountRao }\n })\n if (\n originalPulls.reduce((sum, pull) => sum + pull.amountRao, 0n) *\n EVM_WEI_PER_RAO !==\n amountWei\n )\n invalid('Stake pulls must sum to the input amount.')\n const balances = new Map<string, bigint>()\n if (!Array.isArray(positions)) invalid('Stake positions must be an array.')\n for (const position of positions) {\n const key = normalizeBytes32(position.hotkey, 'Validator').toLowerCase()\n if (balances.has(key)) invalid('Duplicate stake position.')\n assertNonNegativeAmount(position.stakeRao, 'Stake balance')\n balances.set(key, position.stakeRao)\n }\n const fits = (candidatePulls: readonly StakePull[]): boolean => {\n const total = candidatePulls.reduce(\n (sum, pull) => sum + pull.amountRao,\n 0n\n )\n const cut = (total * BigInt(partnerFeeBps)) / 10000n\n const shares = candidatePulls.map((pull, index) =>\n index ? (cut * pull.amountRao) / total : 0n\n )\n shares[0] = cut - shares.reduce((sum, share) => sum + share, 0n)\n return candidatePulls.every((pull, index) => {\n const balance = balances.get(pull.hotkey)\n if (balance == null) return false\n const remainder = balance - pull.amountRao - shares[index]!\n return (\n remainder === 0n || (remainder > 0n && remainder >= minStakeRao)\n )\n })\n }\n if (!fits(originalPulls))\n invalid(\n 'Stake positions cannot cover the pulls, partner fee, and minimum remainder.'\n )\n let candidate = amountWei\n let candidatePulls = originalPulls\n for (let attempt = 0; ; attempt++) {\n if (!isActive()) throw new Error('Stake quote cancelled.')\n try {\n const result = await quoteAndEstimate(\n candidate,\n candidatePulls,\n minAmountOutWei\n )\n if (!isActive()) throw new Error('Stake quote cancelled.')\n return Object.freeze({\n ...result,\n amountWei: candidate,\n pulls: Object.freeze(\n candidatePulls.map((pull) => Object.freeze({ ...pull }))\n ),\n minAmountOutWei,\n })\n } catch (error) {\n const hotkey = strandedStakeSource(error)\n if (\n !isActive() ||\n !adjustRounding ||\n !hotkey ||\n attempt >= 8 ||\n candidate - EVM_WEI_PER_RAO < minAmountOutWei\n )\n throw error\n const index = candidatePulls.findIndex(\n (pull) => pull.hotkey === hotkey\n )\n if (index < 0 || candidatePulls[index]!.amountRao <= 1n) throw error\n const nextPulls = candidatePulls.map((pull, i) =>\n i === index ? { ...pull, amountRao: pull.amountRao - 1n } : pull\n )\n if (!fits(nextPulls)) throw error\n candidatePulls = nextPulls\n candidate -= EVM_WEI_PER_RAO\n }\n }\n}\n","import {\n AccountId,\n Blake2256,\n getSs58AddressInfo,\n} from '@polkadot-api/substrate-bindings'\nimport {\n bytesToHex,\n concat,\n getAddress,\n hexToBytes,\n isAddress,\n stringToBytes,\n zeroAddress,\n type Address,\n type Hex,\n} from 'viem'\nimport { ForeverMoneyError } from './errors.js'\n\nconst BITTENSOR_SS58_PREFIX = 42\n\nexport function normalizeEvmAddress(value: string): Address {\n // All-uppercase and all-lowercase are valid unchecksummed forms. Mixed case\n // must still pass EIP-55 validation, as it did before the viem migration.\n const candidate =\n typeof value === 'string' && /^0x[0-9A-F]{40}$/.test(value)\n ? value.toLowerCase()\n : value\n if (!isAddress(candidate) || candidate === zeroAddress) {\n throw new ForeverMoneyError(\n 'INVALID_ADDRESS',\n 'Expected a non-zero EVM address.'\n )\n }\n return getAddress(candidate)\n}\n\nexport function evmToMirrorSS58(evmAddress: string): string {\n return AccountId(BITTENSOR_SS58_PREFIX).dec(\n Blake2256(\n concat([\n stringToBytes('evm:'),\n hexToBytes(normalizeEvmAddress(evmAddress)),\n ])\n )\n )\n}\n\nfunction decodeBittensorAddress(value: string): Uint8Array {\n try {\n if (typeof value !== 'string' || !value || value.startsWith('0x'))\n throw new Error('Raw hex is not SS58.')\n const info = getSs58AddressInfo(value)\n if (\n !info.isValid ||\n info.ss58Format !== BITTENSOR_SS58_PREFIX ||\n info.publicKey.length !== 32\n )\n throw new Error('Invalid Bittensor address.')\n const publicKey = info.publicKey\n return publicKey\n } catch {\n throw new ForeverMoneyError(\n 'INVALID_SS58',\n 'Expected a Bittensor SS58 address with prefix 42.'\n )\n }\n}\n\nexport function normalizeSS58(value: string): string {\n return AccountId(BITTENSOR_SS58_PREFIX).dec(decodeBittensorAddress(value))\n}\n\nexport function isBittensorSS58(value: string): boolean {\n try {\n decodeBittensorAddress(value)\n return true\n } catch {\n return false\n }\n}\n\nexport function ss58ToPublicKey(value: string): Hex {\n return bytesToHex(decodeBittensorAddress(value))\n}\n","export const ERC20_ABI = Object.freeze([\n 'function allowance(address owner,address spender) view returns (uint256)',\n 'function approve(address spender,uint256 amount) returns (bool)',\n 'function balanceOf(address account) view returns (uint256)',\n] as const)\n\nexport const STAKING_ABI = Object.freeze([\n 'function allowance(address sourceAddress,address spenderAddress,uint256 netuid) view returns (uint256)',\n 'function approve(address spenderAddress,uint256 netuid,uint256 absoluteAmount)',\n 'function getStake(bytes32 hotkey,bytes32 coldkey,uint256 netuid) view returns (uint256)',\n] as const)\n\nexport const SPOKE_GATEWAY_ABI = Object.freeze([\n 'function ROUTER() view returns (address)',\n 'function BITTENSOR_SELECTOR() view returns (uint64)',\n 'function SUBTENSOR_GATEWAY() view returns (address)',\n 'function maxIntegratorFeeBps() view returns (uint16)',\n 'function bridgeFeeBps() view returns (uint16)',\n 'function quoteBridgeToFinney(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit) view returns (uint256 fee)',\n 'function quoteBridgeToFinney(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit,uint256 gasLimit) view returns (uint256 fee)',\n 'function bridgeToFinney(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit) payable returns (bytes32 messageId)',\n 'function bridgeToFinney(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit,uint256 gasLimit) payable returns (bytes32 messageId)',\n 'function quoteBridgeToFinneyWithFee(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit,uint256 gasLimit,(address recipient,uint16 bps) integrator) view returns (uint256 fee,uint256 cut,uint256 amountCrossing)',\n 'function bridgeToFinneyWithFee(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit,uint256 gasLimit,(address recipient,uint16 bps) integrator) payable returns (bytes32 messageId)',\n 'event BridgedToFinney(address indexed token,address indexed sender,bytes32 indexed ss58,uint256 amount,bytes32 messageId)',\n] as const)\n\nexport const ALPHA_GATEWAY_ABI = Object.freeze([\n 'function ROUTER() view returns (address)',\n 'function allowedLane(uint64 selector) view returns (bool)',\n 'function maxIntegratorFeeBps() view returns (uint16)',\n 'function bridgeFeeBps() view returns (uint16)',\n 'function integratorTaoTopUp(uint256 taoAmount,uint16 bps) pure returns (uint256)',\n 'function quoteBridgeOut(uint64 destSelector,address token,address recipient,uint256 mintedAmount) view returns (uint256 fee)',\n 'function bridgeOut(uint64 destSelector,address token,address recipient,uint256 taoAmount,uint256 stakedAlphaRao,uint256 minTokenOut) payable returns (bytes32 messageId)',\n 'function integratorCut(uint256 amount,uint16 bps) pure returns (uint256)',\n 'function quoteBridgeOutWithFee(uint64 destSelector,address token,address recipient,uint256 mintedAmount,uint256 taoAmount,uint256 stakedAlphaRao,(address recipient,uint16 bps) integrator) view returns (uint256 fee,uint256 nativeTopUp,uint256 alphaTopUp,uint256 amountCrossing)',\n 'function bridgeOutWithFee(uint64 destSelector,address token,address recipient,uint256 taoAmount,uint256 stakedAlphaRao,uint256 minTokenOut,(address recipient,uint16 bps) integrator) payable returns (bytes32 messageId)',\n 'function bridgeOutFromValidators(uint64 destSelector,address token,address recipient,uint256 taoAmount,(bytes32 validator,uint256 alphaRao)[] sources,uint256 minTokenOut) payable returns (bytes32 messageId)',\n 'function bridgeOutFromValidatorsWithFee(uint64 destSelector,address token,address recipient,uint256 taoAmount,(bytes32 validator,uint256 alphaRao)[] sources,uint256 minTokenOut,(address recipient,uint16 bps) integrator) payable returns (bytes32 messageId)',\n 'function MAX_STAKE_SOURCES() view returns (uint256)',\n 'function GATEWAY_COLDKEY() view returns (bytes32)',\n 'function claimLiquid(address token,uint256 minTaoOut,address to)',\n 'function claimNative(address to)',\n 'function claimStaked(address token,bytes32 destColdkey,address to)',\n 'function claimToken(address token,address to)',\n 'function claimableNative(address account) view returns (uint256)',\n 'function claimableToken(address token,address account) view returns (uint256)',\n 'event BridgedOut(uint64 destChainSelector,address indexed token,address indexed sender,address indexed recipient,uint256 minted,bytes32 messageId)',\n 'event Claimable(address indexed token,address indexed user,uint256 native,uint256 wsn)',\n 'event NotDelivered(uint64 indexed sourceChainSelector,address indexed token,uint256 amount,uint8 reason)',\n 'event DeliveredLiquid(address indexed token,bytes32 indexed ss58,uint256 taoOut)',\n 'event DeliveredStaked(address indexed token,bytes32 indexed ss58,uint256 alphaRao)',\n] as const)\n\nexport const ALPHA_VAULT_ABI = Object.freeze([\n 'function isPaused() view returns (bool)',\n 'function pausedUntil() view returns (uint256)',\n 'function isListed(address token) view returns (bool)',\n 'function backing(address token) view returns (uint256 stakedAlpha)',\n 'function positionOf(address token) view returns (bytes32 validator,uint256 netuid)',\n] as const)\n\nexport const VAULT_FACTORY_ABI = Object.freeze([\n 'function create(address owner,bytes32 associatedMiner,address akAddress,address poolManager,address poolAddress,address positionManagerImpl,(address token,uint256 amount)[] stashTokens) payable returns (address manager)',\n 'event SnLiquidityManagerCreated(address indexed manager,address indexed owner,bytes32 associatedMiner,address akAddress,address poolAddress,address poolManager,address positionManager)',\n] as const)\n\nexport const VAULT_MANAGER_ABI = Object.freeze([\n 'function claimFees(address akAddress)',\n 'function topUpAk(address akAddress,address token,uint256 amount) payable',\n 'function withdrawFromAkAndPositions(address akAddress,uint256 amount0,uint256 amount1,uint256[] decreaseTokenIds,bool unwrapETH)',\n 'function stake(address akAddress,bytes data)',\n 'function unstake(address akAddress,bytes data)',\n 'function owner() view returns (address)',\n 'event AKStashTopUp(address akAddress,address token,uint256 amount)',\n 'event AKStashWithdraw(address akAddress,address token,uint256 amount)',\n] as const)\n\nexport const CCIP_EXECUTION_ABI = Object.freeze([\n 'event ExecutionStateChanged(uint64 indexed sourceChainSelector,uint64 indexed sequenceNumber,bytes32 indexed messageId,bytes32 messageHash,uint8 state,bytes returnData,uint256 gasUsed)',\n] as const)\n\nexport const CCIP_ROUTER_ABI = Object.freeze([\n 'function isOffRamp(uint64 sourceChainSelector,address offRamp) view returns (bool)',\n] as const)\n\nexport const foreverMoneyAbis = Object.freeze({\n alphaGateway: ALPHA_GATEWAY_ABI,\n alphaVault: ALPHA_VAULT_ABI,\n ccipExecution: CCIP_EXECUTION_ABI,\n ccipRouter: CCIP_ROUTER_ABI,\n erc20: ERC20_ABI,\n spokeGateway: SPOKE_GATEWAY_ABI,\n staking: STAKING_ABI,\n vaultFactory: VAULT_FACTORY_ABI,\n vaultManager: VAULT_MANAGER_ABI,\n})\n","import {\n estimateRoundedStake,\n type StakeRoundingOptions,\n type StakeRoundingResult,\n} from './stake-rounding.js'\nimport { encodeFunctionData, parseAbi, type PublicClient } from 'viem'\nimport {\n ALPHA_GATEWAY_ABI,\n ERC20_ABI,\n SPOKE_GATEWAY_ABI,\n STAKING_ABI,\n} from '../abis/index.js'\nimport {\n normalizeEvmAddress,\n normalizeSS58,\n ss58ToPublicKey,\n} from '../core/addresses.js'\nimport {\n assertWholeRao,\n feeWithBuffer,\n gasLimitWithBuffer,\n} from '../core/amounts.js'\nimport {\n EVM_WEI_PER_RAO,\n SN80_NETUID,\n foreverMoneyDeployment,\n getForeverMoneyEvmDeployment,\n type ForeverMoneyEvmChain,\n} from '../chains/deployment.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport {\n createTransactionPlan,\n type TransactionPlan,\n type TransactionStep,\n} from '../core/plans.js'\nimport {\n assertNonNegativeAmount,\n normalizeBytes32,\n} from '../core/validation.js'\nconst erc20Abi = parseAbi(ERC20_ABI)\nconst spokeAbi = parseAbi(SPOKE_GATEWAY_ABI)\nconst alphaAbi = parseAbi(ALPHA_GATEWAY_ABI)\nconst stakingAbi = parseAbi(STAKING_ABI)\nexport const MIN_LIQUID_EVM_TO_SUBTENSOR_WEI = 10000000000000000n\nexport const MIN_LIQUID_BASE_TO_SUBTENSOR_WEI = MIN_LIQUID_EVM_TO_SUBTENSOR_WEI\n// Subtensor's minimum new stake is 2,000,000 RAO (0.002 TAO).\nexport const MIN_LIQUID_SUBTENSOR_TO_EVM_WEI = 2_000_000n * EVM_WEI_PER_RAO\n// The spoke contracts' original 300k default can no longer cover the variable\n// cost of a liquid AlphaVault exit on Subtensor. The live claim path currently\n// estimates near 2.56m; keep headroom so normal CCIP execution does not fall\n// back to a manual retry when the staking path becomes more expensive.\nexport const EVM_TO_SUBTENSOR_DESTINATION_GAS_LIMIT = 3_500_000n\nfunction resolveDestinationGasLimit(value?: bigint): bigint {\n const gasLimit = value ?? EVM_TO_SUBTENSOR_DESTINATION_GAS_LIMIT\n if (typeof gasLimit !== 'bigint' || gasLimit <= 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Destination gas limit must be a positive bigint.',\n { destinationGasLimit: String(gasLimit) }\n )\n }\n return gasLimit\n}\nexport type SubtensorDelivery = 'liquid' | 'staked'\nexport type SubtensorSource = 'liquid' | 'staked'\nexport type BridgeAsset = 'tao' | 'sn80'\n/**\n * Optional partner (integrator) fee, charged ON TOP of the bridged amount and\n * paid to `recipient` on the source chain. The full `amountWei` still crosses.\n * `bps` is in basis points (1 = 0.01%); the gateway caps it at\n * `maxIntegratorFeeBps`, which `prepare*` reads and enforces.\n */\nexport interface PartnerFee {\n readonly recipient: string\n readonly bps: number\n}\nexport const MAX_PARTNER_FEE_BPS = 10_000\n/**\n * One staked position to pull from when bridging staked alpha from Subtensor:\n * the validator hotkey the caller's stake sits on and how much of it to take.\n * The gateway re-delegates every pull to the token's canonical validator\n * before depositing, so stake with any validator can be bridged.\n */\nexport interface StakePull {\n readonly hotkey: string\n readonly amountRao: bigint\n}\n/** Gateway limit on positions per bridge (`AlphaGateway.MAX_STAKE_SOURCES`). */\nexport const MAX_STAKE_PULLS = 16\nexport interface EvmToSubtensorRequest {\n readonly evmChain: ForeverMoneyEvmChain\n readonly asset?: BridgeAsset\n readonly partnerFee?: PartnerFee\n /**\n * CCIP gas made available to the Subtensor receiver. Defaults to\n * `EVM_TO_SUBTENSOR_DESTINATION_GAS_LIMIT`; set per transaction when the\n * destination execution path needs a different budget.\n */\n readonly destinationGasLimit?: bigint\n readonly sender: string\n readonly amountWei: bigint\n readonly destination: string\n readonly delivery: SubtensorDelivery\n}\nexport interface SubtensorToEvmRequest {\n /** Opt-in read-only amount adjustment. False/omitted preserves exact input.\n * Requires named stakePulls and current balances; minAmountOutWei is never lowered.\n * Preparation may return an approval first; prepare again after it confirms.\n */\n readonly stakeRounding?: false | StakeRoundingOptions\n /** Minimum destination-token output in 18-decimal wei, after partner fees.\n * Defaults to amountWei. Must be positive and no greater than amountWei.\n * Callers choose their tolerance explicitly, including staking rounding dust.\n */\n readonly minAmountOutWei?: bigint\n readonly evmChain: ForeverMoneyEvmChain\n readonly asset?: BridgeAsset\n readonly partnerFee?: PartnerFee\n readonly sender: string\n readonly recipient: string\n readonly amountWei: bigint\n readonly source: SubtensorSource\n readonly netuid?: bigint\n /**\n * For a staked source: the positions to pull, summing to `amountWei` in\n * RAO. Omit when the stake already sits on the token's canonical validator.\n * With a partner fee, the cut is charged on top and spread across the pulls\n * in proportion to their amounts, so each position must hold its amount\n * plus its share of the cut.\n */\n readonly stakePulls?: readonly StakePull[]\n}\nexport type BaseToSubtensorRequest = Omit<EvmToSubtensorRequest, 'evmChain'>\nexport type SubtensorToBaseRequest = Omit<SubtensorToEvmRequest, 'evmChain'>\nexport interface BridgePreparation {\n /** Present when rounding was enabled. Display the returned amount and use its plan. */\n readonly stakeRounding?: StakeRoundingResult\n readonly exactNetworkFeeWei: bigint\n readonly transactionValueWei: bigint\n /**\n * Extra the sender pays for the partner fee, in the units of the source leg:\n * token wei for an EVM source, alpha (as 18-decimal wei) for a staked source,\n * TAO wei for a liquid source. Zero when no partner fee is set.\n */\n readonly partnerFeeWei: bigint\n readonly plan: TransactionPlan\n}\ninterface ResolvedPartnerFee {\n readonly recipient: `0x${string}`\n readonly bps: number\n}\nconst NO_PARTNER_FEE: ResolvedPartnerFee = {\n recipient: '0x0000000000000000000000000000000000000000',\n bps: 0,\n}\nfunction resolvePartnerFee(\n fee: PartnerFee | undefined,\n gateway: `0x${string}`\n): ResolvedPartnerFee {\n if (fee === undefined) return NO_PARTNER_FEE\n if (\n typeof fee.bps !== 'number' ||\n !Number.isInteger(fee.bps) ||\n fee.bps < 0 ||\n fee.bps > MAX_PARTNER_FEE_BPS\n ) {\n throw new ForeverMoneyError(\n 'INVALID_PARTNER_FEE',\n `Partner fee bps must be an integer between 0 and ${MAX_PARTNER_FEE_BPS}.`,\n { bps: fee.bps }\n )\n }\n if (fee.bps === 0) return NO_PARTNER_FEE\n const recipient = normalizeEvmAddress(fee.recipient)\n if (\n recipient === NO_PARTNER_FEE.recipient ||\n recipient.toLowerCase() === gateway.toLowerCase()\n ) {\n throw new ForeverMoneyError(\n 'INVALID_PARTNER_FEE',\n 'Partner fee recipient must not be the zero address or the gateway.',\n { recipient }\n )\n }\n return { recipient, bps: fee.bps }\n}\n/** `bps` of `amount`, rounded down: the extra token (spoke) or alpha (hub) pulled on top. */\nexport function partnerFeeCut(amount: bigint, bps: number): bigint {\n return (amount * BigInt(bps)) / 10_000n\n}\n/** Extra native TAO a liquid Subtensor source carries for the partner, rounded up to a whole RAO. */\nexport function partnerFeeTaoTopUp(taoAmount: bigint, bps: number): bigint {\n const raw = partnerFeeCut(taoAmount, bps)\n if (raw === 0n) return 0n\n return ((raw + EVM_WEI_PER_RAO - 1n) / EVM_WEI_PER_RAO) * EVM_WEI_PER_RAO\n}\nfunction assertPartnerFeeAllowed(fee: ResolvedPartnerFee, maxBps: number) {\n if (fee.bps > maxBps) {\n throw new ForeverMoneyError(\n 'INVALID_PARTNER_FEE',\n `Partner fee of ${fee.bps} bps exceeds the gateway maximum of ${maxBps} bps.`,\n { bps: fee.bps, maxBps }\n )\n }\n}\nfunction bridgeAsset(\n evmChain: ForeverMoneyEvmChain,\n asset: BridgeAsset = 'tao'\n) {\n if (asset !== 'tao' && asset !== 'sn80') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Asset must be \"tao\" or \"sn80\".'\n )\n }\n if (asset === 'sn80' && evmChain !== 'base') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'SN80 bridging is supported between Base and Subtensor.'\n )\n }\n const evm = getForeverMoneyEvmDeployment(evmChain)\n return asset === 'sn80'\n ? {\n evmToken: foreverMoneyDeployment.base.contracts.wrappedSn80,\n subtensorToken:\n foreverMoneyDeployment.subtensor.contracts.wrappedSn80,\n label: 'SN80',\n wrappedLabel: 'SN80',\n }\n : {\n evmToken: evm.contracts.wrappedTao,\n subtensorToken:\n foreverMoneyDeployment.subtensor.contracts.wrappedTao,\n label: 'TAO',\n wrappedLabel: 'wrapped TAO',\n }\n}\nfunction assertAssetMode(\n asset: BridgeAsset | undefined,\n mode: SubtensorSource\n): void {\n if (asset === 'sn80' && mode !== 'staked') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'SN80 bridging requires staked subnet 80 input or delivery; liquid TAO conversion is not supported.'\n )\n }\n}\nfunction sourceNetuid(input: SubtensorToEvmRequest): bigint | undefined {\n if (input.source !== 'staked') return undefined\n const netuid =\n input.netuid ?? (input.asset === 'sn80' ? SN80_NETUID : undefined)\n if (netuid === undefined) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'A netuid is required when bridging staked TAO.'\n )\n }\n assertNonNegativeAmount(netuid, 'netuid')\n if (input.asset === 'sn80' && netuid !== SN80_NETUID) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'SN80 staking approvals must use netuid 80.'\n )\n }\n return netuid\n}\n/** Resolved pulls for a staked source that names them; undefined otherwise. */\nfunction stakePullsFor(\n input: SubtensorToEvmRequest,\n amountRao: bigint\n): ResolvedStakePull[] | undefined {\n if (input.stakePulls === undefined) return undefined\n if (input.source !== 'staked') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake pulls are only valid for a staked source.'\n )\n }\n return resolveStakePulls(input.stakePulls, amountRao)\n}\nfunction minimumSubtensorOutput(input: SubtensorToEvmRequest): bigint {\n const minimum = input.minAmountOutWei ?? input.amountWei\n assertNonNegativeAmount(minimum, 'Minimum output')\n if (minimum === 0n || minimum > input.amountWei) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Minimum output must be positive and no greater than the input amount.'\n )\n }\n return minimum\n}\nfunction assertDelivery(value: unknown): asserts value is SubtensorDelivery {\n if (value !== 'liquid' && value !== 'staked') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Delivery must be \"liquid\" or \"staked\".'\n )\n }\n}\nfunction assertSource(value: unknown): asserts value is SubtensorSource {\n if (value !== 'liquid' && value !== 'staked') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Source must be \"liquid\" or \"staked\".'\n )\n }\n}\nfunction assertBaseToSubtensorAmount(\n amountWei: bigint,\n delivery: SubtensorDelivery\n): void {\n assertWholeRao(amountWei)\n if (delivery === 'liquid' && amountWei < MIN_LIQUID_EVM_TO_SUBTENSOR_WEI) {\n throw new ForeverMoneyError(\n 'AMOUNT_BELOW_MINIMUM',\n 'Liquid delivery from an EVM chain to Subtensor requires at least 0.01 TAO.',\n {\n amountWei: amountWei.toString(),\n minimumAmountWei: MIN_LIQUID_EVM_TO_SUBTENSOR_WEI.toString(),\n }\n )\n }\n}\nfunction assertSubtensorToEvmAmount(\n amountWei: bigint,\n source: SubtensorSource\n): void {\n assertWholeRao(amountWei)\n if (source === 'liquid' && amountWei < MIN_LIQUID_SUBTENSOR_TO_EVM_WEI) {\n throw new ForeverMoneyError(\n 'AMOUNT_BELOW_MINIMUM',\n 'Bridging liquid TAO from Subtensor requires at least 0.002 TAO.',\n {\n amountWei: amountWei.toString(),\n minimumAmountWei: MIN_LIQUID_SUBTENSOR_TO_EVM_WEI.toString(),\n }\n )\n }\n}\nexport interface BuildEvmToSubtensorPlanRequest extends EvmToSubtensorRequest {\n readonly allowanceWei: bigint\n readonly exactNetworkFeeWei: bigint\n readonly estimatedBridgeGas?: bigint\n}\nexport interface BuildSubtensorToEvmPlanRequest extends SubtensorToEvmRequest {\n readonly stakingAllowanceRao?: bigint\n readonly exactNetworkFeeWei: bigint\n readonly estimatedBridgeGas?: bigint\n}\nexport type BuildBaseToSubtensorPlanRequest = Omit<\n BuildEvmToSubtensorPlanRequest,\n 'evmChain'\n>\nexport type BuildSubtensorToBasePlanRequest = Omit<\n BuildSubtensorToEvmPlanRequest,\n 'evmChain'\n>\nfunction transactionStep(\n kind: TransactionStep['kind'],\n label: string,\n chainId: number,\n from: string,\n to: string,\n data: string,\n value: bigint,\n gasLimit?: bigint\n): TransactionStep {\n return {\n kind,\n label,\n transaction: {\n chainId,\n from,\n to,\n data,\n value: value.toString(),\n ...(gasLimit === undefined\n ? {}\n : { gasLimit: gasLimit.toString() }),\n },\n }\n}\ntype ExitParams = {\n ss58: `0x${string}`\n evmFallback: `0x${string}`\n wantLiquid: boolean\n minTaoOut: bigint\n}\nfunction partnerFeeSummary(\n charged: bigint,\n unit: string,\n fee: ResolvedPartnerFee\n): string {\n if (fee.bps === 0) return ''\n return ` Partner fee: ${charged} wei of ${unit} (${fee.bps} bps) on top, paid to ${fee.recipient}.`\n}\nfunction encodeSpokeBridge(\n token: `0x${string}`,\n amountWei: bigint,\n exit: ExitParams,\n destinationGasLimit: bigint,\n fee: ResolvedPartnerFee\n): `0x${string}` {\n return fee.bps === 0\n ? encodeFunctionData({\n abi: spokeAbi,\n functionName: 'bridgeToFinney',\n args: [token, amountWei, exit, destinationGasLimit],\n })\n : encodeFunctionData({\n abi: spokeAbi,\n functionName: 'bridgeToFinneyWithFee',\n args: [token, amountWei, exit, destinationGasLimit, fee],\n })\n}\ntype ResolvedStakePull = { validator: `0x${string}`; alphaRao: bigint }\n/**\n * Validate the caller's pull list against the gateway's rules: 1..16 entries,\n * unique bytes32 hotkeys, positive amounts, summing to the bridged alpha.\n */\nfunction resolveStakePulls(\n pulls: readonly StakePull[],\n amountRao: bigint\n): ResolvedStakePull[] {\n if (pulls.length === 0 || pulls.length > MAX_STAKE_PULLS) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Between 1 and ${MAX_STAKE_PULLS} stake pulls are required.`,\n { count: pulls.length }\n )\n }\n const seen = new Set<string>()\n let total = 0n\n const resolved = pulls.map((pull) => {\n const validator = normalizeBytes32(pull.hotkey, 'Stake pull hotkey')\n if (validator === `0x${'0'.repeat(64)}`) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake pull hotkey must not be zero.'\n )\n }\n const key = validator.toLowerCase()\n if (seen.has(key)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake pulls must not repeat a hotkey.',\n { hotkey: validator }\n )\n }\n seen.add(key)\n if (typeof pull.amountRao !== 'bigint' || pull.amountRao <= 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Each stake pull must take a positive amount of RAO.',\n { hotkey: validator }\n )\n }\n total += pull.amountRao\n return { validator, alphaRao: pull.amountRao }\n })\n if (total !== amountRao) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake pulls must sum to the bridged amount.',\n { pulledRao: total.toString(), amountRao: amountRao.toString() }\n )\n }\n return resolved\n}\nfunction encodeHubBridge(\n destSelector: bigint,\n token: `0x${string}`,\n recipient: `0x${string}`,\n taoAmount: bigint,\n stakedAlphaRao: bigint,\n minTokenOut: bigint,\n fee: ResolvedPartnerFee,\n pulls?: ResolvedStakePull[]\n): `0x${string}` {\n if (pulls !== undefined) {\n const args = [\n destSelector,\n token,\n recipient,\n taoAmount,\n pulls,\n minTokenOut,\n ] as const\n return fee.bps === 0\n ? encodeFunctionData({\n abi: alphaAbi,\n functionName: 'bridgeOutFromValidators',\n args,\n })\n : encodeFunctionData({\n abi: alphaAbi,\n functionName: 'bridgeOutFromValidatorsWithFee',\n args: [...args, fee],\n })\n }\n const args = [\n destSelector,\n token,\n recipient,\n taoAmount,\n stakedAlphaRao,\n minTokenOut,\n ] as const\n return fee.bps === 0\n ? encodeFunctionData({\n abi: alphaAbi,\n functionName: 'bridgeOut',\n args,\n })\n : encodeFunctionData({\n abi: alphaAbi,\n functionName: 'bridgeOutWithFee',\n args: [...args, fee],\n })\n}\nasync function quoteSpokeWithFee(\n provider: PublicClient,\n gateway: `0x${string}`,\n token: `0x${string}`,\n amountWei: bigint,\n exit: ExitParams,\n destinationGasLimit: bigint,\n fee: ResolvedPartnerFee\n): Promise<bigint> {\n const maxBps = await provider.readContract({\n address: gateway,\n abi: spokeAbi,\n functionName: 'maxIntegratorFeeBps',\n })\n assertPartnerFeeAllowed(fee, maxBps)\n const [networkFee] = await provider.readContract({\n address: gateway,\n abi: spokeAbi,\n functionName: 'quoteBridgeToFinneyWithFee',\n args: [token, amountWei, exit, destinationGasLimit, fee],\n })\n return networkFee\n}\nasync function quoteHubWithFee(\n provider: PublicClient,\n gateway: `0x${string}`,\n destSelector: bigint,\n token: `0x${string}`,\n recipient: `0x${string}`,\n mintedAmount: bigint,\n taoAmount: bigint,\n stakedAlphaRao: bigint,\n fee: ResolvedPartnerFee\n): Promise<{\n networkFee: bigint\n taoTopUp: bigint\n alphaTopUpRao: bigint\n}> {\n const maxBps = await provider.readContract({\n address: gateway,\n abi: alphaAbi,\n functionName: 'maxIntegratorFeeBps',\n })\n assertPartnerFeeAllowed(fee, maxBps)\n const [networkFee, taoTopUp, alphaTopUpRao, crossing] =\n await provider.readContract({\n address: gateway,\n abi: alphaAbi,\n functionName: 'quoteBridgeOutWithFee',\n args: [\n destSelector,\n token,\n recipient,\n mintedAmount,\n taoAmount,\n stakedAlphaRao,\n fee,\n ],\n })\n // The gateway computes the same top-ups the plan builder does; a mismatch\n // means the deployed contract differs from the ABI the SDK was built for.\n if (\n crossing !== mintedAmount ||\n taoTopUp !== partnerFeeTaoTopUp(taoAmount, fee.bps) ||\n alphaTopUpRao !== partnerFeeCut(stakedAlphaRao, fee.bps)\n ) {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'The gateway partner fee quote does not match the SDK fee calculation.',\n {\n crossing: crossing.toString(),\n taoTopUp: taoTopUp.toString(),\n alphaTopUpRao: alphaTopUpRao.toString(),\n }\n )\n }\n return { networkFee, taoTopUp, alphaTopUpRao }\n}\nexport function buildEvmToSubtensorPlan(\n input: BuildEvmToSubtensorPlanRequest\n): TransactionPlan {\n const sender = normalizeEvmAddress(input.sender)\n const asset = bridgeAsset(input.evmChain, input.asset)\n assertDelivery(input.delivery)\n assertAssetMode(input.asset, input.delivery)\n assertBaseToSubtensorAmount(input.amountWei, input.delivery)\n assertNonNegativeAmount(input.allowanceWei, 'Token allowance')\n assertNonNegativeAmount(input.exactNetworkFeeWei, 'Network fee')\n const destinationGasLimit = resolveDestinationGasLimit(\n input.destinationGasLimit\n )\n const destination = normalizeSS58(input.destination)\n const exit = {\n ss58: ss58ToPublicKey(destination),\n evmFallback: sender,\n wantLiquid: input.delivery === 'liquid',\n minTaoOut: input.amountWei,\n }\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const partnerFee = resolvePartnerFee(\n input.partnerFee,\n evm.contracts.gateway\n )\n const cut = partnerFeeCut(input.amountWei, partnerFee.bps)\n const steps: TransactionStep[] = []\n if (input.allowanceWei < input.amountWei + cut) {\n steps.push(\n transactionStep(\n 'approval',\n `Approve ${asset.wrappedLabel} for the ForeverMoney gateway`,\n evm.chainId,\n sender,\n asset.evmToken,\n encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [evm.contracts.gateway, input.amountWei + cut],\n }),\n 0n\n )\n )\n }\n const value = feeWithBuffer(input.exactNetworkFeeWei)\n steps.push(\n transactionStep(\n 'transaction',\n `Bridge ${asset.wrappedLabel} from ${evm.name} to Subtensor (${input.delivery})`,\n evm.chainId,\n sender,\n evm.contracts.gateway,\n encodeSpokeBridge(\n asset.evmToken,\n input.amountWei,\n exit,\n destinationGasLimit,\n partnerFee\n ),\n value,\n input.estimatedBridgeGas === undefined\n ? undefined\n : gasLimitWithBuffer(input.estimatedBridgeGas)\n )\n )\n return createTransactionPlan({\n action:\n evm.key === 'base'\n ? 'bridge.base-to-subtensor'\n : 'bridge.robinhood-to-subtensor',\n summary: `Bridge ${input.amountWei} wei of ${asset.wrappedLabel} from ${evm.name} to ${destination}.${partnerFeeSummary(cut, asset.wrappedLabel, partnerFee)}`,\n steps,\n })\n}\nexport function buildBaseToSubtensorPlan(\n input: BuildBaseToSubtensorPlanRequest\n): TransactionPlan {\n return buildEvmToSubtensorPlan({ ...input, evmChain: 'base' })\n}\nexport function buildSubtensorToEvmPlan(\n input: BuildSubtensorToEvmPlanRequest\n): TransactionPlan {\n const sender = normalizeEvmAddress(input.sender)\n const recipient = normalizeEvmAddress(input.recipient)\n const asset = bridgeAsset(input.evmChain, input.asset)\n assertSource(input.source)\n assertAssetMode(input.asset, input.source)\n const netuid = sourceNetuid(input)\n assertSubtensorToEvmAmount(input.amountWei, input.source)\n const minAmountOutWei = minimumSubtensorOutput(input)\n assertNonNegativeAmount(input.exactNetworkFeeWei, 'Network fee')\n const { subtensor } = foreverMoneyDeployment\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const partnerFee = resolvePartnerFee(\n input.partnerFee,\n subtensor.contracts.gateway\n )\n const amountRao = input.amountWei / EVM_WEI_PER_RAO\n // Charged on top: extra alpha for a staked source, extra TAO for a liquid one.\n const alphaTopUpRao =\n input.source === 'staked'\n ? partnerFeeCut(amountRao, partnerFee.bps)\n : 0n\n const taoTopUp =\n input.source === 'liquid'\n ? partnerFeeTaoTopUp(input.amountWei, partnerFee.bps)\n : 0n\n const steps: TransactionStep[] = []\n if (input.source === 'staked') {\n if (input.stakingAllowanceRao === undefined) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The staking allowance is required when bridging staked TAO.'\n )\n }\n assertNonNegativeAmount(input.stakingAllowanceRao, 'Staking allowance')\n if (input.stakingAllowanceRao < amountRao + alphaTopUpRao) {\n steps.push(\n transactionStep(\n 'approval',\n `Approve staked ${asset.label} for the ForeverMoney gateway`,\n subtensor.chainId,\n sender,\n subtensor.contracts.stakingPrecompile,\n encodeFunctionData({\n abi: stakingAbi,\n functionName: 'approve',\n args: [\n subtensor.contracts.gateway,\n netuid!,\n amountRao + alphaTopUpRao,\n ],\n }),\n 0n\n )\n )\n }\n } else if (\n input.netuid !== undefined ||\n input.stakingAllowanceRao !== undefined\n ) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'netuid and staking allowance are only valid for staked TAO.'\n )\n }\n const taoAmount = input.source === 'liquid' ? input.amountWei : 0n\n const stakedAlphaRao = input.source === 'staked' ? amountRao : 0n\n const pulls = stakePullsFor(input, amountRao)\n const value = taoAmount + taoTopUp + feeWithBuffer(input.exactNetworkFeeWei)\n assertNonNegativeAmount(value, 'Transaction value')\n steps.push(\n transactionStep(\n 'transaction',\n `Bridge ${input.source} ${asset.label} from Subtensor to ${evm.name}`,\n subtensor.chainId,\n sender,\n subtensor.contracts.gateway,\n encodeHubBridge(\n evm.ccipSelector,\n asset.subtensorToken,\n recipient,\n taoAmount,\n stakedAlphaRao,\n minAmountOutWei,\n partnerFee,\n pulls\n ),\n value,\n input.estimatedBridgeGas === undefined\n ? undefined\n : gasLimitWithBuffer(input.estimatedBridgeGas)\n )\n )\n return createTransactionPlan({\n action:\n evm.key === 'base'\n ? 'bridge.subtensor-to-base'\n : 'bridge.subtensor-to-robinhood',\n summary: `Bridge ${input.amountWei} wei of ${input.source} ${asset.label} from Subtensor to ${recipient} on ${evm.name}.${partnerFeeSummary(\n input.source === 'liquid'\n ? taoTopUp\n : alphaTopUpRao * EVM_WEI_PER_RAO,\n input.source === 'liquid' ? 'TAO' : `staked ${asset.label}`,\n partnerFee\n )}`,\n steps,\n })\n}\nexport function buildSubtensorToBasePlan(\n input: BuildSubtensorToBasePlanRequest\n): TransactionPlan {\n return buildSubtensorToEvmPlan({ ...input, evmChain: 'base' })\n}\nexport async function prepareEvmToSubtensor(\n provider: PublicClient,\n input: EvmToSubtensorRequest\n): Promise<BridgePreparation> {\n const sender = normalizeEvmAddress(input.sender)\n const asset = bridgeAsset(input.evmChain, input.asset)\n assertDelivery(input.delivery)\n assertAssetMode(input.asset, input.delivery)\n assertBaseToSubtensorAmount(input.amountWei, input.delivery)\n const destinationGasLimit = resolveDestinationGasLimit(\n input.destinationGasLimit\n )\n const destination = normalizeSS58(input.destination)\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const exit = {\n ss58: ss58ToPublicKey(destination),\n evmFallback: sender,\n wantLiquid: input.delivery === 'liquid',\n minTaoOut: input.amountWei,\n }\n const partnerFee = resolvePartnerFee(\n input.partnerFee,\n evm.contracts.gateway\n )\n const cut = partnerFeeCut(input.amountWei, partnerFee.bps)\n const [allowanceWei, exactNetworkFeeWei] = await Promise.all([\n provider.readContract({\n address: asset.evmToken,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [sender, evm.contracts.gateway],\n }),\n partnerFee.bps === 0\n ? provider.readContract({\n address: evm.contracts.gateway,\n abi: spokeAbi,\n functionName: 'quoteBridgeToFinney',\n args: [\n asset.evmToken,\n input.amountWei,\n exit,\n destinationGasLimit,\n ],\n })\n : quoteSpokeWithFee(\n provider,\n evm.contracts.gateway,\n asset.evmToken,\n input.amountWei,\n exit,\n destinationGasLimit,\n partnerFee\n ),\n ])\n let estimatedBridgeGas: bigint | undefined\n if (allowanceWei >= input.amountWei + cut) {\n const data = encodeSpokeBridge(\n asset.evmToken,\n input.amountWei,\n exit,\n destinationGasLimit,\n partnerFee\n )\n estimatedBridgeGas = await provider.estimateGas({\n account: sender,\n to: evm.contracts.gateway,\n data,\n value: feeWithBuffer(exactNetworkFeeWei),\n })\n }\n const plan = buildEvmToSubtensorPlan({\n ...input,\n allowanceWei,\n exactNetworkFeeWei,\n ...(estimatedBridgeGas === undefined ? {} : { estimatedBridgeGas }),\n })\n return Object.freeze({\n exactNetworkFeeWei,\n transactionValueWei: feeWithBuffer(exactNetworkFeeWei),\n partnerFeeWei: cut,\n plan,\n })\n}\nexport function prepareBaseToSubtensor(\n provider: PublicClient,\n input: BaseToSubtensorRequest\n): Promise<BridgePreparation> {\n return prepareEvmToSubtensor(provider, { ...input, evmChain: 'base' })\n}\nasync function prepareSubtensorToEvmExact(\n provider: PublicClient,\n input: SubtensorToEvmRequest\n): Promise<BridgePreparation> {\n const sender = normalizeEvmAddress(input.sender)\n const recipient = normalizeEvmAddress(input.recipient)\n const asset = bridgeAsset(input.evmChain, input.asset)\n assertSource(input.source)\n assertAssetMode(input.asset, input.source)\n const netuid = sourceNetuid(input)\n assertSubtensorToEvmAmount(input.amountWei, input.source)\n const minAmountOutWei = minimumSubtensorOutput(input)\n const { subtensor } = foreverMoneyDeployment\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const partnerFee = resolvePartnerFee(\n input.partnerFee,\n subtensor.contracts.gateway\n )\n const taoAmount = input.source === 'liquid' ? input.amountWei : 0n\n const stakedAlphaRao =\n input.source === 'staked' ? input.amountWei / EVM_WEI_PER_RAO : 0n\n const exactNetworkFeeWei =\n partnerFee.bps === 0\n ? await provider.readContract({\n address: subtensor.contracts.gateway,\n abi: alphaAbi,\n functionName: 'quoteBridgeOut',\n args: [\n evm.ccipSelector,\n asset.subtensorToken,\n recipient,\n input.amountWei,\n ],\n })\n : (\n await quoteHubWithFee(\n provider,\n subtensor.contracts.gateway,\n evm.ccipSelector,\n asset.subtensorToken,\n recipient,\n input.amountWei,\n taoAmount,\n stakedAlphaRao,\n partnerFee\n )\n ).networkFee\n let stakingAllowanceRao: bigint | undefined\n if (input.source === 'staked') {\n stakingAllowanceRao = await provider.readContract({\n address: subtensor.contracts.stakingPrecompile,\n abi: stakingAbi,\n functionName: 'allowance',\n args: [sender, subtensor.contracts.gateway, netuid!],\n })\n }\n const alphaTopUpRao = partnerFeeCut(stakedAlphaRao, partnerFee.bps)\n const taoTopUp = partnerFeeTaoTopUp(taoAmount, partnerFee.bps)\n const value = taoAmount + taoTopUp + feeWithBuffer(exactNetworkFeeWei)\n assertNonNegativeAmount(value, 'Transaction value')\n let estimatedBridgeGas: bigint | undefined\n if (\n input.source === 'liquid' ||\n (stakingAllowanceRao !== undefined &&\n stakingAllowanceRao >= stakedAlphaRao + alphaTopUpRao)\n ) {\n estimatedBridgeGas = await provider.estimateGas({\n account: sender,\n to: subtensor.contracts.gateway,\n data: encodeHubBridge(\n evm.ccipSelector,\n asset.subtensorToken,\n recipient,\n taoAmount,\n stakedAlphaRao,\n minAmountOutWei,\n partnerFee,\n stakePullsFor(input, stakedAlphaRao)\n ),\n value,\n })\n }\n const plan = buildSubtensorToEvmPlan({\n ...input,\n exactNetworkFeeWei,\n ...(stakingAllowanceRao === undefined ? {} : { stakingAllowanceRao }),\n ...(estimatedBridgeGas === undefined ? {} : { estimatedBridgeGas }),\n })\n return Object.freeze({\n exactNetworkFeeWei,\n transactionValueWei: value,\n partnerFeeWei:\n input.source === 'liquid'\n ? taoTopUp\n : alphaTopUpRao * EVM_WEI_PER_RAO,\n plan,\n })\n}\n/** Prepare an exact or explicitly rounding-adjusted plan. No transactions are sent. */\nexport async function prepareSubtensorToEvm(\n provider: PublicClient,\n input: SubtensorToEvmRequest\n): Promise<BridgePreparation> {\n const options = input.stakeRounding\n if (\n options != null &&\n options !== false &&\n typeof options.enabled !== 'boolean'\n ) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'stakeRounding.enabled must be a boolean.'\n )\n }\n if (!options || !options.enabled)\n return prepareSubtensorToEvmExact(provider, input)\n if (input.source !== 'staked' || !input.stakePulls?.length) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake rounding requires a staked source with named stakePulls.'\n )\n }\n const minimum = minimumSubtensorOutput(input)\n const result = await estimateRoundedStake({\n amountWei: input.amountWei,\n minAmountOutWei: minimum,\n pulls: input.stakePulls,\n positions: options.positions,\n minStakeRao: options.minStakeRao ?? 0n,\n partnerFeeBps: input.partnerFee?.bps ?? 0,\n quoteAndEstimate: async (amountWei, stakePulls, minAmountOutWei) => ({\n prepared: await prepareSubtensorToEvmExact(provider, {\n ...input,\n amountWei,\n stakePulls,\n minAmountOutWei,\n stakeRounding: false,\n }),\n }),\n })\n return Object.freeze({\n ...result.prepared,\n stakeRounding: Object.freeze({\n requestedAmountWei: input.amountWei,\n amountWei: result.amountWei,\n minAmountOutWei: result.minAmountOutWei,\n pulls: result.pulls,\n simulationComplete: !result.prepared.plan.steps.some(\n (step) => step.kind === 'approval'\n ),\n }),\n })\n}\n\nexport function prepareSubtensorToBase(\n provider: PublicClient,\n input: SubtensorToBaseRequest\n): Promise<BridgePreparation> {\n return prepareSubtensorToEvm(provider, { ...input, evmChain: 'base' })\n}\n","import { keccak256, stringToBytes } from 'viem'\nimport { FOREVERMONEY_DEPLOYMENT_VERSION } from '../chains/deployment.js'\n\nexport type TransactionStepKind = 'approval' | 'transaction'\nexport type TransactionAction =\n | 'bridge.base-to-subtensor'\n | 'bridge.robinhood-to-subtensor'\n | 'bridge.subtensor-to-base'\n | 'bridge.subtensor-to-robinhood'\n | 'vault.claim-fees'\n | 'vault.create'\n | 'vault.deposit'\n | 'vault.stake'\n | 'vault.unstake'\n | 'vault.withdraw'\n\nexport interface PreparedTransaction {\n readonly chainId: number\n readonly from: string\n readonly to: string\n readonly data: string\n readonly value: string\n readonly gasLimit?: string\n}\n\nexport interface TransactionStep {\n readonly kind: TransactionStepKind\n readonly label: string\n readonly transaction: PreparedTransaction\n}\n\nexport interface TransactionPlan {\n readonly version: '1'\n readonly deploymentVersion: typeof FOREVERMONEY_DEPLOYMENT_VERSION\n readonly action: TransactionAction\n readonly summary: string\n readonly steps: readonly TransactionStep[]\n readonly hash: string\n}\n\ntype UnhashedPlan = Omit<\n TransactionPlan,\n 'deploymentVersion' | 'hash' | 'version'\n>\n\nexport function createTransactionPlan(plan: UnhashedPlan): TransactionPlan {\n const steps = plan.steps.map((step) =>\n Object.freeze({\n ...step,\n transaction: Object.freeze({ ...step.transaction }),\n })\n )\n const versionedPlan = {\n version: '1' as const,\n deploymentVersion: FOREVERMONEY_DEPLOYMENT_VERSION,\n action: plan.action,\n summary: plan.summary,\n steps: Object.freeze(steps),\n }\n return Object.freeze({\n ...versionedPlan,\n hash: keccak256(stringToBytes(JSON.stringify(versionedPlan))),\n })\n}\n","import { createPublicClient, custom, type PublicClient } from 'viem'\nimport { ForeverMoneyError } from './errors.js'\n\nexport interface RpcRequest {\n readonly method: string\n readonly params?: readonly unknown[] | Record<string, unknown>\n}\n\nexport interface RpcTransport {\n request(request: RpcRequest): Promise<unknown>\n}\n\nexport interface HttpTransportOptions {\n readonly timeoutMs?: number\n readonly fetch?: typeof globalThis.fetch\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction invalidJsonRpcResponse(): ForeverMoneyError {\n return new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC returned an invalid JSON-RPC response.'\n )\n}\n\nfunction isLoopback(endpoint: URL): boolean {\n return (\n endpoint.hostname === 'localhost' ||\n endpoint.hostname === '127.0.0.1' ||\n endpoint.hostname === '[::1]'\n )\n}\n\nfunction jsonRpcResult(body: unknown, expectedId: number): unknown {\n if (!isRecord(body) || body.jsonrpc !== '2.0' || body.id !== expectedId) {\n throw invalidJsonRpcResponse()\n }\n if (body.error !== undefined) {\n if (\n !isRecord(body.error) ||\n !Number.isInteger(body.error.code) ||\n typeof body.error.message !== 'string'\n ) {\n throw invalidJsonRpcResponse()\n }\n throw new ForeverMoneyError('RPC_ERROR', body.error.message, {\n rpcCode: body.error.code,\n ...(body.error.data === undefined\n ? {}\n : { rpcData: body.error.data }),\n })\n }\n if (!Object.prototype.hasOwnProperty.call(body, 'result')) {\n throw invalidJsonRpcResponse()\n }\n return body.result\n}\n\nexport function http(\n url: string,\n options: HttpTransportOptions = {}\n): RpcTransport {\n let endpoint: URL\n try {\n endpoint = new URL(url)\n } catch {\n throw new ForeverMoneyError('RPC_ERROR', 'RPC URL is invalid.')\n }\n if (endpoint.protocol !== 'https:' && endpoint.protocol !== 'http:') {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC URL must use HTTP or HTTPS.'\n )\n }\n if (endpoint.protocol === 'http:' && !isLoopback(endpoint)) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'Non-local RPC URLs must use HTTPS.'\n )\n }\n\n const timeoutMs = options.timeoutMs ?? 15_000\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC timeout must be a positive integer.'\n )\n }\n const fetchImplementation = options.fetch ?? globalThis.fetch\n if (typeof fetchImplementation !== 'function') {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'This runtime does not provide fetch. Pass an explicit fetch implementation.'\n )\n }\n\n let requestId = 0\n return Object.freeze({\n async request(request: RpcRequest): Promise<unknown> {\n if (\n !isRecord(request) ||\n typeof request.method !== 'string' ||\n request.method.length === 0\n ) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC method must be a non-empty string.'\n )\n }\n if (\n request.params !== undefined &&\n !Array.isArray(request.params) &&\n !isRecord(request.params)\n ) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC params must be an array or object.'\n )\n }\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n const id = ++requestId\n try {\n const response = await fetchImplementation(endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id,\n method: request.method,\n params: request.params ?? [],\n }),\n signal: controller.signal,\n })\n if (!response.ok) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n `RPC returned HTTP ${response.status}.`,\n { status: response.status }\n )\n }\n return jsonRpcResult(await response.json(), id)\n } catch (error) {\n if (error instanceof ForeverMoneyError) throw error\n const message =\n error instanceof Error && error.name === 'AbortError'\n ? `RPC request timed out after ${timeoutMs}ms.`\n : 'RPC request failed.'\n throw new ForeverMoneyError('RPC_ERROR', message)\n } finally {\n clearTimeout(timer)\n }\n },\n })\n}\n\nexport function providerFromTransport(transport: RpcTransport): PublicClient {\n if (!transport || typeof transport.request !== 'function') {\n throw new ForeverMoneyError(\n 'MISSING_TRANSPORT',\n 'An EIP-1193-compatible RPC transport is required.'\n )\n }\n return createPublicClient({\n transport: custom(transport, { retryCount: 0 }),\n cacheTime: 0,\n batch: { multicall: false },\n })\n}\n\n/** Minimal structural interface implemented by ethers JSON-RPC providers. */\nexport interface LegacyRpcProvider {\n send(method: string, params: unknown[]): Promise<unknown>\n}\n\nexport type TrackingProvider = PublicClient | LegacyRpcProvider\n\n/** Adapt legacy providers without importing ethers or changing their RPC endpoint. */\nexport function trackingClient(provider: TrackingProvider): PublicClient {\n if (\n provider &&\n 'getChainId' in provider &&\n typeof provider.getChainId === 'function'\n )\n return provider\n if (provider && 'send' in provider && typeof provider.send === 'function') {\n return providerFromTransport({\n request: ({ method, params }) => {\n if (params !== undefined && !Array.isArray(params))\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'Tracking RPC params must be an array.'\n )\n return provider.send(\n method,\n params === undefined\n ? []\n : [...(params as readonly unknown[])]\n )\n },\n })\n }\n throw new ForeverMoneyError(\n 'MISSING_TRANSPORT',\n 'A viem public client or JSON-RPC provider is required.'\n )\n}\n","import {\n BaseError,\n ContractFunctionRevertedError,\n ExecutionRevertedError,\n} from 'viem'\nimport { ForeverMoneyError } from './errors.js'\n\nfunction stringProperty(value: unknown, property: string): string | undefined {\n if (typeof value !== 'object' || value === null || !(property in value)) {\n return undefined\n }\n const entry = (value as Record<string, unknown>)[property]\n return typeof entry === 'string' ? entry : undefined\n}\n\nexport async function providerOperation<T>(\n operation: string,\n action: () => Promise<T>\n): Promise<T> {\n try {\n return await action()\n } catch (error) {\n if (error instanceof ForeverMoneyError) throw error\n const revert =\n error instanceof BaseError\n ? error.walk(\n (cause) =>\n cause instanceof ContractFunctionRevertedError ||\n cause instanceof ExecutionRevertedError\n )\n : undefined\n const viemRevert =\n revert instanceof ContractFunctionRevertedError ||\n revert instanceof ExecutionRevertedError\n const causeCode = viemRevert\n ? revert.name\n : stringProperty(error, 'code')\n const reason = viemRevert\n ? revert instanceof ContractFunctionRevertedError\n ? (revert.data?.errorName ?? revert.reason)\n : undefined\n : stringProperty(error, 'reason')\n const reverted = viemRevert || causeCode === 'CALL_EXCEPTION'\n throw new ForeverMoneyError(\n reverted ? 'SIMULATION_REVERTED' : 'RPC_ERROR',\n reverted ? `${operation} reverted.` : `${operation} failed.`,\n {\n ...(causeCode === undefined ? {} : { causeCode }),\n ...(reason === undefined ? {} : { reason }),\n }\n )\n }\n}\n","import {\n encodeFunctionData,\n parseAbi,\n zeroAddress,\n type Address,\n type PublicClient,\n} from 'viem'\nimport {\n ERC20_ABI,\n VAULT_FACTORY_ABI,\n VAULT_MANAGER_ABI,\n} from '../abis/index.js'\nimport { normalizeEvmAddress } from '../core/addresses.js'\nimport { foreverMoneyDeployment } from '../chains/deployment.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport {\n createTransactionPlan,\n type TransactionPlan,\n type TransactionStep,\n} from '../core/plans.js'\nimport {\n assertArray,\n assertBoolean,\n assertNonNegativeAmount,\n assertPositiveAmount,\n assertRecord,\n normalizeOptionalBytes32,\n} from '../core/validation.js'\nconst erc20Abi = parseAbi(ERC20_ABI)\nconst factoryAbi = parseAbi(VAULT_FACTORY_ABI)\nconst managerAbi = parseAbi(VAULT_MANAGER_ABI)\nexport interface VaultStashToken {\n readonly token: string\n readonly amount: bigint\n}\nexport interface CreateVaultRequest {\n readonly owner: string\n readonly associatedMiner?: string\n readonly akAddress: string\n readonly poolManager: string\n readonly poolAddress: string\n readonly positionManagerImplementation: string\n readonly stashTokens: readonly VaultStashToken[]\n}\nexport interface VaultTokenAllowance {\n readonly token: string\n readonly allowance: bigint\n}\nfunction step(\n kind: TransactionStep['kind'],\n label: string,\n from: string,\n to: string,\n data: string,\n value = 0n\n): TransactionStep {\n return {\n kind,\n label,\n transaction: {\n chainId: foreverMoneyDeployment.base.chainId,\n from,\n to,\n data,\n value: value.toString(),\n },\n }\n}\nfunction normalizeStashTokens(\n stashTokens: readonly VaultStashToken[]\n): readonly { readonly token: Address; readonly amount: bigint }[] {\n assertArray(stashTokens, 'Stash tokens')\n const seen = new Set<string>()\n return stashTokens.map((entry) => {\n assertRecord(entry, 'Stash token')\n if (typeof entry.token !== 'string') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stash token address must be a string.'\n )\n }\n const normalizedToken = normalizeEvmAddress(entry.token)\n assertPositiveAmount(entry.amount, 'Stash amount')\n const key = normalizedToken.toLowerCase()\n if (seen.has(key)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Duplicate stash token: ${normalizedToken}.`\n )\n }\n seen.add(key)\n return Object.freeze({\n token: normalizedToken,\n amount: entry.amount,\n })\n })\n}\nfunction allowanceMap(\n allowances: readonly VaultTokenAllowance[]\n): ReadonlyMap<string, bigint> {\n assertArray(allowances, 'Token allowances')\n const result = new Map<string, bigint>()\n for (const entry of allowances) {\n assertRecord(entry, 'Token allowance')\n if (typeof entry.token !== 'string') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Allowance token address must be a string.'\n )\n }\n const token = normalizeEvmAddress(entry.token).toLowerCase()\n assertNonNegativeAmount(entry.allowance, 'Token allowance')\n if (result.has(token)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Duplicate allowance for token ${entry.token}.`\n )\n }\n result.set(token, entry.allowance)\n }\n return result\n}\nfunction assertAllowanceSet(\n allowances: ReadonlyMap<string, bigint>,\n tokens: readonly VaultStashToken[]\n): void {\n const expected = new Set(\n tokens\n .filter(\n ({ token }) =>\n token !== foreverMoneyDeployment.base.contracts.weth\n )\n .map(({ token }) => token.toLowerCase())\n )\n for (const token of allowances.keys()) {\n if (!expected.has(token)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Unexpected allowance for token ${token}.`\n )\n }\n }\n}\nexport function buildCreateVaultPlan(\n input: CreateVaultRequest & {\n readonly allowances: readonly VaultTokenAllowance[]\n }\n): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const akAddress = normalizeEvmAddress(input.akAddress)\n const poolManager = normalizeEvmAddress(input.poolManager)\n const poolAddress = normalizeEvmAddress(input.poolAddress)\n const positionManagerImplementation = normalizeEvmAddress(\n input.positionManagerImplementation\n )\n const associatedMiner = normalizeOptionalBytes32(\n input.associatedMiner,\n 'Associated miner'\n )\n const stashTokens = normalizeStashTokens(input.stashTokens)\n const allowances = allowanceMap(input.allowances)\n assertAllowanceSet(allowances, stashTokens)\n const { base } = foreverMoneyDeployment\n const steps: TransactionStep[] = []\n let value = 0n\n for (const stash of stashTokens) {\n if (stash.token === base.contracts.weth) {\n value += stash.amount\n assertNonNegativeAmount(value, 'Vault creation value')\n continue\n }\n const allowance = allowances.get(stash.token.toLowerCase())\n if (allowance === undefined) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Missing allowance for stash token ${stash.token}.`\n )\n }\n if (allowance < stash.amount) {\n steps.push(\n step(\n 'approval',\n `Approve ${stash.token} for the vault factory`,\n owner,\n stash.token,\n encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [base.contracts.vaultFactory, stash.amount],\n })\n )\n )\n }\n }\n steps.push(\n step(\n 'transaction',\n 'Create ForeverMoney vault',\n owner,\n base.contracts.vaultFactory,\n encodeFunctionData({\n abi: factoryAbi,\n functionName: 'create',\n args: [\n owner,\n associatedMiner,\n akAddress,\n poolManager,\n poolAddress,\n positionManagerImplementation,\n stashTokens,\n ],\n }),\n value\n )\n )\n return createTransactionPlan({\n action: 'vault.create',\n summary: `Create a vault owned by ${owner} with ${stashTokens.length} initial stash token(s).`,\n steps,\n })\n}\nexport async function prepareCreateVault(\n provider: PublicClient,\n input: CreateVaultRequest\n): Promise<TransactionPlan> {\n const owner = normalizeEvmAddress(input.owner)\n const stashTokens = normalizeStashTokens(input.stashTokens)\n const erc20Stash = stashTokens.filter(\n ({ token }) => token !== foreverMoneyDeployment.base.contracts.weth\n )\n const allowances = await Promise.all(\n erc20Stash.map(async ({ token }) => ({\n token,\n allowance: await provider.readContract({\n address: token,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [\n owner,\n foreverMoneyDeployment.base.contracts.vaultFactory,\n ],\n }),\n }))\n )\n return buildCreateVaultPlan({ ...input, allowances })\n}\nexport interface DepositVaultRequest {\n readonly owner: string\n readonly manager: string\n readonly akAddress: string\n readonly deposits: readonly VaultStashToken[]\n}\nexport function buildDepositVaultPlan(\n input: DepositVaultRequest & {\n readonly allowances: readonly VaultTokenAllowance[]\n }\n): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const akAddress = normalizeEvmAddress(input.akAddress)\n const deposits = normalizeStashTokens(input.deposits)\n if (deposits.length === 0) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'At least one vault deposit is required.'\n )\n }\n const allowances = allowanceMap(input.allowances)\n assertAllowanceSet(allowances, deposits)\n const steps: TransactionStep[] = []\n for (const deposit of deposits) {\n if (deposit.token === foreverMoneyDeployment.base.contracts.weth) {\n steps.push(\n step(\n 'transaction',\n 'Deposit native ETH into the vault as WETH',\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: 'topUpAk',\n args: [akAddress, zeroAddress, deposit.amount],\n }),\n deposit.amount\n )\n )\n continue\n }\n const allowance = allowances.get(deposit.token.toLowerCase())\n if (allowance === undefined) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Missing allowance for deposit token ${deposit.token}.`\n )\n }\n if (allowance < deposit.amount) {\n steps.push(\n step(\n 'approval',\n `Approve ${deposit.token} for the vault manager`,\n owner,\n deposit.token,\n encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [manager, deposit.amount],\n })\n )\n )\n }\n steps.push(\n step(\n 'transaction',\n `Deposit ${deposit.token} into the vault`,\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: 'topUpAk',\n args: [akAddress, deposit.token, deposit.amount],\n })\n )\n )\n }\n return createTransactionPlan({\n action: 'vault.deposit',\n summary: `Deposit ${deposits.length} token amount(s) into vault ${manager}.`,\n steps,\n })\n}\nexport async function prepareDepositVault(\n provider: PublicClient,\n input: DepositVaultRequest\n): Promise<TransactionPlan> {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const deposits = normalizeStashTokens(input.deposits)\n const erc20Deposits = deposits.filter(\n ({ token }) => token !== foreverMoneyDeployment.base.contracts.weth\n )\n const allowances = await Promise.all(\n erc20Deposits.map(async ({ token }) => ({\n token,\n allowance: await provider.readContract({\n address: token,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [owner, manager],\n }),\n }))\n )\n return buildDepositVaultPlan({ ...input, allowances })\n}\nexport interface WithdrawVaultRequest {\n readonly owner: string\n readonly manager: string\n readonly akAddress: string\n readonly amount0: bigint\n readonly amount1: bigint\n readonly decreaseTokenIds: readonly bigint[]\n readonly unwrapWeth: boolean\n}\nexport function buildWithdrawVaultPlan(\n input: WithdrawVaultRequest\n): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const akAddress = normalizeEvmAddress(input.akAddress)\n assertArray(input.decreaseTokenIds, 'Position token IDs')\n assertBoolean(input.unwrapWeth, 'unwrapWeth')\n assertNonNegativeAmount(input.amount0, 'Token 0 withdrawal')\n assertNonNegativeAmount(input.amount1, 'Token 1 withdrawal')\n if (input.amount0 === 0n && input.amount1 === 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_ZERO',\n 'At least one withdrawal amount must be greater than zero.'\n )\n }\n for (const tokenId of input.decreaseTokenIds) {\n assertNonNegativeAmount(tokenId, 'Position token ID')\n }\n return createTransactionPlan({\n action: 'vault.withdraw',\n summary: `Withdraw token amounts from vault ${manager}.`,\n steps: [\n step(\n 'transaction',\n 'Withdraw assets from the vault',\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: 'withdrawFromAkAndPositions',\n args: [\n akAddress,\n input.amount0,\n input.amount1,\n input.decreaseTokenIds,\n input.unwrapWeth,\n ],\n })\n ),\n ],\n })\n}\nexport function buildClaimVaultFeesPlan(input: {\n readonly owner: string\n readonly manager: string\n readonly akAddress: string\n}): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const akAddress = normalizeEvmAddress(input.akAddress)\n return createTransactionPlan({\n action: 'vault.claim-fees',\n summary: `Claim all fees for ${akAddress} from vault ${manager}.`,\n steps: [\n step(\n 'transaction',\n 'Claim vault fees',\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: 'claimFees',\n args: [akAddress],\n })\n ),\n ],\n })\n}\nexport function buildSetVaultStakingPlan(input: {\n readonly owner: string\n readonly manager: string\n readonly akAddress: string\n readonly staking: boolean\n}): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const akAddress = normalizeEvmAddress(input.akAddress)\n assertBoolean(input.staking, 'staking')\n const action = input.staking ? 'stake' : 'unstake'\n return createTransactionPlan({\n action: `vault.${action}`,\n summary: `${input.staking ? 'Stake' : 'Unstake'} the active position in vault ${manager}.`,\n steps: [\n step(\n 'transaction',\n `${input.staking ? 'Stake' : 'Unstake'} the vault position`,\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: action,\n args: [akAddress, '0x'],\n })\n ),\n ],\n })\n}\n","import { trackingClient, type TrackingProvider } from '../core/transport.js'\nimport {\n decodeEventLog,\n parseAbi,\n TransactionReceiptNotFoundError,\n type Hex,\n type PublicClient,\n} from 'viem'\nimport { ALPHA_GATEWAY_ABI, CCIP_EXECUTION_ABI } from '../abis/index.js'\nimport { foreverMoneyDeployment } from '../chains/deployment.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport {\n assertBridgeDirection,\n bridgeMessageIdFromReceipt,\n evmChainFromBridgeDirection,\n isEvmToSubtensorDirection,\n type BridgeDirection,\n} from './receipts.js'\nimport { getForeverMoneyEvmDeployment } from '../chains/deployment.js'\nimport { normalizeBytes32 } from '../core/validation.js'\n\nconst ccipExecutionAbi = parseAbi(CCIP_EXECUTION_ABI)\nconst alphaGatewayAbi = parseAbi(ALPHA_GATEWAY_ABI)\n\nexport type CcipDeliveryStatus = 'failure' | 'recovery' | 'success' | 'waiting'\n\nexport interface CcipDeliveryStatusRequest {\n readonly direction: BridgeDirection\n readonly messageId: string\n readonly fromBlock: number\n}\n\nexport interface CcipDeliveryCheckpoint {\n readonly direction: BridgeDirection\n readonly destinationChainId: number\n readonly fromBlock: number\n}\n\nexport type BridgeSourceTransactionStatus = 'confirmed' | 'failed' | 'pending'\n\nexport interface BridgeSourceStatusRequest {\n readonly direction: BridgeDirection\n readonly transactionHash: string\n}\n\ninterface BridgeSourceStatusBase {\n readonly direction: BridgeDirection\n readonly sourceChainId: number\n readonly transactionHash: string\n}\n\nexport type BridgeSourceStatus =\n | (BridgeSourceStatusBase & {\n readonly status: 'confirmed'\n readonly messageId: string\n })\n | (BridgeSourceStatusBase & {\n readonly status: 'failed' | 'pending'\n readonly messageId: null\n })\n\nexport function destinationChainId(direction: BridgeDirection): number {\n assertBridgeDirection(direction)\n const evm = getForeverMoneyEvmDeployment(\n evmChainFromBridgeDirection(direction)\n )\n return isEvmToSubtensorDirection(direction)\n ? foreverMoneyDeployment.subtensor.chainId\n : evm.chainId\n}\n\nexport function sourceChainId(direction: BridgeDirection): number {\n assertBridgeDirection(direction)\n const evm = getForeverMoneyEvmDeployment(\n evmChainFromBridgeDirection(direction)\n )\n return isEvmToSubtensorDirection(direction)\n ? evm.chainId\n : foreverMoneyDeployment.subtensor.chainId\n}\n\nasync function assertProviderChain(\n provider: PublicClient,\n expectedChainId: number,\n label: string\n): Promise<void> {\n const chainId = await provider.getChainId()\n if (chainId !== expectedChainId) {\n throw new ForeverMoneyError(\n 'CHAIN_MISMATCH',\n `${label} transport reported chain ID ${chainId}; expected ${expectedChainId}.`,\n {\n expectedChainId,\n actualChainId: chainId.toString(),\n }\n )\n }\n}\n\nasync function assertDestinationProvider(\n provider: PublicClient,\n direction: BridgeDirection\n): Promise<number> {\n const expectedChainId = destinationChainId(direction)\n await assertProviderChain(provider, expectedChainId, 'Bridge destination')\n return expectedChainId\n}\n\nexport async function getBridgeSourceStatus(\n provider: TrackingProvider,\n input: BridgeSourceStatusRequest\n): Promise<BridgeSourceStatus> {\n const client = trackingClient(provider)\n const expectedChainId = sourceChainId(input.direction)\n const transactionHash = normalizeBytes32(\n input.transactionHash,\n 'Transaction hash'\n )\n await assertProviderChain(client, expectedChainId, 'Bridge source')\n const receipt = await receiptOrNull(client, transactionHash)\n if (receipt === null) {\n return Object.freeze({\n direction: input.direction,\n sourceChainId: expectedChainId,\n transactionHash,\n status: 'pending',\n messageId: null,\n })\n }\n if (receipt.status === 'reverted') {\n return Object.freeze({\n direction: input.direction,\n sourceChainId: expectedChainId,\n transactionHash,\n status: 'failed',\n messageId: null,\n })\n }\n if (receipt.status !== 'success') {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'The bridge source receipt has an invalid status.'\n )\n }\n const messageId = bridgeMessageIdFromReceipt(input.direction, receipt)\n if (messageId === null) {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'The confirmed bridge source receipt does not contain its canonical gateway event.'\n )\n }\n return Object.freeze({\n direction: input.direction,\n sourceChainId: expectedChainId,\n transactionHash,\n status: 'confirmed',\n messageId,\n })\n}\n\nexport async function getCcipDeliveryCheckpoint(\n provider: TrackingProvider,\n direction: BridgeDirection\n): Promise<CcipDeliveryCheckpoint> {\n const client = trackingClient(provider)\n const expectedChainId = await assertDestinationProvider(client, direction)\n const blockNumber = await client.getBlockNumber({ cacheTime: 0 })\n const fromBlock = Number(blockNumber)\n if (!Number.isSafeInteger(fromBlock) || fromBlock < 0) {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'Bridge destination transport returned an invalid block number.'\n )\n }\n return Object.freeze({\n direction,\n destinationChainId: expectedChainId,\n fromBlock,\n })\n}\n\nexport async function getCcipDeliveryStatus(\n provider: TrackingProvider,\n input: CcipDeliveryStatusRequest\n): Promise<CcipDeliveryStatus> {\n const client = trackingClient(provider)\n const expectedChainId = destinationChainId(input.direction)\n const messageId = normalizeBytes32(input.messageId, 'CCIP message ID')\n if (!Number.isSafeInteger(input.fromBlock) || input.fromBlock < 0) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'CCIP fromBlock must be a non-negative safe integer.'\n )\n }\n await assertProviderChain(client, expectedChainId, 'Bridge destination')\n\n const evmChain = evmChainFromBridgeDirection(input.direction)\n const evm = getForeverMoneyEvmDeployment(evmChain)\n const evmToSubtensor = isEvmToSubtensorDirection(input.direction)\n const sourceSelector = evmToSubtensor\n ? evm.ccipSelector\n : foreverMoneyDeployment.subtensor.ccipSelector\n const offRamp = evmToSubtensor\n ? evmChain === 'base'\n ? foreverMoneyDeployment.subtensor.contracts.ccipOffRampFromBase\n : foreverMoneyDeployment.subtensor.contracts\n .ccipOffRampFromRobinhood\n : evm.contracts.ccipOffRampFromSubtensor\n const logs = await client.getLogs({\n address: offRamp,\n fromBlock: BigInt(input.fromBlock),\n toBlock: 'latest',\n event: ccipExecutionAbi[0],\n args: { sourceChainSelector: sourceSelector, messageId },\n strict: true,\n })\n const latest = logs.at(-1)\n if (latest === undefined) return 'waiting'\n\n const state = latest.args.state\n if (state === 3) return 'failure'\n if (state !== 2) return 'waiting'\n if (!evmToSubtensor) return 'success'\n\n const receipt = await receiptOrNull(client, latest.transactionHash!)\n if (receipt === null) {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'The CCIP execution receipt is unavailable.'\n )\n }\n const subtensorGateways = [\n ...foreverMoneyDeployment.subtensor.contracts.legacyGateways,\n foreverMoneyDeployment.subtensor.contracts.gateway,\n ]\n for (const log of receipt.logs) {\n if (\n !subtensorGateways.some(\n (gateway) => log.address.toLowerCase() === gateway.toLowerCase()\n )\n ) {\n continue\n }\n try {\n const { eventName } = decodeEventLog({\n abi: alphaGatewayAbi,\n data: log.data,\n topics: log.topics,\n })\n // V5 can report an undelivered message without a Claimable event.\n if (eventName === 'Claimable' || eventName === 'NotDelivered') {\n return 'recovery'\n }\n } catch {\n // The execution receipt can contain other gateway events.\n }\n }\n return 'success'\n}\n\nasync function receiptOrNull(provider: PublicClient, hash: Hex) {\n try {\n return await provider.getTransactionReceipt({ hash })\n } catch (error) {\n if (error instanceof TransactionReceiptNotFoundError) return null\n throw error\n }\n}\n","import { decodeEventLog, isHex, parseAbi, type Hex } from 'viem'\nimport { ALPHA_GATEWAY_ABI, SPOKE_GATEWAY_ABI } from '../abis/index.js'\nimport {\n foreverMoneyDeployment,\n getForeverMoneyEvmDeployment,\n type ForeverMoneyEvmChain,\n} from '../chains/deployment.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport { isLogFrom, type TransactionReceiptLike } from '../core/receipts.js'\n\nexport type { ReceiptLog, TransactionReceiptLike } from '../core/receipts.js'\n\nconst alphaGatewayAbi = parseAbi(ALPHA_GATEWAY_ABI)\nconst spokeGatewayAbi = parseAbi(SPOKE_GATEWAY_ABI)\n\nexport type BridgeDirection =\n | 'base-to-subtensor'\n | 'robinhood-to-subtensor'\n | 'subtensor-to-base'\n | 'subtensor-to-robinhood'\n\nexport function assertBridgeDirection(\n value: unknown\n): asserts value is BridgeDirection {\n if (\n value !== 'base-to-subtensor' &&\n value !== 'robinhood-to-subtensor' &&\n value !== 'subtensor-to-base' &&\n value !== 'subtensor-to-robinhood'\n ) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Bridge direction must identify a canonical Base or Robinhood lane.'\n )\n }\n}\n\nexport function evmChainFromBridgeDirection(\n direction: BridgeDirection\n): ForeverMoneyEvmChain {\n assertBridgeDirection(direction)\n return direction.includes('robinhood') ? 'robinhood' : 'base'\n}\n\nexport function isEvmToSubtensorDirection(direction: BridgeDirection): boolean {\n assertBridgeDirection(direction)\n return direction.endsWith('-to-subtensor')\n}\n\nexport function bridgeMessageIdFromReceipt(\n direction: BridgeDirection,\n receipt: TransactionReceiptLike\n): string | null {\n assertBridgeDirection(direction)\n const evm = getForeverMoneyEvmDeployment(\n evmChainFromBridgeDirection(direction)\n )\n const evmToSubtensor = isEvmToSubtensorDirection(direction)\n const [addresses, contractAbi, eventName] = evmToSubtensor\n ? [\n [...evm.contracts.legacyGateways, evm.contracts.gateway],\n spokeGatewayAbi,\n 'BridgedToFinney',\n ]\n : [\n [\n ...foreverMoneyDeployment.subtensor.contracts.legacyGateways,\n foreverMoneyDeployment.subtensor.contracts.gateway,\n ],\n alphaGatewayAbi,\n 'BridgedOut',\n ]\n\n for (const log of receipt.logs) {\n if (!addresses.some((address) => isLogFrom(log, address))) continue\n try {\n const parsed = decodeEventLog({\n abi: contractAbi,\n data: log.data as Hex,\n topics: [...log.topics] as [Hex, ...Hex[]],\n })\n const messageId =\n 'messageId' in parsed.args ? parsed.args.messageId : undefined\n if (\n parsed.eventName === eventName &&\n typeof messageId === 'string' &&\n isHex(messageId, { strict: true }) &&\n messageId.length === 66 &&\n (evmToSubtensor ||\n ('destChainSelector' in parsed.args &&\n parsed.args.destChainSelector === evm.ccipSelector))\n ) {\n return messageId.toLowerCase()\n }\n } catch {\n // A receipt can contain unrelated events from the same contract.\n }\n }\n return null\n}\n","export interface ReceiptLog {\n readonly address: string\n readonly data: string\n readonly topics: readonly string[]\n}\n\nexport interface TransactionReceiptLike {\n readonly logs: readonly ReceiptLog[]\n}\n\nexport function isLogFrom(log: ReceiptLog, address: string): boolean {\n return log.address.toLowerCase() === address.toLowerCase()\n}\n","import type { PublicClient } from 'viem'\nimport {\n prepareBaseToSubtensor,\n prepareEvmToSubtensor,\n prepareSubtensorToBase,\n prepareSubtensorToEvm,\n type BaseToSubtensorRequest,\n type BridgePreparation,\n type EvmToSubtensorRequest,\n type SubtensorToBaseRequest,\n type SubtensorToEvmRequest,\n} from './bridge/plans.js'\nimport {\n BASE_CHAIN_ID,\n ROBINHOOD_CHAIN_ID,\n SUBTENSOR_CHAIN_ID,\n getForeverMoneyEvmDeployment,\n} from './chains/deployment.js'\nimport { ForeverMoneyError } from './core/errors.js'\nimport { providerFromTransport, type RpcTransport } from './core/transport.js'\nimport { providerOperation } from './core/provider-errors.js'\nimport {\n prepareCreateVault,\n prepareDepositVault,\n type CreateVaultRequest,\n type DepositVaultRequest,\n} from './vaults/plans.js'\nimport type { TransactionPlan } from './core/plans.js'\nimport {\n destinationChainId,\n getBridgeSourceStatus,\n getCcipDeliveryCheckpoint,\n getCcipDeliveryStatus,\n sourceChainId,\n type BridgeSourceStatus,\n type BridgeSourceStatusRequest,\n type CcipDeliveryCheckpoint,\n type CcipDeliveryStatus,\n type CcipDeliveryStatusRequest,\n} from './bridge/tracking.js'\nimport type { BridgeDirection } from './bridge/receipts.js'\n\nexport interface ForeverMoneyClientOptions {\n readonly transports: {\n readonly base: RpcTransport\n readonly robinhood?: RpcTransport\n readonly subtensor: RpcTransport\n }\n}\n\nexport interface ForeverMoneyClient {\n readonly bridge: {\n prepareEvmToSubtensor(\n input: EvmToSubtensorRequest\n ): Promise<BridgePreparation>\n prepareBaseToSubtensor(\n input: BaseToSubtensorRequest\n ): Promise<BridgePreparation>\n prepareSubtensorToEvm(\n input: SubtensorToEvmRequest\n ): Promise<BridgePreparation>\n prepareSubtensorToBase(\n input: SubtensorToBaseRequest\n ): Promise<BridgePreparation>\n getDeliveryCheckpoint(\n direction: BridgeDirection\n ): Promise<CcipDeliveryCheckpoint>\n getDeliveryStatus(\n input: CcipDeliveryStatusRequest\n ): Promise<CcipDeliveryStatus>\n getSourceStatus(\n input: BridgeSourceStatusRequest\n ): Promise<BridgeSourceStatus>\n }\n readonly vaults: {\n prepareCreate(input: CreateVaultRequest): Promise<TransactionPlan>\n prepareDeposit(input: DepositVaultRequest): Promise<TransactionPlan>\n }\n verifyConnections(): Promise<void>\n}\n\nasync function assertProviderChain(\n provider: PublicClient,\n expectedChainId: number,\n name: string\n): Promise<void> {\n const chainId = await providerOperation(\n `Reading the ${name} chain ID`,\n () => provider.getChainId()\n )\n if (chainId !== expectedChainId) {\n throw new ForeverMoneyError(\n 'CHAIN_MISMATCH',\n `${name} transport reported chain ID ${chainId}; expected ${expectedChainId}.`,\n {\n expectedChainId,\n actualChainId: chainId.toString(),\n }\n )\n }\n}\n\nexport function createForeverMoneyClient(\n options: ForeverMoneyClientOptions\n): ForeverMoneyClient {\n if (!options?.transports?.base || !options.transports.subtensor) {\n throw new ForeverMoneyError(\n 'MISSING_TRANSPORT',\n 'Base and Subtensor transports are required.'\n )\n }\n const baseProvider = providerFromTransport(options.transports.base)\n const subtensorProvider = providerFromTransport(\n options.transports.subtensor\n )\n const robinhoodProvider = options.transports.robinhood\n ? providerFromTransport(options.transports.robinhood)\n : undefined\n const verifyBaseConnection = async (): Promise<void> => {\n await assertProviderChain(baseProvider, BASE_CHAIN_ID, 'Base')\n }\n const verifySubtensorConnection = async (): Promise<void> => {\n await assertProviderChain(\n subtensorProvider,\n SUBTENSOR_CHAIN_ID,\n 'Subtensor'\n )\n }\n const verifyRobinhoodConnection = async (): Promise<void> => {\n if (robinhoodProvider === undefined) return\n await assertProviderChain(\n robinhoodProvider,\n ROBINHOOD_CHAIN_ID,\n 'Robinhood'\n )\n }\n const verifyConnections = async (): Promise<void> => {\n await Promise.all([\n verifyBaseConnection(),\n verifyRobinhoodConnection(),\n verifySubtensorConnection(),\n ])\n }\n const providerForChain = (chainId: number): PublicClient => {\n if (chainId === BASE_CHAIN_ID) return baseProvider\n if (chainId === SUBTENSOR_CHAIN_ID) return subtensorProvider\n if (chainId === ROBINHOOD_CHAIN_ID && robinhoodProvider !== undefined) {\n return robinhoodProvider\n }\n throw new ForeverMoneyError(\n 'MISSING_TRANSPORT',\n `A transport for chain ID ${chainId} is required for this operation.`\n )\n }\n\n return Object.freeze({\n bridge: Object.freeze({\n async prepareEvmToSubtensor(input: EvmToSubtensorRequest) {\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const provider = providerForChain(evm.chainId)\n await assertProviderChain(provider, evm.chainId, evm.name)\n return providerOperation(\n `Preparing the ${evm.name} to Subtensor bridge`,\n () => prepareEvmToSubtensor(provider, input)\n )\n },\n async prepareBaseToSubtensor(input: BaseToSubtensorRequest) {\n await verifyBaseConnection()\n return providerOperation(\n 'Preparing the Base to Subtensor bridge',\n () => prepareBaseToSubtensor(baseProvider, input)\n )\n },\n async prepareSubtensorToEvm(input: SubtensorToEvmRequest) {\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n await verifySubtensorConnection()\n return providerOperation(\n `Preparing the Subtensor to ${evm.name} bridge`,\n () => prepareSubtensorToEvm(subtensorProvider, input)\n )\n },\n async prepareSubtensorToBase(input: SubtensorToBaseRequest) {\n await verifySubtensorConnection()\n return providerOperation(\n 'Preparing the Subtensor to Base bridge',\n () => prepareSubtensorToBase(subtensorProvider, input)\n )\n },\n async getDeliveryCheckpoint(direction: BridgeDirection) {\n const expectedChainId = destinationChainId(direction)\n const provider = providerForChain(expectedChainId)\n return providerOperation(\n 'Reading the bridge delivery checkpoint',\n () => getCcipDeliveryCheckpoint(provider, direction)\n )\n },\n async getDeliveryStatus(input: CcipDeliveryStatusRequest) {\n const expectedChainId = destinationChainId(input.direction)\n const provider = providerForChain(expectedChainId)\n return providerOperation('Reading CCIP delivery status', () =>\n getCcipDeliveryStatus(provider, input)\n )\n },\n async getSourceStatus(input: BridgeSourceStatusRequest) {\n const expectedChainId = sourceChainId(input.direction)\n const provider = providerForChain(expectedChainId)\n return providerOperation(\n 'Reading the bridge source transaction',\n () => getBridgeSourceStatus(provider, input)\n )\n },\n }),\n vaults: Object.freeze({\n async prepareCreate(input: CreateVaultRequest) {\n await verifyBaseConnection()\n return providerOperation('Preparing vault creation', () =>\n prepareCreateVault(baseProvider, input)\n )\n },\n async prepareDeposit(input: DepositVaultRequest) {\n await verifyBaseConnection()\n return providerOperation('Preparing the vault deposit', () =>\n prepareDepositVault(baseProvider, input)\n )\n },\n }),\n verifyConnections,\n })\n}\n","import { decodeEventLog, parseAbi, type Hex } from 'viem'\nimport { VAULT_FACTORY_ABI } from '../abis/index.js'\nimport { foreverMoneyDeployment } from '../chains/deployment.js'\nimport { normalizeEvmAddress } from '../core/addresses.js'\nimport { isLogFrom, type TransactionReceiptLike } from '../core/receipts.js'\n\nconst vaultFactoryAbi = parseAbi(VAULT_FACTORY_ABI)\n\nexport function vaultManagerFromCreationReceipt(\n receipt: TransactionReceiptLike\n): string | null {\n for (const log of receipt.logs) {\n if (\n !isLogFrom(log, foreverMoneyDeployment.base.contracts.vaultFactory)\n ) {\n continue\n }\n try {\n const parsed = decodeEventLog({\n abi: vaultFactoryAbi,\n data: log.data as Hex,\n topics: [...log.topics] as [Hex, ...Hex[]],\n })\n if (parsed.eventName === 'SnLiquidityManagerCreated') {\n return normalizeEvmAddress(String(parsed.args.manager))\n }\n } catch {\n // A receipt can contain unrelated events from the same contract.\n }\n }\n return null\n}\n","import {\n defineChain,\n maxUint256,\n type Address,\n type Chain,\n type Hex,\n} from 'viem'\nimport {\n BASE_CHAIN_ID,\n ROBINHOOD_CHAIN_ID,\n SUBTENSOR_CHAIN_ID,\n} from '../chains/deployment.js'\nimport { ForeverMoneyError } from './errors.js'\nimport type { PreparedTransaction } from './plans.js'\n\nexport interface Eip1193TransactionRequest {\n readonly from: string\n readonly to: string\n readonly data: string\n readonly value: string\n readonly gas?: string\n}\n\nfunction decimalQuantity(value: string, label: string): bigint {\n if (!/^(0|[1-9][0-9]*)$/.test(value)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be an unsigned decimal integer.`\n )\n }\n const quantity = BigInt(value)\n if (quantity > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} exceeds uint256.`\n )\n }\n return quantity\n}\n\nfunction hexQuantity(value: bigint): string {\n return `0x${value.toString(16)}`\n}\n\nexport function toEip1193Transaction(\n transaction: PreparedTransaction\n): Eip1193TransactionRequest {\n const value = decimalQuantity(transaction.value, 'Transaction value')\n const gasLimit =\n transaction.gasLimit === undefined\n ? undefined\n : decimalQuantity(transaction.gasLimit, 'Transaction gas limit')\n\n return Object.freeze({\n from: transaction.from,\n to: transaction.to,\n data: transaction.data,\n value: hexQuantity(value),\n ...(gasLimit === undefined ? {} : { gas: hexQuantity(gasLimit) }),\n })\n}\n\nexport function toEthersTransaction(\n transaction: PreparedTransaction\n): Readonly<EthersCompatibleTransactionRequest> {\n return Object.freeze({\n chainId: transaction.chainId,\n to: transaction.to,\n data: transaction.data,\n value: decimalQuantity(transaction.value, 'Transaction value'),\n ...(transaction.gasLimit === undefined\n ? {}\n : {\n gasLimit: decimalQuantity(\n transaction.gasLimit,\n 'Transaction gas limit'\n ),\n }),\n })\n}\n\n// Structural compatibility for existing consumers; no ethers dependency.\nexport interface EthersCompatibleTransactionRequest {\n readonly chainId: number\n readonly to: string\n readonly data: string\n readonly value: bigint\n readonly gasLimit?: bigint\n}\n\nexport interface ViemTransactionRequest {\n readonly chain: Chain\n readonly account: Address\n readonly chainId: number\n readonly to: Address\n readonly data: Hex\n readonly value: bigint\n readonly gas?: bigint\n}\n\nconst transactionChains = new Map<number, Chain>(\n (\n [\n [BASE_CHAIN_ID, 'Base', 'Ether', 'ETH'],\n [ROBINHOOD_CHAIN_ID, 'Robinhood', 'Ether', 'ETH'],\n [SUBTENSOR_CHAIN_ID, 'Subtensor', 'TAO', 'TAO'],\n ] as const\n ).map(([id, name, currency, symbol]) => [\n id,\n Object.freeze(\n defineChain({\n id,\n name,\n nativeCurrency: Object.freeze({\n name: currency,\n symbol,\n decimals: 18,\n }),\n // Chain identity only. The caller retains ownership of the wallet transport.\n rpcUrls: Object.freeze({\n default: Object.freeze({ http: Object.freeze([]) }),\n }),\n })\n ),\n ])\n)\n\nexport function toViemTransaction(\n transaction: PreparedTransaction\n): Readonly<ViemTransactionRequest> {\n const chain = transactionChains.get(transaction.chainId)\n if (!chain)\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Unsupported transaction chain.'\n )\n return Object.freeze({\n chain,\n account: transaction.from as Address,\n chainId: transaction.chainId,\n to: transaction.to as Address,\n data: transaction.data as Hex,\n value: decimalQuantity(transaction.value, 'Transaction value'),\n ...(transaction.gasLimit === undefined\n ? {}\n : {\n gas: decimalQuantity(\n transaction.gasLimit,\n 'Transaction gas limit'\n ),\n }),\n })\n}\n"],"mappings":"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","names":["maxUint256","maxUint256","candidatePulls","getAddress","getAddress","stringToBytes","step","stringToBytes","args","step","encodeFunctionData","parseAbi","zeroAddress","erc20Abi","parseAbi","encodeFunctionData","zeroAddress","decodeEventLog","parseAbi","isHex","parseAbi","parseAbi","isHex","parseAbi","alphaGatewayAbi","decodeEventLog","assertProviderChain","decodeEventLog","parseAbi","parseAbi","decodeEventLog","maxUint256","maxUint256"]}
1
+ {"version":3,"sources":["../src/chains/deployment.ts","../src/core/amounts.ts","../src/core/errors.ts","../src/core/validation.ts","../src/bridge/stake-rounding.ts","../src/core/addresses.ts","../src/abis/index.ts","../src/bridge/plans.ts","../src/core/plans.ts","../src/core/transport.ts","../src/core/provider-errors.ts","../src/vaults/plans.ts","../src/bridge/tracking.ts","../src/bridge/receipts.ts","../src/core/receipts.ts","../src/client.ts","../src/vaults/receipts.ts","../src/core/transactions.ts"],"sourcesContent":["import { getAddress } from 'viem'\n\nexport const BASE_CHAIN_ID = 8453\nexport const ROBINHOOD_CHAIN_ID = 4663\nexport const SUBTENSOR_CHAIN_ID = 964\nexport const BASE_CCIP_SELECTOR = 15_971_525_489_660_198_786n\nexport const ROBINHOOD_CCIP_SELECTOR = 6_180_753_054_346_818_345n\nexport const SUBTENSOR_CCIP_SELECTOR = 2_135_107_236_357_186_872n\nexport const RAO_PER_TAO = 1_000_000_000n\nexport const EVM_WEI_PER_RAO = 1_000_000_000n\nexport const SN80_NETUID = 80n\nexport const FOREVERMONEY_DEPLOYMENT_VERSION = '1.4.0' as const\n\nexport const foreverMoneyDeployment = Object.freeze({\n version: FOREVERMONEY_DEPLOYMENT_VERSION,\n base: Object.freeze({\n key: 'base',\n name: 'Base',\n chainId: BASE_CHAIN_ID,\n ccipSelector: BASE_CCIP_SELECTOR,\n contracts: Object.freeze({\n gateway: getAddress('0x1da2415229b614C787e145D1D7346eb496319C52'),\n // Retired gateways, oldest first; kept only to track transfers sent\n // through them.\n legacyGateways: [\n getAddress('0x5EF3d7D19e4b233a1A169DA0d5CB02ec6b160a2C'),\n ] as readonly `0x${string}`[],\n wrappedTao: getAddress(\n '0xf3081494b87e8d5fb7960f066e931d1d0e6e3d67'\n ),\n wrappedSn80: getAddress(\n '0x6f63d869011f95274498023b4abfc00b30c34378'\n ),\n ccipRouter: getAddress(\n '0x881e3A65B4d4a04dD529061dd0071cf975F58bCD'\n ),\n ccipOffRampFromSubtensor: getAddress(\n '0xf09AFe78d3c7d359b334d7cB88995751F7eC5E13'\n ),\n vaultFactory: getAddress(\n '0x9b7F3c7aa335D8BF9f91741E541820466735F868'\n ),\n vaultManagerImplementation: getAddress(\n '0x235Ad8654fe3a1619a9892eBCaD9361F416168da'\n ),\n batchLiquidityManagerQuery: getAddress(\n '0xd117176C5E6809b68500995F59589A8c081565A5'\n ),\n weth: getAddress('0x4200000000000000000000000000000000000006'),\n }),\n deploymentBlock: 50_098_800,\n }),\n robinhood: Object.freeze({\n key: 'robinhood',\n name: 'Robinhood',\n chainId: ROBINHOOD_CHAIN_ID,\n ccipSelector: ROBINHOOD_CCIP_SELECTOR,\n contracts: Object.freeze({\n gateway: getAddress('0xf27fdA637131E25B2A1b4865ED9597d881980c7E'),\n legacyGateways: [\n getAddress('0x53Dcc4FE04193e489BE537F722F65317DB1E65d8'),\n ] as readonly `0x${string}`[],\n wrappedTao: getAddress(\n '0xf3081494B87e8D5fb7960f066E931D1D0e6E3d67'\n ),\n wrappedSn80: getAddress(\n '0x6f63d869011f95274498023b4abfc00b30c34378'\n ),\n ccipRouter: getAddress(\n '0x06fC836cf9839B1cd891C440A0a45242DA6Ae1c9'\n ),\n ccipOffRampFromSubtensor: getAddress(\n '0xcDca5D374e46A6DDDab50bD2D9acB8c796eC35C3'\n ),\n }),\n }),\n subtensor: Object.freeze({\n chainId: SUBTENSOR_CHAIN_ID,\n ccipSelector: SUBTENSOR_CCIP_SELECTOR,\n contracts: Object.freeze({\n // V5.1 AlphaGateway: multi-validator staked input (tao-bridge 485c898).\n gateway: getAddress('0xd5Fa238aa4177f6c1341491969d9cBeec94EEd69'),\n // V4 and V5 hubs. The spokes still deliver to the V5 hub (their hub\n // pointer is immutable), so it stays here for delivery tracking.\n legacyGateways: [\n getAddress('0x998f20Fea90bF7792774dECc7f994716442B1705'),\n getAddress('0xcd0C6d98D0A126B1c113d15b4c28F38321437787'),\n ] as readonly `0x${string}`[],\n alphaVault: getAddress(\n '0x11837459896D96F821a8D88eC93a3C8D152033D4'\n ),\n wrappedTao: getAddress(\n '0xC5b6C1632d34901239396F5E1BDe54B342900256'\n ),\n wrappedSn80: getAddress(\n '0xfD628dE75EF96f0A5C59659159C6cA81E0DC2222'\n ),\n ccipRouter: getAddress(\n '0xD941fBEcD2b971d0F54b4C34286C95faB52B60B8'\n ),\n ccipOffRampFromBase: getAddress(\n '0x51a6150400ed9F0Ae240F5D1b15E3b45Fc4339C7'\n ),\n ccipOffRampFromRobinhood: getAddress(\n '0x51a6150400ed9F0Ae240F5D1b15E3b45Fc4339C7'\n ),\n stakingPrecompile: getAddress(\n '0x0000000000000000000000000000000000000805'\n ),\n }),\n }),\n})\n\nexport type ForeverMoneyDeployment = typeof foreverMoneyDeployment\nexport type ForeverMoneyEvmChain = 'base' | 'robinhood'\n\nexport function getForeverMoneyEvmDeployment(\n chain: ForeverMoneyEvmChain = 'base'\n): ForeverMoneyDeployment['base'] | ForeverMoneyDeployment['robinhood'] {\n return foreverMoneyDeployment[chain]\n}\n","import { maxUint256, formatUnits, parseUnits } from 'viem'\nimport { EVM_WEI_PER_RAO } from '../chains/deployment.js'\nimport { ForeverMoneyError } from './errors.js'\n\nexport const BASIS_POINTS = 10_000n\nexport const NETWORK_FEE_BUFFER_BPS = 200n\nexport const GAS_LIMIT_BUFFER_BPS = 5_000n\n\nexport function parseTaoAmount(value: string): bigint {\n if (typeof value !== 'string') {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must be decimal strings.'\n )\n }\n const decimalPlaces = value.includes('.')\n ? (value.split('.')[1]?.length ?? 0)\n : 0\n if (decimalPlaces > 9) {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must be positive decimal strings with at most nine decimal places.'\n )\n }\n let amount: bigint\n try {\n amount = parseUnits(value, 18)\n } catch {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must be positive decimal strings with at most nine decimal places.'\n )\n }\n assertWholeRao(amount)\n return amount\n}\n\nexport function assertWholeRao(amountWei: bigint): void {\n if (typeof amountWei !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The amount must be a bigint.'\n )\n }\n if (amountWei === 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_ZERO',\n 'The amount must be greater than zero.'\n )\n }\n if (amountWei < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The amount cannot be negative.'\n )\n }\n if (amountWei > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The amount exceeds uint256.'\n )\n }\n if (amountWei % EVM_WEI_PER_RAO !== 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must resolve to a whole RAO.'\n )\n }\n}\n\nexport function formatTaoAmount(amountWei: bigint): string {\n if (typeof amountWei !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The TAO amount must be a bigint.'\n )\n }\n if (amountWei < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'A TAO amount cannot be negative.'\n )\n }\n if (amountWei > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The TAO amount exceeds uint256.'\n )\n }\n if (amountWei % EVM_WEI_PER_RAO !== 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_NOT_WHOLE_RAO',\n 'TAO amounts must resolve to a whole RAO.'\n )\n }\n const formatted = formatUnits(amountWei, 18)\n return formatted.includes('.') ? formatted : `${formatted}.0`\n}\n\nfunction mulDivCeil(\n value: bigint,\n numerator: bigint,\n denominator: bigint\n): bigint {\n return (value * numerator + denominator - 1n) / denominator\n}\n\nexport function feeWithBuffer(fee: bigint): bigint {\n if (typeof fee !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The network fee must be a bigint.'\n )\n }\n if (fee < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'A network fee cannot be negative.'\n )\n }\n const buffered = mulDivCeil(\n fee,\n BASIS_POINTS + NETWORK_FEE_BUFFER_BPS,\n BASIS_POINTS\n )\n if (buffered > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The buffered network fee exceeds uint256.'\n )\n }\n return buffered\n}\n\nexport function gasLimitWithBuffer(gasLimit: bigint): bigint {\n if (typeof gasLimit !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The gas limit must be a bigint.'\n )\n }\n if (gasLimit <= 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'A gas limit must be greater than zero.'\n )\n }\n const buffered = mulDivCeil(\n gasLimit,\n BASIS_POINTS + GAS_LIMIT_BUFFER_BPS,\n BASIS_POINTS\n )\n if (buffered > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The buffered gas limit exceeds uint256.'\n )\n }\n return buffered\n}\n","export type ForeverMoneyErrorCode =\n | 'AMOUNT_BELOW_MINIMUM'\n | 'AMOUNT_NOT_WHOLE_RAO'\n | 'AMOUNT_ZERO'\n | 'CHAIN_MISMATCH'\n | 'INVALID_ADDRESS'\n | 'INVALID_BYTES32'\n | 'INVALID_PARTNER_FEE'\n | 'INVALID_PROVIDER_RESPONSE'\n | 'INVALID_SS58'\n | 'INVALID_TRANSACTION_PLAN'\n | 'MISSING_TRANSPORT'\n | 'RPC_ERROR'\n | 'SIMULATION_REVERTED'\n\nexport class ForeverMoneyError extends Error {\n readonly code: ForeverMoneyErrorCode\n readonly details: Readonly<Record<string, unknown>> | undefined\n\n constructor(\n code: ForeverMoneyErrorCode,\n message: string,\n details?: Readonly<Record<string, unknown>>\n ) {\n super(message)\n this.name = 'ForeverMoneyError'\n this.code = code\n this.details =\n details === undefined ? undefined : Object.freeze({ ...details })\n }\n}\n","import { maxUint256, zeroHash, isHex, type Hex } from 'viem'\nimport { ForeverMoneyError } from './errors.js'\n\nfunction assertBigInt(\n amount: unknown,\n label: string\n): asserts amount is bigint {\n if (typeof amount !== 'bigint') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be a bigint.`\n )\n }\n}\n\nexport function assertPositiveAmount(\n amount: unknown,\n label: string\n): asserts amount is bigint {\n assertBigInt(amount, label)\n if (amount === 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_ZERO',\n `${label} must be greater than zero.`\n )\n }\n if (amount < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} cannot be negative.`\n )\n }\n if (amount > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} exceeds uint256.`\n )\n }\n}\n\nexport function assertNonNegativeAmount(\n amount: unknown,\n label: string\n): asserts amount is bigint {\n assertBigInt(amount, label)\n if (amount < 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} cannot be negative.`\n )\n }\n if (amount > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} exceeds uint256.`\n )\n }\n}\n\nexport function assertBoolean(\n value: unknown,\n label: string\n): asserts value is boolean {\n if (typeof value !== 'boolean') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be a boolean.`\n )\n }\n}\n\nexport function assertArray(\n value: unknown,\n label: string\n): asserts value is readonly unknown[] {\n if (!Array.isArray(value)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be an array.`\n )\n }\n}\n\nexport function assertRecord(\n value: unknown,\n label: string\n): asserts value is Readonly<Record<string, unknown>> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be an object.`\n )\n }\n}\n\nexport function normalizeBytes32(value: string, label: string): Hex {\n if (!isHex(value, { strict: true }) || value.length !== 66) {\n throw new ForeverMoneyError(\n 'INVALID_BYTES32',\n `${label} must be a 32-byte hex value.`\n )\n }\n return value.toLowerCase() as Hex\n}\n\nexport function normalizeOptionalBytes32(\n value: string | undefined,\n label: string\n): Hex {\n return value === undefined ? zeroHash : normalizeBytes32(value, label)\n}\n","import { EVM_WEI_PER_RAO } from '../chains/deployment.js'\nimport { assertWholeRao } from '../core/amounts.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport {\n assertBoolean,\n assertNonNegativeAmount,\n assertPositiveAmount,\n normalizeBytes32,\n} from '../core/validation.js'\nimport type { StakePull } from './plans.js'\n\nexport interface StakePosition {\n readonly hotkey: string\n readonly stakeRao: bigint\n}\nexport interface StakeRoundingOptions {\n readonly enabled: boolean\n /** Current source balances, including any partner fee headroom. */\n readonly positions: readonly StakePosition[]\n /** Minimum positive remainder to leave on any source. Defaults to zero. */\n readonly minStakeRao?: bigint\n}\nexport interface StakeRoundingResult {\n readonly requestedAmountWei: bigint\n readonly amountWei: bigint\n readonly minAmountOutWei: bigint\n readonly pulls: readonly StakePull[]\n /** False when approval is still required; prepare again after approval. */\n readonly simulationComplete: boolean\n}\nexport interface EstimateRoundedStakeRequest<T> {\n readonly amountWei: bigint\n readonly minAmountOutWei: bigint\n readonly pulls: readonly StakePull[]\n readonly positions: readonly StakePosition[]\n readonly minStakeRao?: bigint\n /** Defaults to true. False estimates the exact input once, without adjustments. */\n readonly adjustRounding?: boolean\n readonly partnerFeeBps?: number\n readonly isActive?: () => boolean\n readonly quoteAndEstimate: (\n amountWei: bigint,\n pulls: readonly StakePull[],\n minAmountOutWei: bigint\n ) => Promise<T>\n}\nexport type RoundedStakeEstimate<T> = T & {\n readonly amountWei: bigint\n readonly minAmountOutWei: bigint\n readonly pulls: readonly StakePull[]\n}\n\nfunction invalid(message: string): never {\n throw new ForeverMoneyError('INVALID_TRANSACTION_PLAN', message)\n}\n\n/** Small explicit output tolerance for stake transfer/deposit dust. Never returns zero. */\nexport function stakedMinimumOutput(\n amountWei: bigint,\n sourceCount = 1\n): bigint {\n assertWholeRao(amountWei)\n if (!Number.isInteger(sourceCount) || sourceCount < 1 || sourceCount > 16)\n invalid('Source count must be between 1 and 16.')\n const rao = amountWei / EVM_WEI_PER_RAO\n const dust = 2n * BigInt(sourceCount) + 2n\n return (rao > dust ? rao - dust : rao) * EVM_WEI_PER_RAO\n}\n\n/** Supports raw RPC, ethers and viem nested errors. Ignores unrelated revert data. */\nexport function strandedStakeSource(error: unknown): string | null {\n const queue: unknown[] = [error]\n const seen = new Set<object>()\n while (queue.length && seen.size < 20) {\n const entry = queue.shift()\n if (\n typeof entry === 'string' &&\n /^0x5408a598[0-9a-f]{128}$/i.test(entry)\n )\n return `0x${entry.slice(10, 74)}`.toLowerCase()\n if (entry && typeof entry === 'object' && !seen.has(entry)) {\n seen.add(entry)\n for (const key of [\n 'data',\n 'error',\n 'info',\n 'cause',\n 'details',\n 'rpcData',\n ]) {\n const nested = (entry as Record<string, unknown>)[key]\n if (nested != null) queue.push(nested)\n }\n }\n }\n return null\n}\n\n/** SDK-owned, read-only candidate search. Never lowers minAmountOutWei or broadcasts.\n * At most eight reductions of one alpha base unit; only StrandedStake triggers retries.\n * quoteAndEstimate must quote and simulate the exact candidate, and must never sign/send.\n */\nexport async function estimateRoundedStake<T>({\n amountWei,\n minAmountOutWei,\n pulls,\n positions,\n minStakeRao = 0n,\n adjustRounding = true,\n partnerFeeBps = 0,\n quoteAndEstimate,\n isActive = () => true,\n}: EstimateRoundedStakeRequest<T>): Promise<RoundedStakeEstimate<T>> {\n assertWholeRao(amountWei)\n assertPositiveAmount(minAmountOutWei, 'Minimum output')\n if (minAmountOutWei > amountWei)\n invalid('Minimum output cannot exceed input.')\n assertBoolean(adjustRounding, 'adjustRounding')\n assertNonNegativeAmount(minStakeRao, 'Minimum remaining stake')\n if (\n !Number.isInteger(partnerFeeBps) ||\n partnerFeeBps < 0 ||\n partnerFeeBps > 10000\n )\n invalid('Invalid partner fee basis points.')\n if (!Array.isArray(pulls) || pulls.length < 1 || pulls.length > 16)\n invalid('Provide between 1 and 16 stake pulls.')\n const keys = new Set<string>()\n const originalPulls = pulls.map((pull) => {\n const hotkey = normalizeBytes32(pull.hotkey, 'Validator').toLowerCase()\n if (keys.has(hotkey)) invalid('Duplicate stake source.')\n keys.add(hotkey)\n assertPositiveAmount(pull.amountRao, 'Stake pull')\n return { hotkey, amountRao: pull.amountRao }\n })\n if (\n originalPulls.reduce((sum, pull) => sum + pull.amountRao, 0n) *\n EVM_WEI_PER_RAO !==\n amountWei\n )\n invalid('Stake pulls must sum to the input amount.')\n const balances = new Map<string, bigint>()\n if (!Array.isArray(positions)) invalid('Stake positions must be an array.')\n for (const position of positions) {\n const key = normalizeBytes32(position.hotkey, 'Validator').toLowerCase()\n if (balances.has(key)) invalid('Duplicate stake position.')\n assertNonNegativeAmount(position.stakeRao, 'Stake balance')\n balances.set(key, position.stakeRao)\n }\n const fits = (candidatePulls: readonly StakePull[]): boolean => {\n const total = candidatePulls.reduce(\n (sum, pull) => sum + pull.amountRao,\n 0n\n )\n const cut = (total * BigInt(partnerFeeBps)) / 10000n\n const shares = candidatePulls.map((pull, index) =>\n index ? (cut * pull.amountRao) / total : 0n\n )\n shares[0] = cut - shares.reduce((sum, share) => sum + share, 0n)\n return candidatePulls.every((pull, index) => {\n const balance = balances.get(pull.hotkey)\n if (balance == null) return false\n const remainder = balance - pull.amountRao - shares[index]!\n return (\n remainder === 0n || (remainder > 0n && remainder >= minStakeRao)\n )\n })\n }\n if (!fits(originalPulls))\n invalid(\n 'Stake positions cannot cover the pulls, partner fee, and minimum remainder.'\n )\n let candidate = amountWei\n let candidatePulls = originalPulls\n for (let attempt = 0; ; attempt++) {\n if (!isActive()) throw new Error('Stake quote cancelled.')\n try {\n const result = await quoteAndEstimate(\n candidate,\n candidatePulls,\n minAmountOutWei\n )\n if (!isActive()) throw new Error('Stake quote cancelled.')\n return Object.freeze({\n ...result,\n amountWei: candidate,\n pulls: Object.freeze(\n candidatePulls.map((pull) => Object.freeze({ ...pull }))\n ),\n minAmountOutWei,\n })\n } catch (error) {\n const hotkey = strandedStakeSource(error)\n if (\n !isActive() ||\n !adjustRounding ||\n !hotkey ||\n attempt >= 8 ||\n candidate - EVM_WEI_PER_RAO < minAmountOutWei\n )\n throw error\n const index = candidatePulls.findIndex(\n (pull) => pull.hotkey === hotkey\n )\n if (index < 0 || candidatePulls[index]!.amountRao <= 1n) throw error\n const nextPulls = candidatePulls.map((pull, i) =>\n i === index ? { ...pull, amountRao: pull.amountRao - 1n } : pull\n )\n if (!fits(nextPulls)) throw error\n candidatePulls = nextPulls\n candidate -= EVM_WEI_PER_RAO\n }\n }\n}\n","import {\n AccountId,\n Blake2256,\n getSs58AddressInfo,\n} from '@polkadot-api/substrate-bindings'\nimport {\n bytesToHex,\n concat,\n getAddress,\n hexToBytes,\n isAddress,\n stringToBytes,\n zeroAddress,\n type Address,\n type Hex,\n} from 'viem'\nimport { ForeverMoneyError } from './errors.js'\n\nconst BITTENSOR_SS58_PREFIX = 42\n\nexport function normalizeEvmAddress(value: string): Address {\n // All-uppercase and all-lowercase are valid unchecksummed forms. Mixed case\n // must still pass EIP-55 validation, as it did before the viem migration.\n const candidate =\n typeof value === 'string' && /^0x[0-9A-F]{40}$/.test(value)\n ? value.toLowerCase()\n : value\n if (!isAddress(candidate) || candidate === zeroAddress) {\n throw new ForeverMoneyError(\n 'INVALID_ADDRESS',\n 'Expected a non-zero EVM address.'\n )\n }\n return getAddress(candidate)\n}\n\nexport function evmToMirrorSS58(evmAddress: string): string {\n return AccountId(BITTENSOR_SS58_PREFIX).dec(\n Blake2256(\n concat([\n stringToBytes('evm:'),\n hexToBytes(normalizeEvmAddress(evmAddress)),\n ])\n )\n )\n}\n\nfunction decodeBittensorAddress(value: string): Uint8Array {\n try {\n if (typeof value !== 'string' || !value || value.startsWith('0x'))\n throw new Error('Raw hex is not SS58.')\n const info = getSs58AddressInfo(value)\n if (\n !info.isValid ||\n info.ss58Format !== BITTENSOR_SS58_PREFIX ||\n info.publicKey.length !== 32\n )\n throw new Error('Invalid Bittensor address.')\n const publicKey = info.publicKey\n return publicKey\n } catch {\n throw new ForeverMoneyError(\n 'INVALID_SS58',\n 'Expected a Bittensor SS58 address with prefix 42.'\n )\n }\n}\n\nexport function normalizeSS58(value: string): string {\n return AccountId(BITTENSOR_SS58_PREFIX).dec(decodeBittensorAddress(value))\n}\n\nexport function isBittensorSS58(value: string): boolean {\n try {\n decodeBittensorAddress(value)\n return true\n } catch {\n return false\n }\n}\n\nexport function ss58ToPublicKey(value: string): Hex {\n return bytesToHex(decodeBittensorAddress(value))\n}\n","export const ERC20_ABI = Object.freeze([\n 'function allowance(address owner,address spender) view returns (uint256)',\n 'function approve(address spender,uint256 amount) returns (bool)',\n 'function balanceOf(address account) view returns (uint256)',\n] as const)\n\nexport const STAKING_ABI = Object.freeze([\n 'function allowance(address sourceAddress,address spenderAddress,uint256 netuid) view returns (uint256)',\n 'function approve(address spenderAddress,uint256 netuid,uint256 absoluteAmount)',\n 'function getStake(bytes32 hotkey,bytes32 coldkey,uint256 netuid) view returns (uint256)',\n] as const)\n\nexport const SPOKE_GATEWAY_ABI = Object.freeze([\n 'function ROUTER() view returns (address)',\n 'function BITTENSOR_SELECTOR() view returns (uint64)',\n 'function SUBTENSOR_GATEWAY() view returns (address)',\n 'function maxIntegratorFeeBps() view returns (uint16)',\n 'function bridgeFeeBps() view returns (uint16)',\n 'function quoteBridgeToFinney(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit) view returns (uint256 fee)',\n 'function quoteBridgeToFinney(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit,uint256 gasLimit) view returns (uint256 fee)',\n 'function bridgeToFinney(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit) payable returns (bytes32 messageId)',\n 'function bridgeToFinney(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit,uint256 gasLimit) payable returns (bytes32 messageId)',\n 'function quoteBridgeToFinneyWithFee(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit,uint256 gasLimit,(address recipient,uint16 bps) integrator) view returns (uint256 fee,uint256 cut,uint256 amountCrossing)',\n 'function bridgeToFinneyWithFee(address token,uint256 amount,(bytes32 ss58,address evmFallback,bool wantLiquid,uint256 minTaoOut) exit,uint256 gasLimit,(address recipient,uint16 bps) integrator) payable returns (bytes32 messageId)',\n 'event BridgedToFinney(address indexed token,address indexed sender,bytes32 indexed ss58,uint256 amount,bytes32 messageId)',\n] as const)\n\nexport const ALPHA_GATEWAY_ABI = Object.freeze([\n 'function ROUTER() view returns (address)',\n 'function allowedLane(uint64 selector) view returns (bool)',\n 'function maxIntegratorFeeBps() view returns (uint16)',\n 'function bridgeFeeBps() view returns (uint16)',\n 'function integratorTaoTopUp(uint256 taoAmount,uint16 bps) pure returns (uint256)',\n 'function quoteBridgeOut(uint64 destSelector,address token,address recipient,uint256 mintedAmount) view returns (uint256 fee)',\n 'function bridgeOut(uint64 destSelector,address token,address recipient,uint256 taoAmount,uint256 stakedAlphaRao,uint256 minTokenOut) payable returns (bytes32 messageId)',\n 'function integratorCut(uint256 amount,uint16 bps) pure returns (uint256)',\n 'function quoteBridgeOutWithFee(uint64 destSelector,address token,address recipient,uint256 mintedAmount,uint256 taoAmount,uint256 stakedAlphaRao,(address recipient,uint16 bps) integrator) view returns (uint256 fee,uint256 nativeTopUp,uint256 alphaTopUp,uint256 amountCrossing)',\n 'function bridgeOutWithFee(uint64 destSelector,address token,address recipient,uint256 taoAmount,uint256 stakedAlphaRao,uint256 minTokenOut,(address recipient,uint16 bps) integrator) payable returns (bytes32 messageId)',\n 'function bridgeOutFromValidators(uint64 destSelector,address token,address recipient,uint256 taoAmount,(bytes32 validator,uint256 alphaRao)[] sources,uint256 minTokenOut) payable returns (bytes32 messageId)',\n 'function bridgeOutFromValidatorsWithFee(uint64 destSelector,address token,address recipient,uint256 taoAmount,(bytes32 validator,uint256 alphaRao)[] sources,uint256 minTokenOut,(address recipient,uint16 bps) integrator) payable returns (bytes32 messageId)',\n 'function MAX_STAKE_SOURCES() view returns (uint256)',\n 'function GATEWAY_COLDKEY() view returns (bytes32)',\n 'function claimLiquid(address token,uint256 minTaoOut,address to)',\n 'function claimNative(address to)',\n 'function claimStaked(address token,bytes32 destColdkey,address to)',\n 'function claimToken(address token,address to)',\n 'function claimableNative(address account) view returns (uint256)',\n 'function claimableToken(address token,address account) view returns (uint256)',\n 'event BridgedOut(uint64 destChainSelector,address indexed token,address indexed sender,address indexed recipient,uint256 minted,bytes32 messageId)',\n 'event Claimable(address indexed token,address indexed user,uint256 native,uint256 wsn)',\n 'event NotDelivered(uint64 indexed sourceChainSelector,address indexed token,uint256 amount,uint8 reason)',\n 'event DeliveredLiquid(address indexed token,bytes32 indexed ss58,uint256 taoOut)',\n 'event DeliveredStaked(address indexed token,bytes32 indexed ss58,uint256 alphaRao)',\n] as const)\n\nexport const ALPHA_VAULT_ABI = Object.freeze([\n 'function isPaused() view returns (bool)',\n 'function pausedUntil() view returns (uint256)',\n 'function isListed(address token) view returns (bool)',\n 'function backing(address token) view returns (uint256 stakedAlpha)',\n 'function positionOf(address token) view returns (bytes32 validator,uint256 netuid)',\n] as const)\n\nexport const VAULT_FACTORY_ABI = Object.freeze([\n 'function create(address owner,bytes32 associatedMiner,address akAddress,address poolManager,address poolAddress,address positionManagerImpl,(address token,uint256 amount)[] stashTokens) payable returns (address manager)',\n 'event SnLiquidityManagerCreated(address indexed manager,address indexed owner,bytes32 associatedMiner,address akAddress,address poolAddress,address poolManager,address positionManager)',\n] as const)\n\nexport const VAULT_MANAGER_ABI = Object.freeze([\n 'function claimFees(address akAddress)',\n 'function topUpAk(address akAddress,address token,uint256 amount) payable',\n 'function withdrawFromAkAndPositions(address akAddress,uint256 amount0,uint256 amount1,uint256[] decreaseTokenIds,bool unwrapETH)',\n 'function stake(address akAddress,bytes data)',\n 'function unstake(address akAddress,bytes data)',\n 'function owner() view returns (address)',\n 'event AKStashTopUp(address akAddress,address token,uint256 amount)',\n 'event AKStashWithdraw(address akAddress,address token,uint256 amount)',\n] as const)\n\nexport const CCIP_EXECUTION_ABI = Object.freeze([\n 'event ExecutionStateChanged(uint64 indexed sourceChainSelector,uint64 indexed sequenceNumber,bytes32 indexed messageId,bytes32 messageHash,uint8 state,bytes returnData,uint256 gasUsed)',\n] as const)\n\nexport const CCIP_ROUTER_ABI = Object.freeze([\n 'function isOffRamp(uint64 sourceChainSelector,address offRamp) view returns (bool)',\n] as const)\n\nexport const foreverMoneyAbis = Object.freeze({\n alphaGateway: ALPHA_GATEWAY_ABI,\n alphaVault: ALPHA_VAULT_ABI,\n ccipExecution: CCIP_EXECUTION_ABI,\n ccipRouter: CCIP_ROUTER_ABI,\n erc20: ERC20_ABI,\n spokeGateway: SPOKE_GATEWAY_ABI,\n staking: STAKING_ABI,\n vaultFactory: VAULT_FACTORY_ABI,\n vaultManager: VAULT_MANAGER_ABI,\n})\n","import {\n estimateRoundedStake,\n type StakeRoundingOptions,\n type StakeRoundingResult,\n} from './stake-rounding.js'\nimport { encodeFunctionData, parseAbi, type PublicClient } from 'viem'\nimport {\n ALPHA_GATEWAY_ABI,\n ERC20_ABI,\n SPOKE_GATEWAY_ABI,\n STAKING_ABI,\n} from '../abis/index.js'\nimport {\n normalizeEvmAddress,\n normalizeSS58,\n ss58ToPublicKey,\n} from '../core/addresses.js'\nimport {\n assertWholeRao,\n feeWithBuffer,\n gasLimitWithBuffer,\n} from '../core/amounts.js'\nimport {\n EVM_WEI_PER_RAO,\n SN80_NETUID,\n foreverMoneyDeployment,\n getForeverMoneyEvmDeployment,\n type ForeverMoneyEvmChain,\n} from '../chains/deployment.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport {\n createTransactionPlan,\n type TransactionPlan,\n type TransactionStep,\n} from '../core/plans.js'\nimport {\n assertNonNegativeAmount,\n normalizeBytes32,\n} from '../core/validation.js'\nconst erc20Abi = parseAbi(ERC20_ABI)\nconst spokeAbi = parseAbi(SPOKE_GATEWAY_ABI)\nconst alphaAbi = parseAbi(ALPHA_GATEWAY_ABI)\nconst stakingAbi = parseAbi(STAKING_ABI)\nexport const MIN_LIQUID_EVM_TO_SUBTENSOR_WEI = 10000000000000000n\nexport const MIN_LIQUID_BASE_TO_SUBTENSOR_WEI = MIN_LIQUID_EVM_TO_SUBTENSOR_WEI\n// Subtensor's minimum new stake is 2,000,000 RAO (0.002 TAO).\nexport const MIN_LIQUID_SUBTENSOR_TO_EVM_WEI = 2_000_000n * EVM_WEI_PER_RAO\n// The spoke contracts' original 300k default can no longer cover the variable\n// cost of a liquid AlphaVault exit on Subtensor. The live claim path currently\n// estimates near 2.56m; keep headroom so normal CCIP execution does not fall\n// back to a manual retry when the staking path becomes more expensive.\nexport const EVM_TO_SUBTENSOR_DESTINATION_GAS_LIMIT = 3_500_000n\nfunction resolveDestinationGasLimit(value?: bigint): bigint {\n const gasLimit = value ?? EVM_TO_SUBTENSOR_DESTINATION_GAS_LIMIT\n if (typeof gasLimit !== 'bigint' || gasLimit <= 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Destination gas limit must be a positive bigint.',\n { destinationGasLimit: String(gasLimit) }\n )\n }\n return gasLimit\n}\nexport type SubtensorDelivery = 'liquid' | 'staked'\nexport type SubtensorSource = 'liquid' | 'staked'\nexport type BridgeAsset = 'tao' | 'sn80'\n/**\n * Optional partner (integrator) fee, charged ON TOP of the bridged amount and\n * paid to `recipient` on the source chain. The full `amountWei` still crosses.\n * `bps` is in basis points (1 = 0.01%); the gateway caps it at\n * `maxIntegratorFeeBps`, which `prepare*` reads and enforces.\n */\nexport interface PartnerFee {\n readonly recipient: string\n readonly bps: number\n}\nexport const MAX_PARTNER_FEE_BPS = 10_000\n/**\n * One staked position to pull from when bridging staked alpha from Subtensor:\n * the validator hotkey the caller's stake sits on and how much of it to take.\n * The gateway re-delegates every pull to the token's canonical validator\n * before depositing, so stake with any validator can be bridged.\n */\nexport interface StakePull {\n readonly hotkey: string\n readonly amountRao: bigint\n}\n/** Gateway limit on positions per bridge (`AlphaGateway.MAX_STAKE_SOURCES`). */\nexport const MAX_STAKE_PULLS = 16\nexport interface EvmToSubtensorRequest {\n readonly evmChain: ForeverMoneyEvmChain\n readonly asset?: BridgeAsset\n readonly partnerFee?: PartnerFee\n /**\n * CCIP gas made available to the Subtensor receiver. Defaults to\n * `EVM_TO_SUBTENSOR_DESTINATION_GAS_LIMIT`; set per transaction when the\n * destination execution path needs a different budget.\n */\n readonly destinationGasLimit?: bigint\n readonly sender: string\n readonly amountWei: bigint\n readonly destination: string\n readonly delivery: SubtensorDelivery\n}\nexport interface SubtensorToEvmRequest {\n /** Opt-in read-only amount adjustment. False/omitted preserves exact input.\n * Requires named stakePulls and current balances; minAmountOutWei is never lowered.\n * Preparation may return an approval first; prepare again after it confirms.\n */\n readonly stakeRounding?: false | StakeRoundingOptions\n /** Minimum destination-token output in 18-decimal wei, after partner fees.\n * Defaults to amountWei. Must be positive and no greater than amountWei.\n * Callers choose their tolerance explicitly, including staking rounding dust.\n */\n readonly minAmountOutWei?: bigint\n readonly evmChain: ForeverMoneyEvmChain\n readonly asset?: BridgeAsset\n readonly partnerFee?: PartnerFee\n readonly sender: string\n readonly recipient: string\n readonly amountWei: bigint\n readonly source: SubtensorSource\n readonly netuid?: bigint\n /**\n * For a staked source: the positions to pull, summing to `amountWei` in\n * RAO. Omit when the stake already sits on the token's canonical validator.\n * With a partner fee, the cut is charged on top and spread across the pulls\n * in proportion to their amounts, so each position must hold its amount\n * plus its share of the cut.\n */\n readonly stakePulls?: readonly StakePull[]\n}\nexport type BaseToSubtensorRequest = Omit<EvmToSubtensorRequest, 'evmChain'>\nexport type SubtensorToBaseRequest = Omit<SubtensorToEvmRequest, 'evmChain'>\nexport interface BridgePreparation {\n /** Present when rounding was enabled. Display the returned amount and use its plan. */\n readonly stakeRounding?: StakeRoundingResult\n readonly exactNetworkFeeWei: bigint\n readonly transactionValueWei: bigint\n /**\n * Extra the sender pays for the partner fee, in the units of the source leg:\n * token wei for an EVM source, alpha (as 18-decimal wei) for a staked source,\n * TAO wei for a liquid source. Zero when no partner fee is set.\n */\n readonly partnerFeeWei: bigint\n readonly plan: TransactionPlan\n}\ninterface ResolvedPartnerFee {\n readonly recipient: `0x${string}`\n readonly bps: number\n}\nconst NO_PARTNER_FEE: ResolvedPartnerFee = {\n recipient: '0x0000000000000000000000000000000000000000',\n bps: 0,\n}\nfunction resolvePartnerFee(\n fee: PartnerFee | undefined,\n gateway: `0x${string}`\n): ResolvedPartnerFee {\n if (fee === undefined) return NO_PARTNER_FEE\n if (\n typeof fee.bps !== 'number' ||\n !Number.isInteger(fee.bps) ||\n fee.bps < 0 ||\n fee.bps > MAX_PARTNER_FEE_BPS\n ) {\n throw new ForeverMoneyError(\n 'INVALID_PARTNER_FEE',\n `Partner fee bps must be an integer between 0 and ${MAX_PARTNER_FEE_BPS}.`,\n { bps: fee.bps }\n )\n }\n if (fee.bps === 0) return NO_PARTNER_FEE\n const recipient = normalizeEvmAddress(fee.recipient)\n if (\n recipient === NO_PARTNER_FEE.recipient ||\n recipient.toLowerCase() === gateway.toLowerCase()\n ) {\n throw new ForeverMoneyError(\n 'INVALID_PARTNER_FEE',\n 'Partner fee recipient must not be the zero address or the gateway.',\n { recipient }\n )\n }\n return { recipient, bps: fee.bps }\n}\n/** `bps` of `amount`, rounded down: the extra token (spoke) or alpha (hub) pulled on top. */\nexport function partnerFeeCut(amount: bigint, bps: number): bigint {\n return (amount * BigInt(bps)) / 10_000n\n}\n/** Extra native TAO a liquid Subtensor source carries for the partner, rounded up to a whole RAO. */\nexport function partnerFeeTaoTopUp(taoAmount: bigint, bps: number): bigint {\n const raw = partnerFeeCut(taoAmount, bps)\n if (raw === 0n) return 0n\n return ((raw + EVM_WEI_PER_RAO - 1n) / EVM_WEI_PER_RAO) * EVM_WEI_PER_RAO\n}\nfunction assertPartnerFeeAllowed(fee: ResolvedPartnerFee, maxBps: number) {\n if (fee.bps > maxBps) {\n throw new ForeverMoneyError(\n 'INVALID_PARTNER_FEE',\n `Partner fee of ${fee.bps} bps exceeds the gateway maximum of ${maxBps} bps.`,\n { bps: fee.bps, maxBps }\n )\n }\n}\nfunction bridgeAsset(\n evmChain: ForeverMoneyEvmChain,\n asset: BridgeAsset = 'tao'\n) {\n if (asset !== 'tao' && asset !== 'sn80') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Asset must be \"tao\" or \"sn80\".'\n )\n }\n const evm = getForeverMoneyEvmDeployment(evmChain)\n return asset === 'sn80'\n ? {\n evmToken: evm.contracts.wrappedSn80,\n subtensorToken:\n foreverMoneyDeployment.subtensor.contracts.wrappedSn80,\n label: 'SN80',\n wrappedLabel: 'SN80',\n }\n : {\n evmToken: evm.contracts.wrappedTao,\n subtensorToken:\n foreverMoneyDeployment.subtensor.contracts.wrappedTao,\n label: 'TAO',\n wrappedLabel: 'wrapped TAO',\n }\n}\nfunction assertAssetMode(\n asset: BridgeAsset | undefined,\n mode: SubtensorSource\n): void {\n if (asset === 'sn80' && mode !== 'staked') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'SN80 bridging requires staked subnet 80 input or delivery; liquid TAO conversion is not supported.'\n )\n }\n}\nfunction sourceNetuid(input: SubtensorToEvmRequest): bigint | undefined {\n if (input.source !== 'staked') return undefined\n const netuid =\n input.netuid ?? (input.asset === 'sn80' ? SN80_NETUID : undefined)\n if (netuid === undefined) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'A netuid is required when bridging staked TAO.'\n )\n }\n assertNonNegativeAmount(netuid, 'netuid')\n if (input.asset === 'sn80' && netuid !== SN80_NETUID) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'SN80 staking approvals must use netuid 80.'\n )\n }\n return netuid\n}\n/** Resolved pulls for a staked source that names them; undefined otherwise. */\nfunction stakePullsFor(\n input: SubtensorToEvmRequest,\n amountRao: bigint\n): ResolvedStakePull[] | undefined {\n if (input.stakePulls === undefined) return undefined\n if (input.source !== 'staked') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake pulls are only valid for a staked source.'\n )\n }\n return resolveStakePulls(input.stakePulls, amountRao)\n}\nfunction minimumSubtensorOutput(input: SubtensorToEvmRequest): bigint {\n const minimum = input.minAmountOutWei ?? input.amountWei\n assertNonNegativeAmount(minimum, 'Minimum output')\n if (minimum === 0n || minimum > input.amountWei) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Minimum output must be positive and no greater than the input amount.'\n )\n }\n return minimum\n}\nfunction assertDelivery(value: unknown): asserts value is SubtensorDelivery {\n if (value !== 'liquid' && value !== 'staked') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Delivery must be \"liquid\" or \"staked\".'\n )\n }\n}\nfunction assertSource(value: unknown): asserts value is SubtensorSource {\n if (value !== 'liquid' && value !== 'staked') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Source must be \"liquid\" or \"staked\".'\n )\n }\n}\nfunction assertBaseToSubtensorAmount(\n amountWei: bigint,\n delivery: SubtensorDelivery\n): void {\n assertWholeRao(amountWei)\n if (delivery === 'liquid' && amountWei < MIN_LIQUID_EVM_TO_SUBTENSOR_WEI) {\n throw new ForeverMoneyError(\n 'AMOUNT_BELOW_MINIMUM',\n 'Liquid delivery from an EVM chain to Subtensor requires at least 0.01 TAO.',\n {\n amountWei: amountWei.toString(),\n minimumAmountWei: MIN_LIQUID_EVM_TO_SUBTENSOR_WEI.toString(),\n }\n )\n }\n}\nfunction assertSubtensorToEvmAmount(\n amountWei: bigint,\n source: SubtensorSource\n): void {\n assertWholeRao(amountWei)\n if (source === 'liquid' && amountWei < MIN_LIQUID_SUBTENSOR_TO_EVM_WEI) {\n throw new ForeverMoneyError(\n 'AMOUNT_BELOW_MINIMUM',\n 'Bridging liquid TAO from Subtensor requires at least 0.002 TAO.',\n {\n amountWei: amountWei.toString(),\n minimumAmountWei: MIN_LIQUID_SUBTENSOR_TO_EVM_WEI.toString(),\n }\n )\n }\n}\nexport interface BuildEvmToSubtensorPlanRequest extends EvmToSubtensorRequest {\n readonly allowanceWei: bigint\n readonly exactNetworkFeeWei: bigint\n readonly estimatedBridgeGas?: bigint\n}\nexport interface BuildSubtensorToEvmPlanRequest extends SubtensorToEvmRequest {\n readonly stakingAllowanceRao?: bigint\n readonly exactNetworkFeeWei: bigint\n readonly estimatedBridgeGas?: bigint\n}\nexport type BuildBaseToSubtensorPlanRequest = Omit<\n BuildEvmToSubtensorPlanRequest,\n 'evmChain'\n>\nexport type BuildSubtensorToBasePlanRequest = Omit<\n BuildSubtensorToEvmPlanRequest,\n 'evmChain'\n>\nfunction transactionStep(\n kind: TransactionStep['kind'],\n label: string,\n chainId: number,\n from: string,\n to: string,\n data: string,\n value: bigint,\n gasLimit?: bigint\n): TransactionStep {\n return {\n kind,\n label,\n transaction: {\n chainId,\n from,\n to,\n data,\n value: value.toString(),\n ...(gasLimit === undefined\n ? {}\n : { gasLimit: gasLimit.toString() }),\n },\n }\n}\ntype ExitParams = {\n ss58: `0x${string}`\n evmFallback: `0x${string}`\n wantLiquid: boolean\n minTaoOut: bigint\n}\nfunction partnerFeeSummary(\n charged: bigint,\n unit: string,\n fee: ResolvedPartnerFee\n): string {\n if (fee.bps === 0) return ''\n return ` Partner fee: ${charged} wei of ${unit} (${fee.bps} bps) on top, paid to ${fee.recipient}.`\n}\nfunction encodeSpokeBridge(\n token: `0x${string}`,\n amountWei: bigint,\n exit: ExitParams,\n destinationGasLimit: bigint,\n fee: ResolvedPartnerFee\n): `0x${string}` {\n return fee.bps === 0\n ? encodeFunctionData({\n abi: spokeAbi,\n functionName: 'bridgeToFinney',\n args: [token, amountWei, exit, destinationGasLimit],\n })\n : encodeFunctionData({\n abi: spokeAbi,\n functionName: 'bridgeToFinneyWithFee',\n args: [token, amountWei, exit, destinationGasLimit, fee],\n })\n}\ntype ResolvedStakePull = { validator: `0x${string}`; alphaRao: bigint }\n/**\n * Validate the caller's pull list against the gateway's rules: 1..16 entries,\n * unique bytes32 hotkeys, positive amounts, summing to the bridged alpha.\n */\nfunction resolveStakePulls(\n pulls: readonly StakePull[],\n amountRao: bigint\n): ResolvedStakePull[] {\n if (pulls.length === 0 || pulls.length > MAX_STAKE_PULLS) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Between 1 and ${MAX_STAKE_PULLS} stake pulls are required.`,\n { count: pulls.length }\n )\n }\n const seen = new Set<string>()\n let total = 0n\n const resolved = pulls.map((pull) => {\n const validator = normalizeBytes32(pull.hotkey, 'Stake pull hotkey')\n if (validator === `0x${'0'.repeat(64)}`) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake pull hotkey must not be zero.'\n )\n }\n const key = validator.toLowerCase()\n if (seen.has(key)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake pulls must not repeat a hotkey.',\n { hotkey: validator }\n )\n }\n seen.add(key)\n if (typeof pull.amountRao !== 'bigint' || pull.amountRao <= 0n) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Each stake pull must take a positive amount of RAO.',\n { hotkey: validator }\n )\n }\n total += pull.amountRao\n return { validator, alphaRao: pull.amountRao }\n })\n if (total !== amountRao) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake pulls must sum to the bridged amount.',\n { pulledRao: total.toString(), amountRao: amountRao.toString() }\n )\n }\n return resolved\n}\nfunction encodeHubBridge(\n destSelector: bigint,\n token: `0x${string}`,\n recipient: `0x${string}`,\n taoAmount: bigint,\n stakedAlphaRao: bigint,\n minTokenOut: bigint,\n fee: ResolvedPartnerFee,\n pulls?: ResolvedStakePull[]\n): `0x${string}` {\n if (pulls !== undefined) {\n const args = [\n destSelector,\n token,\n recipient,\n taoAmount,\n pulls,\n minTokenOut,\n ] as const\n return fee.bps === 0\n ? encodeFunctionData({\n abi: alphaAbi,\n functionName: 'bridgeOutFromValidators',\n args,\n })\n : encodeFunctionData({\n abi: alphaAbi,\n functionName: 'bridgeOutFromValidatorsWithFee',\n args: [...args, fee],\n })\n }\n const args = [\n destSelector,\n token,\n recipient,\n taoAmount,\n stakedAlphaRao,\n minTokenOut,\n ] as const\n return fee.bps === 0\n ? encodeFunctionData({\n abi: alphaAbi,\n functionName: 'bridgeOut',\n args,\n })\n : encodeFunctionData({\n abi: alphaAbi,\n functionName: 'bridgeOutWithFee',\n args: [...args, fee],\n })\n}\nasync function quoteSpokeWithFee(\n provider: PublicClient,\n gateway: `0x${string}`,\n token: `0x${string}`,\n amountWei: bigint,\n exit: ExitParams,\n destinationGasLimit: bigint,\n fee: ResolvedPartnerFee\n): Promise<bigint> {\n const maxBps = await provider.readContract({\n address: gateway,\n abi: spokeAbi,\n functionName: 'maxIntegratorFeeBps',\n })\n assertPartnerFeeAllowed(fee, maxBps)\n const [networkFee] = await provider.readContract({\n address: gateway,\n abi: spokeAbi,\n functionName: 'quoteBridgeToFinneyWithFee',\n args: [token, amountWei, exit, destinationGasLimit, fee],\n })\n return networkFee\n}\nasync function quoteHubWithFee(\n provider: PublicClient,\n gateway: `0x${string}`,\n destSelector: bigint,\n token: `0x${string}`,\n recipient: `0x${string}`,\n mintedAmount: bigint,\n taoAmount: bigint,\n stakedAlphaRao: bigint,\n fee: ResolvedPartnerFee\n): Promise<{\n networkFee: bigint\n taoTopUp: bigint\n alphaTopUpRao: bigint\n}> {\n const maxBps = await provider.readContract({\n address: gateway,\n abi: alphaAbi,\n functionName: 'maxIntegratorFeeBps',\n })\n assertPartnerFeeAllowed(fee, maxBps)\n const [networkFee, taoTopUp, alphaTopUpRao, crossing] =\n await provider.readContract({\n address: gateway,\n abi: alphaAbi,\n functionName: 'quoteBridgeOutWithFee',\n args: [\n destSelector,\n token,\n recipient,\n mintedAmount,\n taoAmount,\n stakedAlphaRao,\n fee,\n ],\n })\n // The gateway computes the same top-ups the plan builder does; a mismatch\n // means the deployed contract differs from the ABI the SDK was built for.\n if (\n crossing !== mintedAmount ||\n taoTopUp !== partnerFeeTaoTopUp(taoAmount, fee.bps) ||\n alphaTopUpRao !== partnerFeeCut(stakedAlphaRao, fee.bps)\n ) {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'The gateway partner fee quote does not match the SDK fee calculation.',\n {\n crossing: crossing.toString(),\n taoTopUp: taoTopUp.toString(),\n alphaTopUpRao: alphaTopUpRao.toString(),\n }\n )\n }\n return { networkFee, taoTopUp, alphaTopUpRao }\n}\nexport function buildEvmToSubtensorPlan(\n input: BuildEvmToSubtensorPlanRequest\n): TransactionPlan {\n const sender = normalizeEvmAddress(input.sender)\n const asset = bridgeAsset(input.evmChain, input.asset)\n assertDelivery(input.delivery)\n assertAssetMode(input.asset, input.delivery)\n assertBaseToSubtensorAmount(input.amountWei, input.delivery)\n assertNonNegativeAmount(input.allowanceWei, 'Token allowance')\n assertNonNegativeAmount(input.exactNetworkFeeWei, 'Network fee')\n const destinationGasLimit = resolveDestinationGasLimit(\n input.destinationGasLimit\n )\n const destination = normalizeSS58(input.destination)\n const exit = {\n ss58: ss58ToPublicKey(destination),\n evmFallback: sender,\n wantLiquid: input.delivery === 'liquid',\n minTaoOut: input.amountWei,\n }\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const partnerFee = resolvePartnerFee(\n input.partnerFee,\n evm.contracts.gateway\n )\n const cut = partnerFeeCut(input.amountWei, partnerFee.bps)\n const steps: TransactionStep[] = []\n if (input.allowanceWei < input.amountWei + cut) {\n steps.push(\n transactionStep(\n 'approval',\n `Approve ${asset.wrappedLabel} for the ForeverMoney gateway`,\n evm.chainId,\n sender,\n asset.evmToken,\n encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [evm.contracts.gateway, input.amountWei + cut],\n }),\n 0n\n )\n )\n }\n const value = feeWithBuffer(input.exactNetworkFeeWei)\n steps.push(\n transactionStep(\n 'transaction',\n `Bridge ${asset.wrappedLabel} from ${evm.name} to Subtensor (${input.delivery})`,\n evm.chainId,\n sender,\n evm.contracts.gateway,\n encodeSpokeBridge(\n asset.evmToken,\n input.amountWei,\n exit,\n destinationGasLimit,\n partnerFee\n ),\n value,\n input.estimatedBridgeGas === undefined\n ? undefined\n : gasLimitWithBuffer(input.estimatedBridgeGas)\n )\n )\n return createTransactionPlan({\n action:\n evm.key === 'base'\n ? 'bridge.base-to-subtensor'\n : 'bridge.robinhood-to-subtensor',\n summary: `Bridge ${input.amountWei} wei of ${asset.wrappedLabel} from ${evm.name} to ${destination}.${partnerFeeSummary(cut, asset.wrappedLabel, partnerFee)}`,\n steps,\n })\n}\nexport function buildBaseToSubtensorPlan(\n input: BuildBaseToSubtensorPlanRequest\n): TransactionPlan {\n return buildEvmToSubtensorPlan({ ...input, evmChain: 'base' })\n}\nexport function buildSubtensorToEvmPlan(\n input: BuildSubtensorToEvmPlanRequest\n): TransactionPlan {\n const sender = normalizeEvmAddress(input.sender)\n const recipient = normalizeEvmAddress(input.recipient)\n const asset = bridgeAsset(input.evmChain, input.asset)\n assertSource(input.source)\n assertAssetMode(input.asset, input.source)\n const netuid = sourceNetuid(input)\n assertSubtensorToEvmAmount(input.amountWei, input.source)\n const minAmountOutWei = minimumSubtensorOutput(input)\n assertNonNegativeAmount(input.exactNetworkFeeWei, 'Network fee')\n const { subtensor } = foreverMoneyDeployment\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const partnerFee = resolvePartnerFee(\n input.partnerFee,\n subtensor.contracts.gateway\n )\n const amountRao = input.amountWei / EVM_WEI_PER_RAO\n // Charged on top: extra alpha for a staked source, extra TAO for a liquid one.\n const alphaTopUpRao =\n input.source === 'staked'\n ? partnerFeeCut(amountRao, partnerFee.bps)\n : 0n\n const taoTopUp =\n input.source === 'liquid'\n ? partnerFeeTaoTopUp(input.amountWei, partnerFee.bps)\n : 0n\n const steps: TransactionStep[] = []\n if (input.source === 'staked') {\n if (input.stakingAllowanceRao === undefined) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'The staking allowance is required when bridging staked TAO.'\n )\n }\n assertNonNegativeAmount(input.stakingAllowanceRao, 'Staking allowance')\n if (input.stakingAllowanceRao < amountRao + alphaTopUpRao) {\n steps.push(\n transactionStep(\n 'approval',\n `Approve staked ${asset.label} for the ForeverMoney gateway`,\n subtensor.chainId,\n sender,\n subtensor.contracts.stakingPrecompile,\n encodeFunctionData({\n abi: stakingAbi,\n functionName: 'approve',\n args: [\n subtensor.contracts.gateway,\n netuid!,\n amountRao + alphaTopUpRao,\n ],\n }),\n 0n\n )\n )\n }\n } else if (\n input.netuid !== undefined ||\n input.stakingAllowanceRao !== undefined\n ) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'netuid and staking allowance are only valid for staked TAO.'\n )\n }\n const taoAmount = input.source === 'liquid' ? input.amountWei : 0n\n const stakedAlphaRao = input.source === 'staked' ? amountRao : 0n\n const pulls = stakePullsFor(input, amountRao)\n const value = taoAmount + taoTopUp + feeWithBuffer(input.exactNetworkFeeWei)\n assertNonNegativeAmount(value, 'Transaction value')\n steps.push(\n transactionStep(\n 'transaction',\n `Bridge ${input.source} ${asset.label} from Subtensor to ${evm.name}`,\n subtensor.chainId,\n sender,\n subtensor.contracts.gateway,\n encodeHubBridge(\n evm.ccipSelector,\n asset.subtensorToken,\n recipient,\n taoAmount,\n stakedAlphaRao,\n minAmountOutWei,\n partnerFee,\n pulls\n ),\n value,\n input.estimatedBridgeGas === undefined\n ? undefined\n : gasLimitWithBuffer(input.estimatedBridgeGas)\n )\n )\n return createTransactionPlan({\n action:\n evm.key === 'base'\n ? 'bridge.subtensor-to-base'\n : 'bridge.subtensor-to-robinhood',\n summary: `Bridge ${input.amountWei} wei of ${input.source} ${asset.label} from Subtensor to ${recipient} on ${evm.name}.${partnerFeeSummary(\n input.source === 'liquid'\n ? taoTopUp\n : alphaTopUpRao * EVM_WEI_PER_RAO,\n input.source === 'liquid' ? 'TAO' : `staked ${asset.label}`,\n partnerFee\n )}`,\n steps,\n })\n}\nexport function buildSubtensorToBasePlan(\n input: BuildSubtensorToBasePlanRequest\n): TransactionPlan {\n return buildSubtensorToEvmPlan({ ...input, evmChain: 'base' })\n}\nexport async function prepareEvmToSubtensor(\n provider: PublicClient,\n input: EvmToSubtensorRequest\n): Promise<BridgePreparation> {\n const sender = normalizeEvmAddress(input.sender)\n const asset = bridgeAsset(input.evmChain, input.asset)\n assertDelivery(input.delivery)\n assertAssetMode(input.asset, input.delivery)\n assertBaseToSubtensorAmount(input.amountWei, input.delivery)\n const destinationGasLimit = resolveDestinationGasLimit(\n input.destinationGasLimit\n )\n const destination = normalizeSS58(input.destination)\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const exit = {\n ss58: ss58ToPublicKey(destination),\n evmFallback: sender,\n wantLiquid: input.delivery === 'liquid',\n minTaoOut: input.amountWei,\n }\n const partnerFee = resolvePartnerFee(\n input.partnerFee,\n evm.contracts.gateway\n )\n const cut = partnerFeeCut(input.amountWei, partnerFee.bps)\n const [allowanceWei, exactNetworkFeeWei] = await Promise.all([\n provider.readContract({\n address: asset.evmToken,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [sender, evm.contracts.gateway],\n }),\n partnerFee.bps === 0\n ? provider.readContract({\n address: evm.contracts.gateway,\n abi: spokeAbi,\n functionName: 'quoteBridgeToFinney',\n args: [\n asset.evmToken,\n input.amountWei,\n exit,\n destinationGasLimit,\n ],\n })\n : quoteSpokeWithFee(\n provider,\n evm.contracts.gateway,\n asset.evmToken,\n input.amountWei,\n exit,\n destinationGasLimit,\n partnerFee\n ),\n ])\n let estimatedBridgeGas: bigint | undefined\n if (allowanceWei >= input.amountWei + cut) {\n const data = encodeSpokeBridge(\n asset.evmToken,\n input.amountWei,\n exit,\n destinationGasLimit,\n partnerFee\n )\n estimatedBridgeGas = await provider.estimateGas({\n account: sender,\n to: evm.contracts.gateway,\n data,\n value: feeWithBuffer(exactNetworkFeeWei),\n })\n }\n const plan = buildEvmToSubtensorPlan({\n ...input,\n allowanceWei,\n exactNetworkFeeWei,\n ...(estimatedBridgeGas === undefined ? {} : { estimatedBridgeGas }),\n })\n return Object.freeze({\n exactNetworkFeeWei,\n transactionValueWei: feeWithBuffer(exactNetworkFeeWei),\n partnerFeeWei: cut,\n plan,\n })\n}\nexport function prepareBaseToSubtensor(\n provider: PublicClient,\n input: BaseToSubtensorRequest\n): Promise<BridgePreparation> {\n return prepareEvmToSubtensor(provider, { ...input, evmChain: 'base' })\n}\nasync function prepareSubtensorToEvmExact(\n provider: PublicClient,\n input: SubtensorToEvmRequest\n): Promise<BridgePreparation> {\n const sender = normalizeEvmAddress(input.sender)\n const recipient = normalizeEvmAddress(input.recipient)\n const asset = bridgeAsset(input.evmChain, input.asset)\n assertSource(input.source)\n assertAssetMode(input.asset, input.source)\n const netuid = sourceNetuid(input)\n assertSubtensorToEvmAmount(input.amountWei, input.source)\n const minAmountOutWei = minimumSubtensorOutput(input)\n const { subtensor } = foreverMoneyDeployment\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const partnerFee = resolvePartnerFee(\n input.partnerFee,\n subtensor.contracts.gateway\n )\n const taoAmount = input.source === 'liquid' ? input.amountWei : 0n\n const stakedAlphaRao =\n input.source === 'staked' ? input.amountWei / EVM_WEI_PER_RAO : 0n\n const exactNetworkFeeWei =\n partnerFee.bps === 0\n ? await provider.readContract({\n address: subtensor.contracts.gateway,\n abi: alphaAbi,\n functionName: 'quoteBridgeOut',\n args: [\n evm.ccipSelector,\n asset.subtensorToken,\n recipient,\n input.amountWei,\n ],\n })\n : (\n await quoteHubWithFee(\n provider,\n subtensor.contracts.gateway,\n evm.ccipSelector,\n asset.subtensorToken,\n recipient,\n input.amountWei,\n taoAmount,\n stakedAlphaRao,\n partnerFee\n )\n ).networkFee\n let stakingAllowanceRao: bigint | undefined\n if (input.source === 'staked') {\n stakingAllowanceRao = await provider.readContract({\n address: subtensor.contracts.stakingPrecompile,\n abi: stakingAbi,\n functionName: 'allowance',\n args: [sender, subtensor.contracts.gateway, netuid!],\n })\n }\n const alphaTopUpRao = partnerFeeCut(stakedAlphaRao, partnerFee.bps)\n const taoTopUp = partnerFeeTaoTopUp(taoAmount, partnerFee.bps)\n const value = taoAmount + taoTopUp + feeWithBuffer(exactNetworkFeeWei)\n assertNonNegativeAmount(value, 'Transaction value')\n let estimatedBridgeGas: bigint | undefined\n if (\n input.source === 'liquid' ||\n (stakingAllowanceRao !== undefined &&\n stakingAllowanceRao >= stakedAlphaRao + alphaTopUpRao)\n ) {\n estimatedBridgeGas = await provider.estimateGas({\n account: sender,\n to: subtensor.contracts.gateway,\n data: encodeHubBridge(\n evm.ccipSelector,\n asset.subtensorToken,\n recipient,\n taoAmount,\n stakedAlphaRao,\n minAmountOutWei,\n partnerFee,\n stakePullsFor(input, stakedAlphaRao)\n ),\n value,\n })\n }\n const plan = buildSubtensorToEvmPlan({\n ...input,\n exactNetworkFeeWei,\n ...(stakingAllowanceRao === undefined ? {} : { stakingAllowanceRao }),\n ...(estimatedBridgeGas === undefined ? {} : { estimatedBridgeGas }),\n })\n return Object.freeze({\n exactNetworkFeeWei,\n transactionValueWei: value,\n partnerFeeWei:\n input.source === 'liquid'\n ? taoTopUp\n : alphaTopUpRao * EVM_WEI_PER_RAO,\n plan,\n })\n}\n/** Prepare an exact or explicitly rounding-adjusted plan. No transactions are sent. */\nexport async function prepareSubtensorToEvm(\n provider: PublicClient,\n input: SubtensorToEvmRequest\n): Promise<BridgePreparation> {\n const options = input.stakeRounding\n if (\n options != null &&\n options !== false &&\n typeof options.enabled !== 'boolean'\n ) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'stakeRounding.enabled must be a boolean.'\n )\n }\n if (!options || !options.enabled)\n return prepareSubtensorToEvmExact(provider, input)\n if (input.source !== 'staked' || !input.stakePulls?.length) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stake rounding requires a staked source with named stakePulls.'\n )\n }\n const minimum = minimumSubtensorOutput(input)\n const result = await estimateRoundedStake({\n amountWei: input.amountWei,\n minAmountOutWei: minimum,\n pulls: input.stakePulls,\n positions: options.positions,\n minStakeRao: options.minStakeRao ?? 0n,\n partnerFeeBps: input.partnerFee?.bps ?? 0,\n quoteAndEstimate: async (amountWei, stakePulls, minAmountOutWei) => ({\n prepared: await prepareSubtensorToEvmExact(provider, {\n ...input,\n amountWei,\n stakePulls,\n minAmountOutWei,\n stakeRounding: false,\n }),\n }),\n })\n return Object.freeze({\n ...result.prepared,\n stakeRounding: Object.freeze({\n requestedAmountWei: input.amountWei,\n amountWei: result.amountWei,\n minAmountOutWei: result.minAmountOutWei,\n pulls: result.pulls,\n simulationComplete: !result.prepared.plan.steps.some(\n (step) => step.kind === 'approval'\n ),\n }),\n })\n}\n\nexport function prepareSubtensorToBase(\n provider: PublicClient,\n input: SubtensorToBaseRequest\n): Promise<BridgePreparation> {\n return prepareSubtensorToEvm(provider, { ...input, evmChain: 'base' })\n}\n","import { keccak256, stringToBytes } from 'viem'\nimport { FOREVERMONEY_DEPLOYMENT_VERSION } from '../chains/deployment.js'\n\nexport type TransactionStepKind = 'approval' | 'transaction'\nexport type TransactionAction =\n | 'bridge.base-to-subtensor'\n | 'bridge.robinhood-to-subtensor'\n | 'bridge.subtensor-to-base'\n | 'bridge.subtensor-to-robinhood'\n | 'vault.claim-fees'\n | 'vault.create'\n | 'vault.deposit'\n | 'vault.stake'\n | 'vault.unstake'\n | 'vault.withdraw'\n\nexport interface PreparedTransaction {\n readonly chainId: number\n readonly from: string\n readonly to: string\n readonly data: string\n readonly value: string\n readonly gasLimit?: string\n}\n\nexport interface TransactionStep {\n readonly kind: TransactionStepKind\n readonly label: string\n readonly transaction: PreparedTransaction\n}\n\nexport interface TransactionPlan {\n readonly version: '1'\n readonly deploymentVersion: typeof FOREVERMONEY_DEPLOYMENT_VERSION\n readonly action: TransactionAction\n readonly summary: string\n readonly steps: readonly TransactionStep[]\n readonly hash: string\n}\n\ntype UnhashedPlan = Omit<\n TransactionPlan,\n 'deploymentVersion' | 'hash' | 'version'\n>\n\nexport function createTransactionPlan(plan: UnhashedPlan): TransactionPlan {\n const steps = plan.steps.map((step) =>\n Object.freeze({\n ...step,\n transaction: Object.freeze({ ...step.transaction }),\n })\n )\n const versionedPlan = {\n version: '1' as const,\n deploymentVersion: FOREVERMONEY_DEPLOYMENT_VERSION,\n action: plan.action,\n summary: plan.summary,\n steps: Object.freeze(steps),\n }\n return Object.freeze({\n ...versionedPlan,\n hash: keccak256(stringToBytes(JSON.stringify(versionedPlan))),\n })\n}\n","import { createPublicClient, custom, type PublicClient } from 'viem'\nimport { ForeverMoneyError } from './errors.js'\n\nexport interface RpcRequest {\n readonly method: string\n readonly params?: readonly unknown[] | Record<string, unknown>\n}\n\nexport interface RpcTransport {\n request(request: RpcRequest): Promise<unknown>\n}\n\nexport interface HttpTransportOptions {\n readonly timeoutMs?: number\n readonly fetch?: typeof globalThis.fetch\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction invalidJsonRpcResponse(): ForeverMoneyError {\n return new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC returned an invalid JSON-RPC response.'\n )\n}\n\nfunction isLoopback(endpoint: URL): boolean {\n return (\n endpoint.hostname === 'localhost' ||\n endpoint.hostname === '127.0.0.1' ||\n endpoint.hostname === '[::1]'\n )\n}\n\nfunction jsonRpcResult(body: unknown, expectedId: number): unknown {\n if (!isRecord(body) || body.jsonrpc !== '2.0' || body.id !== expectedId) {\n throw invalidJsonRpcResponse()\n }\n if (body.error !== undefined) {\n if (\n !isRecord(body.error) ||\n !Number.isInteger(body.error.code) ||\n typeof body.error.message !== 'string'\n ) {\n throw invalidJsonRpcResponse()\n }\n throw new ForeverMoneyError('RPC_ERROR', body.error.message, {\n rpcCode: body.error.code,\n ...(body.error.data === undefined\n ? {}\n : { rpcData: body.error.data }),\n })\n }\n if (!Object.prototype.hasOwnProperty.call(body, 'result')) {\n throw invalidJsonRpcResponse()\n }\n return body.result\n}\n\nexport function http(\n url: string,\n options: HttpTransportOptions = {}\n): RpcTransport {\n let endpoint: URL\n try {\n endpoint = new URL(url)\n } catch {\n throw new ForeverMoneyError('RPC_ERROR', 'RPC URL is invalid.')\n }\n if (endpoint.protocol !== 'https:' && endpoint.protocol !== 'http:') {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC URL must use HTTP or HTTPS.'\n )\n }\n if (endpoint.protocol === 'http:' && !isLoopback(endpoint)) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'Non-local RPC URLs must use HTTPS.'\n )\n }\n\n const timeoutMs = options.timeoutMs ?? 15_000\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC timeout must be a positive integer.'\n )\n }\n const fetchImplementation = options.fetch ?? globalThis.fetch\n if (typeof fetchImplementation !== 'function') {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'This runtime does not provide fetch. Pass an explicit fetch implementation.'\n )\n }\n\n let requestId = 0\n return Object.freeze({\n async request(request: RpcRequest): Promise<unknown> {\n if (\n !isRecord(request) ||\n typeof request.method !== 'string' ||\n request.method.length === 0\n ) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC method must be a non-empty string.'\n )\n }\n if (\n request.params !== undefined &&\n !Array.isArray(request.params) &&\n !isRecord(request.params)\n ) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'RPC params must be an array or object.'\n )\n }\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n const id = ++requestId\n try {\n const response = await fetchImplementation(endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id,\n method: request.method,\n params: request.params ?? [],\n }),\n signal: controller.signal,\n })\n if (!response.ok) {\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n `RPC returned HTTP ${response.status}.`,\n { status: response.status }\n )\n }\n return jsonRpcResult(await response.json(), id)\n } catch (error) {\n if (error instanceof ForeverMoneyError) throw error\n const message =\n error instanceof Error && error.name === 'AbortError'\n ? `RPC request timed out after ${timeoutMs}ms.`\n : 'RPC request failed.'\n throw new ForeverMoneyError('RPC_ERROR', message)\n } finally {\n clearTimeout(timer)\n }\n },\n })\n}\n\nexport function providerFromTransport(transport: RpcTransport): PublicClient {\n if (!transport || typeof transport.request !== 'function') {\n throw new ForeverMoneyError(\n 'MISSING_TRANSPORT',\n 'An EIP-1193-compatible RPC transport is required.'\n )\n }\n return createPublicClient({\n transport: custom(transport, { retryCount: 0 }),\n cacheTime: 0,\n batch: { multicall: false },\n })\n}\n\n/** Minimal structural interface implemented by ethers JSON-RPC providers. */\nexport interface LegacyRpcProvider {\n send(method: string, params: unknown[]): Promise<unknown>\n}\n\nexport type TrackingProvider = PublicClient | LegacyRpcProvider\n\n/** Adapt legacy providers without importing ethers or changing their RPC endpoint. */\nexport function trackingClient(provider: TrackingProvider): PublicClient {\n if (\n provider &&\n 'getChainId' in provider &&\n typeof provider.getChainId === 'function'\n )\n return provider\n if (provider && 'send' in provider && typeof provider.send === 'function') {\n return providerFromTransport({\n request: ({ method, params }) => {\n if (params !== undefined && !Array.isArray(params))\n throw new ForeverMoneyError(\n 'RPC_ERROR',\n 'Tracking RPC params must be an array.'\n )\n return provider.send(\n method,\n params === undefined\n ? []\n : [...(params as readonly unknown[])]\n )\n },\n })\n }\n throw new ForeverMoneyError(\n 'MISSING_TRANSPORT',\n 'A viem public client or JSON-RPC provider is required.'\n )\n}\n","import {\n BaseError,\n ContractFunctionRevertedError,\n ExecutionRevertedError,\n} from 'viem'\nimport { ForeverMoneyError } from './errors.js'\n\nfunction stringProperty(value: unknown, property: string): string | undefined {\n if (typeof value !== 'object' || value === null || !(property in value)) {\n return undefined\n }\n const entry = (value as Record<string, unknown>)[property]\n return typeof entry === 'string' ? entry : undefined\n}\n\nexport async function providerOperation<T>(\n operation: string,\n action: () => Promise<T>\n): Promise<T> {\n try {\n return await action()\n } catch (error) {\n if (error instanceof ForeverMoneyError) throw error\n const revert =\n error instanceof BaseError\n ? error.walk(\n (cause) =>\n cause instanceof ContractFunctionRevertedError ||\n cause instanceof ExecutionRevertedError\n )\n : undefined\n const viemRevert =\n revert instanceof ContractFunctionRevertedError ||\n revert instanceof ExecutionRevertedError\n const causeCode = viemRevert\n ? revert.name\n : stringProperty(error, 'code')\n const reason = viemRevert\n ? revert instanceof ContractFunctionRevertedError\n ? (revert.data?.errorName ?? revert.reason)\n : undefined\n : stringProperty(error, 'reason')\n const reverted = viemRevert || causeCode === 'CALL_EXCEPTION'\n throw new ForeverMoneyError(\n reverted ? 'SIMULATION_REVERTED' : 'RPC_ERROR',\n reverted ? `${operation} reverted.` : `${operation} failed.`,\n {\n ...(causeCode === undefined ? {} : { causeCode }),\n ...(reason === undefined ? {} : { reason }),\n }\n )\n }\n}\n","import {\n encodeFunctionData,\n parseAbi,\n zeroAddress,\n type Address,\n type PublicClient,\n} from 'viem'\nimport {\n ERC20_ABI,\n VAULT_FACTORY_ABI,\n VAULT_MANAGER_ABI,\n} from '../abis/index.js'\nimport { normalizeEvmAddress } from '../core/addresses.js'\nimport { foreverMoneyDeployment } from '../chains/deployment.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport {\n createTransactionPlan,\n type TransactionPlan,\n type TransactionStep,\n} from '../core/plans.js'\nimport {\n assertArray,\n assertBoolean,\n assertNonNegativeAmount,\n assertPositiveAmount,\n assertRecord,\n normalizeOptionalBytes32,\n} from '../core/validation.js'\nconst erc20Abi = parseAbi(ERC20_ABI)\nconst factoryAbi = parseAbi(VAULT_FACTORY_ABI)\nconst managerAbi = parseAbi(VAULT_MANAGER_ABI)\nexport interface VaultStashToken {\n readonly token: string\n readonly amount: bigint\n}\nexport interface CreateVaultRequest {\n readonly owner: string\n readonly associatedMiner?: string\n readonly akAddress: string\n readonly poolManager: string\n readonly poolAddress: string\n readonly positionManagerImplementation: string\n readonly stashTokens: readonly VaultStashToken[]\n}\nexport interface VaultTokenAllowance {\n readonly token: string\n readonly allowance: bigint\n}\nfunction step(\n kind: TransactionStep['kind'],\n label: string,\n from: string,\n to: string,\n data: string,\n value = 0n\n): TransactionStep {\n return {\n kind,\n label,\n transaction: {\n chainId: foreverMoneyDeployment.base.chainId,\n from,\n to,\n data,\n value: value.toString(),\n },\n }\n}\nfunction normalizeStashTokens(\n stashTokens: readonly VaultStashToken[]\n): readonly { readonly token: Address; readonly amount: bigint }[] {\n assertArray(stashTokens, 'Stash tokens')\n const seen = new Set<string>()\n return stashTokens.map((entry) => {\n assertRecord(entry, 'Stash token')\n if (typeof entry.token !== 'string') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Stash token address must be a string.'\n )\n }\n const normalizedToken = normalizeEvmAddress(entry.token)\n assertPositiveAmount(entry.amount, 'Stash amount')\n const key = normalizedToken.toLowerCase()\n if (seen.has(key)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Duplicate stash token: ${normalizedToken}.`\n )\n }\n seen.add(key)\n return Object.freeze({\n token: normalizedToken,\n amount: entry.amount,\n })\n })\n}\nfunction allowanceMap(\n allowances: readonly VaultTokenAllowance[]\n): ReadonlyMap<string, bigint> {\n assertArray(allowances, 'Token allowances')\n const result = new Map<string, bigint>()\n for (const entry of allowances) {\n assertRecord(entry, 'Token allowance')\n if (typeof entry.token !== 'string') {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Allowance token address must be a string.'\n )\n }\n const token = normalizeEvmAddress(entry.token).toLowerCase()\n assertNonNegativeAmount(entry.allowance, 'Token allowance')\n if (result.has(token)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Duplicate allowance for token ${entry.token}.`\n )\n }\n result.set(token, entry.allowance)\n }\n return result\n}\nfunction assertAllowanceSet(\n allowances: ReadonlyMap<string, bigint>,\n tokens: readonly VaultStashToken[]\n): void {\n const expected = new Set(\n tokens\n .filter(\n ({ token }) =>\n token !== foreverMoneyDeployment.base.contracts.weth\n )\n .map(({ token }) => token.toLowerCase())\n )\n for (const token of allowances.keys()) {\n if (!expected.has(token)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Unexpected allowance for token ${token}.`\n )\n }\n }\n}\nexport function buildCreateVaultPlan(\n input: CreateVaultRequest & {\n readonly allowances: readonly VaultTokenAllowance[]\n }\n): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const akAddress = normalizeEvmAddress(input.akAddress)\n const poolManager = normalizeEvmAddress(input.poolManager)\n const poolAddress = normalizeEvmAddress(input.poolAddress)\n const positionManagerImplementation = normalizeEvmAddress(\n input.positionManagerImplementation\n )\n const associatedMiner = normalizeOptionalBytes32(\n input.associatedMiner,\n 'Associated miner'\n )\n const stashTokens = normalizeStashTokens(input.stashTokens)\n const allowances = allowanceMap(input.allowances)\n assertAllowanceSet(allowances, stashTokens)\n const { base } = foreverMoneyDeployment\n const steps: TransactionStep[] = []\n let value = 0n\n for (const stash of stashTokens) {\n if (stash.token === base.contracts.weth) {\n value += stash.amount\n assertNonNegativeAmount(value, 'Vault creation value')\n continue\n }\n const allowance = allowances.get(stash.token.toLowerCase())\n if (allowance === undefined) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Missing allowance for stash token ${stash.token}.`\n )\n }\n if (allowance < stash.amount) {\n steps.push(\n step(\n 'approval',\n `Approve ${stash.token} for the vault factory`,\n owner,\n stash.token,\n encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [base.contracts.vaultFactory, stash.amount],\n })\n )\n )\n }\n }\n steps.push(\n step(\n 'transaction',\n 'Create ForeverMoney vault',\n owner,\n base.contracts.vaultFactory,\n encodeFunctionData({\n abi: factoryAbi,\n functionName: 'create',\n args: [\n owner,\n associatedMiner,\n akAddress,\n poolManager,\n poolAddress,\n positionManagerImplementation,\n stashTokens,\n ],\n }),\n value\n )\n )\n return createTransactionPlan({\n action: 'vault.create',\n summary: `Create a vault owned by ${owner} with ${stashTokens.length} initial stash token(s).`,\n steps,\n })\n}\nexport async function prepareCreateVault(\n provider: PublicClient,\n input: CreateVaultRequest\n): Promise<TransactionPlan> {\n const owner = normalizeEvmAddress(input.owner)\n const stashTokens = normalizeStashTokens(input.stashTokens)\n const erc20Stash = stashTokens.filter(\n ({ token }) => token !== foreverMoneyDeployment.base.contracts.weth\n )\n const allowances = await Promise.all(\n erc20Stash.map(async ({ token }) => ({\n token,\n allowance: await provider.readContract({\n address: token,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [\n owner,\n foreverMoneyDeployment.base.contracts.vaultFactory,\n ],\n }),\n }))\n )\n return buildCreateVaultPlan({ ...input, allowances })\n}\nexport interface DepositVaultRequest {\n readonly owner: string\n readonly manager: string\n readonly akAddress: string\n readonly deposits: readonly VaultStashToken[]\n}\nexport function buildDepositVaultPlan(\n input: DepositVaultRequest & {\n readonly allowances: readonly VaultTokenAllowance[]\n }\n): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const akAddress = normalizeEvmAddress(input.akAddress)\n const deposits = normalizeStashTokens(input.deposits)\n if (deposits.length === 0) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'At least one vault deposit is required.'\n )\n }\n const allowances = allowanceMap(input.allowances)\n assertAllowanceSet(allowances, deposits)\n const steps: TransactionStep[] = []\n for (const deposit of deposits) {\n if (deposit.token === foreverMoneyDeployment.base.contracts.weth) {\n steps.push(\n step(\n 'transaction',\n 'Deposit native ETH into the vault as WETH',\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: 'topUpAk',\n args: [akAddress, zeroAddress, deposit.amount],\n }),\n deposit.amount\n )\n )\n continue\n }\n const allowance = allowances.get(deposit.token.toLowerCase())\n if (allowance === undefined) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `Missing allowance for deposit token ${deposit.token}.`\n )\n }\n if (allowance < deposit.amount) {\n steps.push(\n step(\n 'approval',\n `Approve ${deposit.token} for the vault manager`,\n owner,\n deposit.token,\n encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [manager, deposit.amount],\n })\n )\n )\n }\n steps.push(\n step(\n 'transaction',\n `Deposit ${deposit.token} into the vault`,\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: 'topUpAk',\n args: [akAddress, deposit.token, deposit.amount],\n })\n )\n )\n }\n return createTransactionPlan({\n action: 'vault.deposit',\n summary: `Deposit ${deposits.length} token amount(s) into vault ${manager}.`,\n steps,\n })\n}\nexport async function prepareDepositVault(\n provider: PublicClient,\n input: DepositVaultRequest\n): Promise<TransactionPlan> {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const deposits = normalizeStashTokens(input.deposits)\n const erc20Deposits = deposits.filter(\n ({ token }) => token !== foreverMoneyDeployment.base.contracts.weth\n )\n const allowances = await Promise.all(\n erc20Deposits.map(async ({ token }) => ({\n token,\n allowance: await provider.readContract({\n address: token,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [owner, manager],\n }),\n }))\n )\n return buildDepositVaultPlan({ ...input, allowances })\n}\nexport interface WithdrawVaultRequest {\n readonly owner: string\n readonly manager: string\n readonly akAddress: string\n readonly amount0: bigint\n readonly amount1: bigint\n readonly decreaseTokenIds: readonly bigint[]\n readonly unwrapWeth: boolean\n}\nexport function buildWithdrawVaultPlan(\n input: WithdrawVaultRequest\n): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const akAddress = normalizeEvmAddress(input.akAddress)\n assertArray(input.decreaseTokenIds, 'Position token IDs')\n assertBoolean(input.unwrapWeth, 'unwrapWeth')\n assertNonNegativeAmount(input.amount0, 'Token 0 withdrawal')\n assertNonNegativeAmount(input.amount1, 'Token 1 withdrawal')\n if (input.amount0 === 0n && input.amount1 === 0n) {\n throw new ForeverMoneyError(\n 'AMOUNT_ZERO',\n 'At least one withdrawal amount must be greater than zero.'\n )\n }\n for (const tokenId of input.decreaseTokenIds) {\n assertNonNegativeAmount(tokenId, 'Position token ID')\n }\n return createTransactionPlan({\n action: 'vault.withdraw',\n summary: `Withdraw token amounts from vault ${manager}.`,\n steps: [\n step(\n 'transaction',\n 'Withdraw assets from the vault',\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: 'withdrawFromAkAndPositions',\n args: [\n akAddress,\n input.amount0,\n input.amount1,\n input.decreaseTokenIds,\n input.unwrapWeth,\n ],\n })\n ),\n ],\n })\n}\nexport function buildClaimVaultFeesPlan(input: {\n readonly owner: string\n readonly manager: string\n readonly akAddress: string\n}): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const akAddress = normalizeEvmAddress(input.akAddress)\n return createTransactionPlan({\n action: 'vault.claim-fees',\n summary: `Claim all fees for ${akAddress} from vault ${manager}.`,\n steps: [\n step(\n 'transaction',\n 'Claim vault fees',\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: 'claimFees',\n args: [akAddress],\n })\n ),\n ],\n })\n}\nexport function buildSetVaultStakingPlan(input: {\n readonly owner: string\n readonly manager: string\n readonly akAddress: string\n readonly staking: boolean\n}): TransactionPlan {\n const owner = normalizeEvmAddress(input.owner)\n const manager = normalizeEvmAddress(input.manager)\n const akAddress = normalizeEvmAddress(input.akAddress)\n assertBoolean(input.staking, 'staking')\n const action = input.staking ? 'stake' : 'unstake'\n return createTransactionPlan({\n action: `vault.${action}`,\n summary: `${input.staking ? 'Stake' : 'Unstake'} the active position in vault ${manager}.`,\n steps: [\n step(\n 'transaction',\n `${input.staking ? 'Stake' : 'Unstake'} the vault position`,\n owner,\n manager,\n encodeFunctionData({\n abi: managerAbi,\n functionName: action,\n args: [akAddress, '0x'],\n })\n ),\n ],\n })\n}\n","import { trackingClient, type TrackingProvider } from '../core/transport.js'\nimport {\n decodeEventLog,\n parseAbi,\n TransactionReceiptNotFoundError,\n type Hex,\n type PublicClient,\n} from 'viem'\nimport { ALPHA_GATEWAY_ABI, CCIP_EXECUTION_ABI } from '../abis/index.js'\nimport { foreverMoneyDeployment } from '../chains/deployment.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport {\n assertBridgeDirection,\n bridgeMessageIdFromReceipt,\n evmChainFromBridgeDirection,\n isEvmToSubtensorDirection,\n type BridgeDirection,\n} from './receipts.js'\nimport { getForeverMoneyEvmDeployment } from '../chains/deployment.js'\nimport { normalizeBytes32 } from '../core/validation.js'\n\nconst ccipExecutionAbi = parseAbi(CCIP_EXECUTION_ABI)\nconst alphaGatewayAbi = parseAbi(ALPHA_GATEWAY_ABI)\n\nexport type CcipDeliveryStatus = 'failure' | 'recovery' | 'success' | 'waiting'\n\nexport interface CcipDeliveryStatusRequest {\n readonly direction: BridgeDirection\n readonly messageId: string\n readonly fromBlock: number\n}\n\nexport interface CcipDeliveryCheckpoint {\n readonly direction: BridgeDirection\n readonly destinationChainId: number\n readonly fromBlock: number\n}\n\nexport type BridgeSourceTransactionStatus = 'confirmed' | 'failed' | 'pending'\n\nexport interface BridgeSourceStatusRequest {\n readonly direction: BridgeDirection\n readonly transactionHash: string\n}\n\ninterface BridgeSourceStatusBase {\n readonly direction: BridgeDirection\n readonly sourceChainId: number\n readonly transactionHash: string\n}\n\nexport type BridgeSourceStatus =\n | (BridgeSourceStatusBase & {\n readonly status: 'confirmed'\n readonly messageId: string\n })\n | (BridgeSourceStatusBase & {\n readonly status: 'failed' | 'pending'\n readonly messageId: null\n })\n\nexport function destinationChainId(direction: BridgeDirection): number {\n assertBridgeDirection(direction)\n const evm = getForeverMoneyEvmDeployment(\n evmChainFromBridgeDirection(direction)\n )\n return isEvmToSubtensorDirection(direction)\n ? foreverMoneyDeployment.subtensor.chainId\n : evm.chainId\n}\n\nexport function sourceChainId(direction: BridgeDirection): number {\n assertBridgeDirection(direction)\n const evm = getForeverMoneyEvmDeployment(\n evmChainFromBridgeDirection(direction)\n )\n return isEvmToSubtensorDirection(direction)\n ? evm.chainId\n : foreverMoneyDeployment.subtensor.chainId\n}\n\nasync function assertProviderChain(\n provider: PublicClient,\n expectedChainId: number,\n label: string\n): Promise<void> {\n const chainId = await provider.getChainId()\n if (chainId !== expectedChainId) {\n throw new ForeverMoneyError(\n 'CHAIN_MISMATCH',\n `${label} transport reported chain ID ${chainId}; expected ${expectedChainId}.`,\n {\n expectedChainId,\n actualChainId: chainId.toString(),\n }\n )\n }\n}\n\nasync function assertDestinationProvider(\n provider: PublicClient,\n direction: BridgeDirection\n): Promise<number> {\n const expectedChainId = destinationChainId(direction)\n await assertProviderChain(provider, expectedChainId, 'Bridge destination')\n return expectedChainId\n}\n\nexport async function getBridgeSourceStatus(\n provider: TrackingProvider,\n input: BridgeSourceStatusRequest\n): Promise<BridgeSourceStatus> {\n const client = trackingClient(provider)\n const expectedChainId = sourceChainId(input.direction)\n const transactionHash = normalizeBytes32(\n input.transactionHash,\n 'Transaction hash'\n )\n await assertProviderChain(client, expectedChainId, 'Bridge source')\n const receipt = await receiptOrNull(client, transactionHash)\n if (receipt === null) {\n return Object.freeze({\n direction: input.direction,\n sourceChainId: expectedChainId,\n transactionHash,\n status: 'pending',\n messageId: null,\n })\n }\n if (receipt.status === 'reverted') {\n return Object.freeze({\n direction: input.direction,\n sourceChainId: expectedChainId,\n transactionHash,\n status: 'failed',\n messageId: null,\n })\n }\n if (receipt.status !== 'success') {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'The bridge source receipt has an invalid status.'\n )\n }\n const messageId = bridgeMessageIdFromReceipt(input.direction, receipt)\n if (messageId === null) {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'The confirmed bridge source receipt does not contain its canonical gateway event.'\n )\n }\n return Object.freeze({\n direction: input.direction,\n sourceChainId: expectedChainId,\n transactionHash,\n status: 'confirmed',\n messageId,\n })\n}\n\nexport async function getCcipDeliveryCheckpoint(\n provider: TrackingProvider,\n direction: BridgeDirection\n): Promise<CcipDeliveryCheckpoint> {\n const client = trackingClient(provider)\n const expectedChainId = await assertDestinationProvider(client, direction)\n const blockNumber = await client.getBlockNumber({ cacheTime: 0 })\n const fromBlock = Number(blockNumber)\n if (!Number.isSafeInteger(fromBlock) || fromBlock < 0) {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'Bridge destination transport returned an invalid block number.'\n )\n }\n return Object.freeze({\n direction,\n destinationChainId: expectedChainId,\n fromBlock,\n })\n}\n\nexport async function getCcipDeliveryStatus(\n provider: TrackingProvider,\n input: CcipDeliveryStatusRequest\n): Promise<CcipDeliveryStatus> {\n const client = trackingClient(provider)\n const expectedChainId = destinationChainId(input.direction)\n const messageId = normalizeBytes32(input.messageId, 'CCIP message ID')\n if (!Number.isSafeInteger(input.fromBlock) || input.fromBlock < 0) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'CCIP fromBlock must be a non-negative safe integer.'\n )\n }\n await assertProviderChain(client, expectedChainId, 'Bridge destination')\n\n const evmChain = evmChainFromBridgeDirection(input.direction)\n const evm = getForeverMoneyEvmDeployment(evmChain)\n const evmToSubtensor = isEvmToSubtensorDirection(input.direction)\n const sourceSelector = evmToSubtensor\n ? evm.ccipSelector\n : foreverMoneyDeployment.subtensor.ccipSelector\n const offRamp = evmToSubtensor\n ? evmChain === 'base'\n ? foreverMoneyDeployment.subtensor.contracts.ccipOffRampFromBase\n : foreverMoneyDeployment.subtensor.contracts\n .ccipOffRampFromRobinhood\n : evm.contracts.ccipOffRampFromSubtensor\n const logs = await client.getLogs({\n address: offRamp,\n fromBlock: BigInt(input.fromBlock),\n toBlock: 'latest',\n event: ccipExecutionAbi[0],\n args: { sourceChainSelector: sourceSelector, messageId },\n strict: true,\n })\n const latest = logs.at(-1)\n if (latest === undefined) return 'waiting'\n\n const state = latest.args.state\n if (state === 3) return 'failure'\n if (state !== 2) return 'waiting'\n if (!evmToSubtensor) return 'success'\n\n const receipt = await receiptOrNull(client, latest.transactionHash!)\n if (receipt === null) {\n throw new ForeverMoneyError(\n 'INVALID_PROVIDER_RESPONSE',\n 'The CCIP execution receipt is unavailable.'\n )\n }\n const subtensorGateways = [\n ...foreverMoneyDeployment.subtensor.contracts.legacyGateways,\n foreverMoneyDeployment.subtensor.contracts.gateway,\n ]\n for (const log of receipt.logs) {\n if (\n !subtensorGateways.some(\n (gateway) => log.address.toLowerCase() === gateway.toLowerCase()\n )\n ) {\n continue\n }\n try {\n const { eventName } = decodeEventLog({\n abi: alphaGatewayAbi,\n data: log.data,\n topics: log.topics,\n })\n // V5 can report an undelivered message without a Claimable event.\n if (eventName === 'Claimable' || eventName === 'NotDelivered') {\n return 'recovery'\n }\n } catch {\n // The execution receipt can contain other gateway events.\n }\n }\n return 'success'\n}\n\nasync function receiptOrNull(provider: PublicClient, hash: Hex) {\n try {\n return await provider.getTransactionReceipt({ hash })\n } catch (error) {\n if (error instanceof TransactionReceiptNotFoundError) return null\n throw error\n }\n}\n","import { decodeEventLog, isHex, parseAbi, type Hex } from 'viem'\nimport { ALPHA_GATEWAY_ABI, SPOKE_GATEWAY_ABI } from '../abis/index.js'\nimport {\n foreverMoneyDeployment,\n getForeverMoneyEvmDeployment,\n type ForeverMoneyEvmChain,\n} from '../chains/deployment.js'\nimport { ForeverMoneyError } from '../core/errors.js'\nimport { isLogFrom, type TransactionReceiptLike } from '../core/receipts.js'\n\nexport type { ReceiptLog, TransactionReceiptLike } from '../core/receipts.js'\n\nconst alphaGatewayAbi = parseAbi(ALPHA_GATEWAY_ABI)\nconst spokeGatewayAbi = parseAbi(SPOKE_GATEWAY_ABI)\n\nexport type BridgeDirection =\n | 'base-to-subtensor'\n | 'robinhood-to-subtensor'\n | 'subtensor-to-base'\n | 'subtensor-to-robinhood'\n\nexport function assertBridgeDirection(\n value: unknown\n): asserts value is BridgeDirection {\n if (\n value !== 'base-to-subtensor' &&\n value !== 'robinhood-to-subtensor' &&\n value !== 'subtensor-to-base' &&\n value !== 'subtensor-to-robinhood'\n ) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Bridge direction must identify a canonical Base or Robinhood lane.'\n )\n }\n}\n\nexport function evmChainFromBridgeDirection(\n direction: BridgeDirection\n): ForeverMoneyEvmChain {\n assertBridgeDirection(direction)\n return direction.includes('robinhood') ? 'robinhood' : 'base'\n}\n\nexport function isEvmToSubtensorDirection(direction: BridgeDirection): boolean {\n assertBridgeDirection(direction)\n return direction.endsWith('-to-subtensor')\n}\n\nexport function bridgeMessageIdFromReceipt(\n direction: BridgeDirection,\n receipt: TransactionReceiptLike\n): string | null {\n assertBridgeDirection(direction)\n const evm = getForeverMoneyEvmDeployment(\n evmChainFromBridgeDirection(direction)\n )\n const evmToSubtensor = isEvmToSubtensorDirection(direction)\n const [addresses, contractAbi, eventName] = evmToSubtensor\n ? [\n [...evm.contracts.legacyGateways, evm.contracts.gateway],\n spokeGatewayAbi,\n 'BridgedToFinney',\n ]\n : [\n [\n ...foreverMoneyDeployment.subtensor.contracts.legacyGateways,\n foreverMoneyDeployment.subtensor.contracts.gateway,\n ],\n alphaGatewayAbi,\n 'BridgedOut',\n ]\n\n for (const log of receipt.logs) {\n if (!addresses.some((address) => isLogFrom(log, address))) continue\n try {\n const parsed = decodeEventLog({\n abi: contractAbi,\n data: log.data as Hex,\n topics: [...log.topics] as [Hex, ...Hex[]],\n })\n const messageId =\n 'messageId' in parsed.args ? parsed.args.messageId : undefined\n if (\n parsed.eventName === eventName &&\n typeof messageId === 'string' &&\n isHex(messageId, { strict: true }) &&\n messageId.length === 66 &&\n (evmToSubtensor ||\n ('destChainSelector' in parsed.args &&\n parsed.args.destChainSelector === evm.ccipSelector))\n ) {\n return messageId.toLowerCase()\n }\n } catch {\n // A receipt can contain unrelated events from the same contract.\n }\n }\n return null\n}\n","export interface ReceiptLog {\n readonly address: string\n readonly data: string\n readonly topics: readonly string[]\n}\n\nexport interface TransactionReceiptLike {\n readonly logs: readonly ReceiptLog[]\n}\n\nexport function isLogFrom(log: ReceiptLog, address: string): boolean {\n return log.address.toLowerCase() === address.toLowerCase()\n}\n","import type { PublicClient } from 'viem'\nimport {\n prepareBaseToSubtensor,\n prepareEvmToSubtensor,\n prepareSubtensorToBase,\n prepareSubtensorToEvm,\n type BaseToSubtensorRequest,\n type BridgePreparation,\n type EvmToSubtensorRequest,\n type SubtensorToBaseRequest,\n type SubtensorToEvmRequest,\n} from './bridge/plans.js'\nimport {\n BASE_CHAIN_ID,\n ROBINHOOD_CHAIN_ID,\n SUBTENSOR_CHAIN_ID,\n getForeverMoneyEvmDeployment,\n} from './chains/deployment.js'\nimport { ForeverMoneyError } from './core/errors.js'\nimport { providerFromTransport, type RpcTransport } from './core/transport.js'\nimport { providerOperation } from './core/provider-errors.js'\nimport {\n prepareCreateVault,\n prepareDepositVault,\n type CreateVaultRequest,\n type DepositVaultRequest,\n} from './vaults/plans.js'\nimport type { TransactionPlan } from './core/plans.js'\nimport {\n destinationChainId,\n getBridgeSourceStatus,\n getCcipDeliveryCheckpoint,\n getCcipDeliveryStatus,\n sourceChainId,\n type BridgeSourceStatus,\n type BridgeSourceStatusRequest,\n type CcipDeliveryCheckpoint,\n type CcipDeliveryStatus,\n type CcipDeliveryStatusRequest,\n} from './bridge/tracking.js'\nimport type { BridgeDirection } from './bridge/receipts.js'\n\nexport interface ForeverMoneyClientOptions {\n readonly transports: {\n readonly base: RpcTransport\n readonly robinhood?: RpcTransport\n readonly subtensor: RpcTransport\n }\n}\n\nexport interface ForeverMoneyClient {\n readonly bridge: {\n prepareEvmToSubtensor(\n input: EvmToSubtensorRequest\n ): Promise<BridgePreparation>\n prepareBaseToSubtensor(\n input: BaseToSubtensorRequest\n ): Promise<BridgePreparation>\n prepareSubtensorToEvm(\n input: SubtensorToEvmRequest\n ): Promise<BridgePreparation>\n prepareSubtensorToBase(\n input: SubtensorToBaseRequest\n ): Promise<BridgePreparation>\n getDeliveryCheckpoint(\n direction: BridgeDirection\n ): Promise<CcipDeliveryCheckpoint>\n getDeliveryStatus(\n input: CcipDeliveryStatusRequest\n ): Promise<CcipDeliveryStatus>\n getSourceStatus(\n input: BridgeSourceStatusRequest\n ): Promise<BridgeSourceStatus>\n }\n readonly vaults: {\n prepareCreate(input: CreateVaultRequest): Promise<TransactionPlan>\n prepareDeposit(input: DepositVaultRequest): Promise<TransactionPlan>\n }\n verifyConnections(): Promise<void>\n}\n\nasync function assertProviderChain(\n provider: PublicClient,\n expectedChainId: number,\n name: string\n): Promise<void> {\n const chainId = await providerOperation(\n `Reading the ${name} chain ID`,\n () => provider.getChainId()\n )\n if (chainId !== expectedChainId) {\n throw new ForeverMoneyError(\n 'CHAIN_MISMATCH',\n `${name} transport reported chain ID ${chainId}; expected ${expectedChainId}.`,\n {\n expectedChainId,\n actualChainId: chainId.toString(),\n }\n )\n }\n}\n\nexport function createForeverMoneyClient(\n options: ForeverMoneyClientOptions\n): ForeverMoneyClient {\n if (!options?.transports?.base || !options.transports.subtensor) {\n throw new ForeverMoneyError(\n 'MISSING_TRANSPORT',\n 'Base and Subtensor transports are required.'\n )\n }\n const baseProvider = providerFromTransport(options.transports.base)\n const subtensorProvider = providerFromTransport(\n options.transports.subtensor\n )\n const robinhoodProvider = options.transports.robinhood\n ? providerFromTransport(options.transports.robinhood)\n : undefined\n const verifyBaseConnection = async (): Promise<void> => {\n await assertProviderChain(baseProvider, BASE_CHAIN_ID, 'Base')\n }\n const verifySubtensorConnection = async (): Promise<void> => {\n await assertProviderChain(\n subtensorProvider,\n SUBTENSOR_CHAIN_ID,\n 'Subtensor'\n )\n }\n const verifyRobinhoodConnection = async (): Promise<void> => {\n if (robinhoodProvider === undefined) return\n await assertProviderChain(\n robinhoodProvider,\n ROBINHOOD_CHAIN_ID,\n 'Robinhood'\n )\n }\n const verifyConnections = async (): Promise<void> => {\n await Promise.all([\n verifyBaseConnection(),\n verifyRobinhoodConnection(),\n verifySubtensorConnection(),\n ])\n }\n const providerForChain = (chainId: number): PublicClient => {\n if (chainId === BASE_CHAIN_ID) return baseProvider\n if (chainId === SUBTENSOR_CHAIN_ID) return subtensorProvider\n if (chainId === ROBINHOOD_CHAIN_ID && robinhoodProvider !== undefined) {\n return robinhoodProvider\n }\n throw new ForeverMoneyError(\n 'MISSING_TRANSPORT',\n `A transport for chain ID ${chainId} is required for this operation.`\n )\n }\n\n return Object.freeze({\n bridge: Object.freeze({\n async prepareEvmToSubtensor(input: EvmToSubtensorRequest) {\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n const provider = providerForChain(evm.chainId)\n await assertProviderChain(provider, evm.chainId, evm.name)\n return providerOperation(\n `Preparing the ${evm.name} to Subtensor bridge`,\n () => prepareEvmToSubtensor(provider, input)\n )\n },\n async prepareBaseToSubtensor(input: BaseToSubtensorRequest) {\n await verifyBaseConnection()\n return providerOperation(\n 'Preparing the Base to Subtensor bridge',\n () => prepareBaseToSubtensor(baseProvider, input)\n )\n },\n async prepareSubtensorToEvm(input: SubtensorToEvmRequest) {\n const evm = getForeverMoneyEvmDeployment(input.evmChain)\n await verifySubtensorConnection()\n return providerOperation(\n `Preparing the Subtensor to ${evm.name} bridge`,\n () => prepareSubtensorToEvm(subtensorProvider, input)\n )\n },\n async prepareSubtensorToBase(input: SubtensorToBaseRequest) {\n await verifySubtensorConnection()\n return providerOperation(\n 'Preparing the Subtensor to Base bridge',\n () => prepareSubtensorToBase(subtensorProvider, input)\n )\n },\n async getDeliveryCheckpoint(direction: BridgeDirection) {\n const expectedChainId = destinationChainId(direction)\n const provider = providerForChain(expectedChainId)\n return providerOperation(\n 'Reading the bridge delivery checkpoint',\n () => getCcipDeliveryCheckpoint(provider, direction)\n )\n },\n async getDeliveryStatus(input: CcipDeliveryStatusRequest) {\n const expectedChainId = destinationChainId(input.direction)\n const provider = providerForChain(expectedChainId)\n return providerOperation('Reading CCIP delivery status', () =>\n getCcipDeliveryStatus(provider, input)\n )\n },\n async getSourceStatus(input: BridgeSourceStatusRequest) {\n const expectedChainId = sourceChainId(input.direction)\n const provider = providerForChain(expectedChainId)\n return providerOperation(\n 'Reading the bridge source transaction',\n () => getBridgeSourceStatus(provider, input)\n )\n },\n }),\n vaults: Object.freeze({\n async prepareCreate(input: CreateVaultRequest) {\n await verifyBaseConnection()\n return providerOperation('Preparing vault creation', () =>\n prepareCreateVault(baseProvider, input)\n )\n },\n async prepareDeposit(input: DepositVaultRequest) {\n await verifyBaseConnection()\n return providerOperation('Preparing the vault deposit', () =>\n prepareDepositVault(baseProvider, input)\n )\n },\n }),\n verifyConnections,\n })\n}\n","import { decodeEventLog, parseAbi, type Hex } from 'viem'\nimport { VAULT_FACTORY_ABI } from '../abis/index.js'\nimport { foreverMoneyDeployment } from '../chains/deployment.js'\nimport { normalizeEvmAddress } from '../core/addresses.js'\nimport { isLogFrom, type TransactionReceiptLike } from '../core/receipts.js'\n\nconst vaultFactoryAbi = parseAbi(VAULT_FACTORY_ABI)\n\nexport function vaultManagerFromCreationReceipt(\n receipt: TransactionReceiptLike\n): string | null {\n for (const log of receipt.logs) {\n if (\n !isLogFrom(log, foreverMoneyDeployment.base.contracts.vaultFactory)\n ) {\n continue\n }\n try {\n const parsed = decodeEventLog({\n abi: vaultFactoryAbi,\n data: log.data as Hex,\n topics: [...log.topics] as [Hex, ...Hex[]],\n })\n if (parsed.eventName === 'SnLiquidityManagerCreated') {\n return normalizeEvmAddress(String(parsed.args.manager))\n }\n } catch {\n // A receipt can contain unrelated events from the same contract.\n }\n }\n return null\n}\n","import {\n defineChain,\n maxUint256,\n type Address,\n type Chain,\n type Hex,\n} from 'viem'\nimport {\n BASE_CHAIN_ID,\n ROBINHOOD_CHAIN_ID,\n SUBTENSOR_CHAIN_ID,\n} from '../chains/deployment.js'\nimport { ForeverMoneyError } from './errors.js'\nimport type { PreparedTransaction } from './plans.js'\n\nexport interface Eip1193TransactionRequest {\n readonly from: string\n readonly to: string\n readonly data: string\n readonly value: string\n readonly gas?: string\n}\n\nfunction decimalQuantity(value: string, label: string): bigint {\n if (!/^(0|[1-9][0-9]*)$/.test(value)) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} must be an unsigned decimal integer.`\n )\n }\n const quantity = BigInt(value)\n if (quantity > maxUint256) {\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n `${label} exceeds uint256.`\n )\n }\n return quantity\n}\n\nfunction hexQuantity(value: bigint): string {\n return `0x${value.toString(16)}`\n}\n\nexport function toEip1193Transaction(\n transaction: PreparedTransaction\n): Eip1193TransactionRequest {\n const value = decimalQuantity(transaction.value, 'Transaction value')\n const gasLimit =\n transaction.gasLimit === undefined\n ? undefined\n : decimalQuantity(transaction.gasLimit, 'Transaction gas limit')\n\n return Object.freeze({\n from: transaction.from,\n to: transaction.to,\n data: transaction.data,\n value: hexQuantity(value),\n ...(gasLimit === undefined ? {} : { gas: hexQuantity(gasLimit) }),\n })\n}\n\nexport function toEthersTransaction(\n transaction: PreparedTransaction\n): Readonly<EthersCompatibleTransactionRequest> {\n return Object.freeze({\n chainId: transaction.chainId,\n to: transaction.to,\n data: transaction.data,\n value: decimalQuantity(transaction.value, 'Transaction value'),\n ...(transaction.gasLimit === undefined\n ? {}\n : {\n gasLimit: decimalQuantity(\n transaction.gasLimit,\n 'Transaction gas limit'\n ),\n }),\n })\n}\n\n// Structural compatibility for existing consumers; no ethers dependency.\nexport interface EthersCompatibleTransactionRequest {\n readonly chainId: number\n readonly to: string\n readonly data: string\n readonly value: bigint\n readonly gasLimit?: bigint\n}\n\nexport interface ViemTransactionRequest {\n readonly chain: Chain\n readonly account: Address\n readonly chainId: number\n readonly to: Address\n readonly data: Hex\n readonly value: bigint\n readonly gas?: bigint\n}\n\nconst transactionChains = new Map<number, Chain>(\n (\n [\n [BASE_CHAIN_ID, 'Base', 'Ether', 'ETH'],\n [ROBINHOOD_CHAIN_ID, 'Robinhood', 'Ether', 'ETH'],\n [SUBTENSOR_CHAIN_ID, 'Subtensor', 'TAO', 'TAO'],\n ] as const\n ).map(([id, name, currency, symbol]) => [\n id,\n Object.freeze(\n defineChain({\n id,\n name,\n nativeCurrency: Object.freeze({\n name: currency,\n symbol,\n decimals: 18,\n }),\n // Chain identity only. The caller retains ownership of the wallet transport.\n rpcUrls: Object.freeze({\n default: Object.freeze({ http: Object.freeze([]) }),\n }),\n })\n ),\n ])\n)\n\nexport function toViemTransaction(\n transaction: PreparedTransaction\n): Readonly<ViemTransactionRequest> {\n const chain = transactionChains.get(transaction.chainId)\n if (!chain)\n throw new ForeverMoneyError(\n 'INVALID_TRANSACTION_PLAN',\n 'Unsupported transaction chain.'\n )\n return Object.freeze({\n chain,\n account: transaction.from as Address,\n chainId: transaction.chainId,\n to: transaction.to as Address,\n data: transaction.data as Hex,\n value: decimalQuantity(transaction.value, 'Transaction value'),\n ...(transaction.gasLimit === undefined\n ? {}\n : {\n gas: decimalQuantity(\n transaction.gasLimit,\n 'Transaction gas limit'\n ),\n }),\n })\n}\n"],"mappings":"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","names":["maxUint256","maxUint256","candidatePulls","getAddress","getAddress","stringToBytes","step","stringToBytes","args","step","encodeFunctionData","parseAbi","zeroAddress","erc20Abi","parseAbi","encodeFunctionData","zeroAddress","decodeEventLog","parseAbi","isHex","parseAbi","parseAbi","isHex","parseAbi","alphaGatewayAbi","decodeEventLog","assertProviderChain","decodeEventLog","parseAbi","parseAbi","decodeEventLog","maxUint256","maxUint256"]}