{"version":3,"file":"index.mjs","names":["packageJson.name","MODULE_TYPE","PLATFORM","fetchBalances","MODULE_TYPE","getErc20ContractData","getTypedContract","TokenCacheSchema","fetchTokens","getErc20ContractData","MODULE_TYPE","PLATFORM","getMiniMetadata","getTransferCallData","MODULE_TYPE","SUBSCRIPTION_INTERVAL","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","fetchBalances","MODULE_TYPE","fetchTokens","MODULE_TYPE","PLATFORM","getMiniMetadata","getTransferCallData","MODULE_TYPE","SUBSCRIPTION_INTERVAL","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","fetchBalances","MODULE_TYPE","BigNumber","TokenCacheSchema","fetchTokens","MODULE_TYPE","PLATFORM","getMiniMetadata","getTransferCallData","MODULE_TYPE","SUBSCRIPTION_INTERVAL","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","fetchBalances","MODULE_TYPE","solAddress","address","fetchTokens","MODULE_TYPE","PLATFORM","getMiniMetadata","getTransferCallData","MODULE_TYPE","solAddress","SUBSCRIPTION_INTERVAL","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","getCacheKey","#balancesMap","#cachedArray","#cachedFilteredMirrorTokens","#cachedSumFormatter","#toArray","#storage","#valueGetter","#cachedRates","#cachedTotal","#cachedFree","#cachedReserved","#cachedLocked","#cachedTransferable","#cachedUnavailable","#cachedFeePayable","#db","#invalidateComputed","#computeRates","BigNumber","#format","#computeTotal","#computeFree","#computeReserved","#computeTransferable","#computeUnavailable","#computeFeePayable","#planck","#decimals","#tokenRates","#balances","#sum","#currency","#change24h","MINIMETADATA_VERSION","solAddress","TokenCacheSchema","fetchOnChainTokenData","solAddress","dynamicTokenMetadataCache","fetchBalances","solAddress","address","MODULE_TYPE","fetchOnChainTokenData","PLATFORM","getBalanceKey","fetchTokens","TokenCacheSchema","fetchOnChainTokenData","MODULE_TYPE","PLATFORM","getMiniMetadata","getTransferCallData","MODULE_TYPE","solAddress","SUBSCRIPTION_INTERVAL","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","solAddress","getTransferCallData","MODULE_TYPE","solAddress","solAddress","getMintDecoder","fetchBalances","solAddress","address","MODULE_TYPE","PLATFORM","fetchTokens","MODULE_TYPE","PLATFORM","getMiniMetadata","SUBSCRIPTION_INTERVAL","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","buildQueries","fetchBalances","MODULE_TYPE","buildQueries","fetchTokens","MODULE_TYPE","getMiniMetadata","MODULE_TYPE","MINIMETADATA_VERSION","getData","getTransferCallData","MODULE_TYPE","getTransferMethod","getEncodedArgs","getTransferEncodedArgs","getTransferAllEncodedArgs","getEncodedValue","subscribeBalances","buildQueries","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","fetchBalances","MODULE_TYPE","fetchTokens","MODULE_TYPE","PLATFORM","getMiniMetadata","MODULE_TYPE","MINIMETADATA_VERSION","getData","getTransferCallData","MODULE_TYPE","SUBSCRIPTION_INTERVAL","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","buildQueries","fetchBalances","MODULE_TYPE","buildQueries","fetchTokens","MODULE_TYPE","getMiniMetadata","MODULE_TYPE","MINIMETADATA_VERSION","getData","getTransferCallData","MODULE_TYPE","getTransferMethod","getEncodedArgs","getTransferEncodedArgs","getTransferAllEncodedArgs","getEncodedValue","subscribeBalances","buildQueries","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","fetchBalances","MODULE_TYPE","fetchTokens","MODULE_TYPE","getMiniMetadata","MODULE_TYPE","MINIMETADATA_VERSION","getData","getTransferCallData","MODULE_TYPE","SUBSCRIPTION_INTERVAL","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","fetchBalances","MODULE_TYPE","fetchTokens","getMiniMetadata","MODULE_TYPE","MINIMETADATA_VERSION","getTransferCallData","MODULE_TYPE","getTransferMethod","subscribeBalances","MODULE_TYPE","PLATFORM","MODULE_TYPE","PLATFORM","Enum","toHex","fetchBalances","fetchTokens","toHex","getMiniMetadata","MODULE_TYPE","MINIMETADATA_VERSION","getTransferCallData","MODULE_TYPE","subscribeBalances","fetchBalances","MODULE_TYPE","MODULE_TYPE","PLATFORM","MINIMETADATA_VERSION","CACHE","#chaindataProvider","#chainConnectors","#storageValue","#storage","#storage$","#lastLiveAt","#nextStorage"],"sources":["../src/configureBigNumber.ts","../package.json","../src/log.ts","../src/modules/evm-erc20/config.ts","../src/modules/abis/erc20BalancesAggregator.ts","../src/modules/abis/multicall.ts","../src/modules/abis/uniswapV2Pair.ts","../src/modules/shared/errors.ts","../src/modules/shared/types.ts","../src/modules/evm-erc20/fetchBalances.ts","../src/modules/evm-erc20/utils.ts","../src/modules/evm-erc20/fetchTokens.ts","../src/modules/evm-erc20/getMiniMetadata.ts","../src/modules/evm-erc20/getTransferCallData.ts","../src/types/fingerprint.ts","../src/modules/evm-erc20/subscribeBalances.ts","../src/modules/evm-erc20/module.ts","../src/types/tokens.ts","../src/modules/evm-erc20/types.ts","../src/modules/evm-native/config.ts","../src/modules/evm-native/fetchBalances.ts","../src/modules/evm-native/fetchTokens.ts","../src/modules/evm-native/getMiniMetadata.ts","../src/modules/evm-native/getTransferCallData.ts","../src/modules/evm-native/subscribeBalances.ts","../src/modules/evm-native/module.ts","../src/modules/evm-native/types.ts","../src/modules/evm-uniswapv2/config.ts","../src/modules/evm-uniswapv2/fetchBalances.ts","../src/modules/evm-uniswapv2/utils.ts","../src/modules/evm-uniswapv2/fetchTokens.ts","../src/modules/evm-uniswapv2/getMiniMetadata.ts","../src/modules/evm-uniswapv2/getTransferCallData.ts","../src/modules/evm-uniswapv2/subscribeBalances.ts","../src/modules/evm-uniswapv2/module.ts","../src/modules/evm-uniswapv2/types.ts","../src/modules/sol-native/config.ts","../src/modules/sol-native/fetchBalances.ts","../src/modules/sol-native/fetchTokens.ts","../src/modules/sol-native/getMiniMetadata.ts","../src/modules/sol-native/getTransferCallData.ts","../src/modules/sol-native/subscribeBalances.ts","../src/modules/sol-native/module.ts","../src/modules/sol-native/types.ts","../src/modules/sol-spl/config.ts","../src/modules/shared/scaleBuilderCache.ts","../src/modules/shared/buildNetworkStorageCoders.ts","../src/modules/shared/parseMetadataRpcCached.ts","../src/modules/shared/fetchRuntimeCallResult.ts","../src/modules/shared/rpcQueryPack.ts","../src/types/balances.ts","../src/types/balancetypes.ts","../src/types/minimetadatas.ts","../src/modules/shared/stabilizeBalances.ts","../src/modules/shared/utils.ts","../src/modules/shared/detectedTokens.ts","../src/modules/sol-shared/metaplexMetadata.ts","../src/modules/sol-shared/tokenAccountExists.ts","../src/modules/sol-shared/tokenDataErrors.ts","../src/modules/sol-spl/onChainTokenMetadata.ts","../src/modules/sol-spl/fetchBalances.ts","../src/modules/sol-spl/fetchTokens.ts","../src/modules/sol-spl/getMiniMetadata.ts","../src/modules/sol-spl/getTransferCallData.ts","../src/modules/sol-spl/subscribeBalances.ts","../src/modules/sol-spl/module.ts","../src/modules/sol-spl/types.ts","../src/modules/sol-token2022/config.ts","../src/modules/sol-token2022/mintExtensions.ts","../src/modules/sol-token2022/transferHook.ts","../src/modules/sol-token2022/getTransferCallData.ts","../src/modules/sol-token2022/onChainTokenMetadata.ts","../src/modules/sol-token2022/fetchBalances.ts","../src/modules/sol-token2022/fetchTokens.ts","../src/modules/sol-token2022/getMiniMetadata.ts","../src/modules/sol-token2022/subscribeBalances.ts","../src/modules/sol-token2022/module.ts","../src/modules/sol-token2022/types.ts","../src/modules/substrate-assets/config.ts","../src/modules/substrate-assets/buildQueries.ts","../src/modules/substrate-assets/fetchBalances.ts","../src/modules/substrate-assets/fetchTokens.ts","../src/modules/substrate-assets/getMiniMetadata.ts","../src/modules/substrate-assets/getTransferCallData.ts","../src/modules/substrate-assets/subscribeBalances.ts","../src/modules/substrate-assets/module.ts","../src/modules/substrate-assets/types.ts","../src/modules/substrate-dtao/alphaPrice.ts","../src/modules/substrate-dtao/convictionLocks.ts","../src/modules/substrate-dtao/config.ts","../src/modules/substrate-dtao/calculatePendingRootClaimable.ts","../src/modules/substrate-dtao/fetchBalances.ts","../src/modules/substrate-dtao/fetchTokens.ts","../src/modules/substrate-dtao/getMiniMetadata.ts","../src/modules/substrate-dtao/getTransferCallData.ts","../src/modules/substrate-dtao/isEffectivelyEqualDTaoBalance.ts","../src/modules/substrate-dtao/subscribeBalances.ts","../src/modules/substrate-dtao/module.ts","../src/modules/substrate-dtao/types.ts","../src/modules/substrate-foreignassets/config.ts","../src/modules/substrate-foreignassets/buildQueries.ts","../src/modules/substrate-foreignassets/fetchBalances.ts","../src/modules/substrate-foreignassets/fetchTokens.ts","../src/modules/substrate-foreignassets/getMiniMetadata.ts","../src/modules/substrate-foreignassets/getTransferCallData.ts","../src/modules/substrate-foreignassets/subscribeBalances.ts","../src/modules/substrate-foreignassets/module.ts","../src/modules/substrate-foreignassets/types.ts","../src/modules/substrate-hydration/config.ts","../src/modules/substrate-hydration/fetchBalances.ts","../src/modules/substrate-hydration/fetchTokens.ts","../src/modules/substrate-hydration/getMiniMetadata.ts","../src/modules/substrate-hydration/getTransferCallData.ts","../src/modules/substrate-hydration/subscribeBalances.ts","../src/modules/substrate-hydration/module.ts","../src/modules/substrate-hydration/types.ts","../src/modules/substrate-native/config.ts","../src/modules/substrate-native/util/lockTypes.ts","../src/modules/substrate-native/queries/buildBaseQueries.ts","../src/modules/substrate-native/util/nompoolAccountId.ts","../src/modules/substrate-native/queries/buildNomPoolQueries.ts","../src/modules/substrate-native/fetchBalances.ts","../src/modules/substrate-native/fetchTokens.ts","../src/modules/substrate-native/getMiniMetadata.ts","../src/modules/substrate-native/getTransferCallData.ts","../src/modules/substrate-native/subscribeBalances.ts","../src/modules/substrate-native/module.ts","../src/modules/substrate-native/types.ts","../src/modules/substrate-psp22/config.ts","../src/modules/abis/psp22.json","../src/modules/substrate-psp22/util.ts","../src/modules/substrate-psp22/fetchBalances.ts","../src/modules/substrate-psp22/fetchTokens.ts","../src/modules/substrate-psp22/getMiniMetadata.ts","../src/modules/substrate-psp22/getTransferCallData.ts","../src/modules/substrate-psp22/subscribeBalances.ts","../src/modules/substrate-psp22/module.ts","../src/modules/substrate-psp22/types.ts","../src/modules/substrate-tokens/config.ts","../src/modules/substrate-tokens/buildQueries.ts","../src/modules/substrate-tokens/fetchBalances.ts","../src/modules/substrate-tokens/fetchTokens.ts","../src/modules/substrate-tokens/getMiniMetadata.ts","../src/modules/substrate-tokens/getTransferCallData.ts","../src/modules/substrate-tokens/subscribeBalances.ts","../src/modules/substrate-tokens/module.ts","../src/modules/substrate-tokens/types.ts","../src/modules/index.ts","../src/getMiniMetadatas/getMetadataRpc.ts","../src/getMiniMetadatas/getSpecVersion.ts","../src/getMiniMetadatas/index.ts","../src/BalancesProvider.ts"],"sourcesContent":["import BigNumber from \"bignumber.js\"\n\n// bignumber.js v10+ throws on invalid input by default (the STRICT option).\n// Restore the v9 behaviour of returning NaN so existing callers are unaffected.\n// The bignumber.js config is a shared singleton, so this applies process-wide.\n// Import BigNumber from here (rather than directly from \"bignumber.js\") to\n// guarantee this config has run before any value is constructed.\nBigNumber.set({ STRICT: false })\n\nexport default BigNumber\n","","import anylogger from \"anylogger\"\n\nimport packageJson from \"../package.json\"\n\nexport default anylogger(packageJson.name)\n","import { EvmErc20TokenSchema } from \"@talismn/chaindata-provider\"\n\nexport const MODULE_TYPE = EvmErc20TokenSchema.shape.type.value\nexport const PLATFORM = EvmErc20TokenSchema.shape.platform.value\n\nexport type { EvmErc20TokenConfig as TokenConfig } from \"./types\"\n","import { parseAbi } from \"viem\"\n\nexport const erc20BalancesAggregatorAbi = parseAbi([\n  \"struct AccountToken {address account; address token;}\",\n  \"function balances(AccountToken[] memory accountTokens) public view returns (uint256[] memory)\",\n] as const)\n","import { parseAbi } from \"viem\"\n\nexport const abiMulticall = parseAbi([\n  \"struct Call { address target; bytes callData; }\",\n  \"struct Call3 { address target; bool allowFailure; bytes callData; }\",\n  \"struct Call3Value { address target; bool allowFailure; uint256 value; bytes callData; }\",\n  \"struct Result { bool success; bytes returnData; }\",\n  \"function aggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes[] memory returnData)\",\n  \"function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData)\",\n  \"function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData)\",\n  \"function blockAndAggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData)\",\n  \"function getBasefee() view returns (uint256 basefee)\",\n  \"function getBlockHash(uint256 blockNumber) view returns (bytes32 blockHash)\",\n  \"function getBlockNumber() view returns (uint256 blockNumber)\",\n  \"function getChainId() view returns (uint256 chainid)\",\n  \"function getCurrentBlockCoinbase() view returns (address coinbase)\",\n  \"function getCurrentBlockDifficulty() view returns (uint256 difficulty)\",\n  \"function getCurrentBlockGasLimit() view returns (uint256 gaslimit)\",\n  \"function getCurrentBlockTimestamp() view returns (uint256 timestamp)\",\n  \"function getEthBalance(address addr) view returns (uint256 balance)\",\n  \"function getLastBlockHash() view returns (bytes32 blockHash)\",\n  \"function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData)\",\n  \"function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData)\",\n] as const)\n","export const uniswapV2PairAbi = [\n  {\n    anonymous: false,\n    inputs: [\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"owner\",\n        type: \"address\",\n      },\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"spender\",\n        type: \"address\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"value\",\n        type: \"uint256\",\n      },\n    ],\n    name: \"Approval\",\n    type: \"event\",\n  },\n  {\n    anonymous: false,\n    inputs: [\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"sender\",\n        type: \"address\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"amount0\",\n        type: \"uint256\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"amount1\",\n        type: \"uint256\",\n      },\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n    ],\n    name: \"Burn\",\n    type: \"event\",\n  },\n  {\n    anonymous: false,\n    inputs: [\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"sender\",\n        type: \"address\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"amount0\",\n        type: \"uint256\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"amount1\",\n        type: \"uint256\",\n      },\n    ],\n    name: \"Mint\",\n    type: \"event\",\n  },\n  {\n    anonymous: false,\n    inputs: [\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"sender\",\n        type: \"address\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"amount0In\",\n        type: \"uint256\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"amount1In\",\n        type: \"uint256\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"amount0Out\",\n        type: \"uint256\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"amount1Out\",\n        type: \"uint256\",\n      },\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n    ],\n    name: \"Swap\",\n    type: \"event\",\n  },\n  {\n    anonymous: false,\n    inputs: [\n      {\n        indexed: false,\n        internalType: \"uint112\",\n        name: \"reserve0\",\n        type: \"uint112\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint112\",\n        name: \"reserve1\",\n        type: \"uint112\",\n      },\n    ],\n    name: \"Sync\",\n    type: \"event\",\n  },\n  {\n    anonymous: false,\n    inputs: [\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"from\",\n        type: \"address\",\n      },\n      {\n        indexed: true,\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n      {\n        indexed: false,\n        internalType: \"uint256\",\n        name: \"value\",\n        type: \"uint256\",\n      },\n    ],\n    name: \"Transfer\",\n    type: \"event\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"DOMAIN_SEPARATOR\",\n    outputs: [\n      {\n        internalType: \"bytes32\",\n        name: \"\",\n        type: \"bytes32\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"MINIMUM_LIQUIDITY\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"pure\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"PERMIT_TYPEHASH\",\n    outputs: [\n      {\n        internalType: \"bytes32\",\n        name: \"\",\n        type: \"bytes32\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"pure\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"owner\",\n        type: \"address\",\n      },\n      {\n        internalType: \"address\",\n        name: \"spender\",\n        type: \"address\",\n      },\n    ],\n    name: \"allowance\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"spender\",\n        type: \"address\",\n      },\n      {\n        internalType: \"uint256\",\n        name: \"value\",\n        type: \"uint256\",\n      },\n    ],\n    name: \"approve\",\n    outputs: [\n      {\n        internalType: \"bool\",\n        name: \"\",\n        type: \"bool\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"owner\",\n        type: \"address\",\n      },\n    ],\n    name: \"balanceOf\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n    ],\n    name: \"burn\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"amount0\",\n        type: \"uint256\",\n      },\n      {\n        internalType: \"uint256\",\n        name: \"amount1\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"decimals\",\n    outputs: [\n      {\n        internalType: \"uint8\",\n        name: \"\",\n        type: \"uint8\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"pure\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"factory\",\n    outputs: [\n      {\n        internalType: \"address\",\n        name: \"\",\n        type: \"address\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"getReserves\",\n    outputs: [\n      {\n        internalType: \"uint112\",\n        name: \"reserve0\",\n        type: \"uint112\",\n      },\n      {\n        internalType: \"uint112\",\n        name: \"reserve1\",\n        type: \"uint112\",\n      },\n      {\n        internalType: \"uint32\",\n        name: \"blockTimestampLast\",\n        type: \"uint32\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"\",\n        type: \"address\",\n      },\n      {\n        internalType: \"address\",\n        name: \"\",\n        type: \"address\",\n      },\n    ],\n    name: \"initialize\",\n    outputs: [],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"kLast\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n    ],\n    name: \"mint\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"liquidity\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"name\",\n    outputs: [\n      {\n        internalType: \"string\",\n        name: \"\",\n        type: \"string\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"pure\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"owner\",\n        type: \"address\",\n      },\n    ],\n    name: \"nonces\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"owner\",\n        type: \"address\",\n      },\n      {\n        internalType: \"address\",\n        name: \"spender\",\n        type: \"address\",\n      },\n      {\n        internalType: \"uint256\",\n        name: \"value\",\n        type: \"uint256\",\n      },\n      {\n        internalType: \"uint256\",\n        name: \"deadline\",\n        type: \"uint256\",\n      },\n      {\n        internalType: \"uint8\",\n        name: \"v\",\n        type: \"uint8\",\n      },\n      {\n        internalType: \"bytes32\",\n        name: \"r\",\n        type: \"bytes32\",\n      },\n      {\n        internalType: \"bytes32\",\n        name: \"s\",\n        type: \"bytes32\",\n      },\n    ],\n    name: \"permit\",\n    outputs: [],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"price0CumulativeLast\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"price1CumulativeLast\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n    ],\n    name: \"skim\",\n    outputs: [],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"uint256\",\n        name: \"amount0Out\",\n        type: \"uint256\",\n      },\n      {\n        internalType: \"uint256\",\n        name: \"amount1Out\",\n        type: \"uint256\",\n      },\n      {\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n      {\n        internalType: \"bytes\",\n        name: \"data\",\n        type: \"bytes\",\n      },\n    ],\n    name: \"swap\",\n    outputs: [],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"symbol\",\n    outputs: [\n      {\n        internalType: \"string\",\n        name: \"\",\n        type: \"string\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"pure\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [],\n    name: \"sync\",\n    outputs: [],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"token0\",\n    outputs: [\n      {\n        internalType: \"address\",\n        name: \"\",\n        type: \"address\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"token1\",\n    outputs: [\n      {\n        internalType: \"address\",\n        name: \"\",\n        type: \"address\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: true,\n    inputs: [],\n    name: \"totalSupply\",\n    outputs: [\n      {\n        internalType: \"uint256\",\n        name: \"\",\n        type: \"uint256\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"view\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n      {\n        internalType: \"uint256\",\n        name: \"value\",\n        type: \"uint256\",\n      },\n    ],\n    name: \"transfer\",\n    outputs: [\n      {\n        internalType: \"bool\",\n        name: \"\",\n        type: \"bool\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n  {\n    constant: false,\n    inputs: [\n      {\n        internalType: \"address\",\n        name: \"from\",\n        type: \"address\",\n      },\n      {\n        internalType: \"address\",\n        name: \"to\",\n        type: \"address\",\n      },\n      {\n        internalType: \"uint256\",\n        name: \"value\",\n        type: \"uint256\",\n      },\n    ],\n    name: \"transferFrom\",\n    outputs: [\n      {\n        internalType: \"bool\",\n        name: \"\",\n        type: \"bool\",\n      },\n    ],\n    payable: false,\n    stateMutability: \"nonpayable\",\n    type: \"function\",\n  },\n] as const\n","import type { TokenId } from \"@talismn/chaindata-provider\"\n\nimport type { Address } from \"../../types\"\n\nexport class BalanceFetchError extends Error {\n  tokenId: TokenId\n  address: Address\n\n  constructor(message: string, tokenId: TokenId, address: Address, cause?: Error) {\n    super(message)\n    this.name = \"BalanceFetchError\"\n    this.tokenId = tokenId\n    this.address = address\n    if (cause) this.cause = cause\n  }\n}\nexport class BalanceFetchNetworkError extends Error {\n  evmNetworkId: string | undefined\n\n  constructor(message: string, evmNetworkId?: string, cause?: Error) {\n    super(message)\n    this.name = \"BalanceFetchNetworkError\"\n    this.evmNetworkId = evmNetworkId\n    if (cause) this.cause = cause\n  }\n}\n","import type { TokenOfType, TokenType } from \"@talismn/chaindata-provider\"\n\nimport type { TokenPlatform, TokensWithAddresses } from \"../../types/IBalanceModule\"\n\nexport type BalanceDef<T extends TokenType = TokenType> = {\n  token: TokenOfType<T>\n  address: TokenPlatform<T> extends \"ethereum\" ? `0x${string}` : string\n}\n\nexport const getBalanceDefs = <T extends TokenType = TokenType>(\n  addressesByToken: TokensWithAddresses\n): BalanceDef<T>[] => {\n  return addressesByToken.flatMap(([token, addresses]) =>\n    addresses.map((address) => ({ token, address }))\n  ) as BalanceDef<T>[]\n}\n\n// esponse of getStorageAt queries:\n// if there is at least one storage entry, the results will be an array with a single object\n// if the storage has no entries in it (ex: Assets on ewx or moonbeam), the response will be an empty array\nexport type QueryStorageChange = [stateKey: `0x${string}`, value: `0x${string}`]\nexport type QueryStorageResult = [{ block: `0x${string}`; changes: QueryStorageChange[] }] | []\n","import { parseEvmErc20TokenId, parseTokenId } from \"@talismn/chaindata-provider\"\nimport { isEthereumAddress } from \"@talismn/crypto\"\nimport { type ChainContract, erc20Abi, type PublicClient } from \"viem\"\n\nimport type { IBalance } from \"../../types\"\nimport type {\n  FetchBalanceErrors,\n  FetchBalanceResults,\n  IBalanceModule,\n} from \"../../types/IBalanceModule\"\nimport { erc20BalancesAggregatorAbi } from \"../abis\"\nimport { BalanceFetchError, BalanceFetchNetworkError } from \"../shared/errors\"\nimport { type BalanceDef, getBalanceDefs } from \"../shared/types\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const client = await connector.getPublicClientForEvmNetwork(networkId)\n  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`)\n\n  for (const [token, addresses] of tokensWithAddresses) {\n    if (token.type !== MODULE_TYPE || token.networkId !== networkId)\n      throw new Error(\n        `Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`\n      )\n\n    for (const address of addresses)\n      if (!isEthereumAddress(address))\n        throw new Error(\n          `Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`\n        )\n  }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  if (client.chain?.contracts?.erc20Aggregator && balanceDefs.length > 1) {\n    const erc20Aggregator = client.chain.contracts.erc20Aggregator as ChainContract\n    return fetchWithAggregator(client, balanceDefs, erc20Aggregator.address)\n  }\n\n  return fetchWithoutAggregator(client, balanceDefs)\n}\n\nconst fetchWithoutAggregator = async (\n  client: PublicClient,\n  balanceDefs: BalanceDef<typeof MODULE_TYPE>[]\n): Promise<FetchBalanceResults> => {\n  if (balanceDefs.length === 0) return { success: [], errors: [] }\n\n  const results = await Promise.allSettled(\n    balanceDefs.map(async ({ token, address }) => {\n      try {\n        const result = await client.readContract({\n          abi: erc20Abi,\n          address: token.contractAddress,\n          functionName: \"balanceOf\",\n          args: [address],\n        })\n\n        const balance: IBalance = {\n          address,\n          tokenId: token.id,\n          value: result.toString(),\n          source: MODULE_TYPE,\n          networkId: parseEvmErc20TokenId(token.id).networkId,\n          status: \"live\",\n        }\n\n        return balance\n      } catch (err) {\n        throw new BalanceFetchError(\n          `Failed to get balance for token ${token.id} and address ${address} on chain ${client.chain?.id}`,\n          token.id,\n          address,\n          err as Error\n        )\n      }\n    })\n  )\n\n  return results.reduce<FetchBalanceResults>(\n    (acc, result) => {\n      if (result.status === \"fulfilled\") acc.success.push(result.value as IBalance)\n      else {\n        const error = result.reason as BalanceFetchError\n        acc.errors.push({\n          tokenId: error.tokenId,\n          address: error.address,\n          error,\n        })\n      }\n      return acc\n    },\n    { success: [], errors: [] }\n  )\n}\n\nconst fetchWithAggregator = async (\n  client: PublicClient,\n  balanceDefs: BalanceDef<typeof MODULE_TYPE>[],\n  erc20BalancesAggregatorAddress: `0x${string}`\n): Promise<FetchBalanceResults> => {\n  if (balanceDefs.length === 0) return { success: [], errors: [] }\n\n  try {\n    const erc20Balances = await client.readContract({\n      abi: erc20BalancesAggregatorAbi,\n      address: erc20BalancesAggregatorAddress,\n      functionName: \"balances\",\n      args: [\n        balanceDefs.map((b) => ({\n          account: b.address,\n          token: b.token.contractAddress,\n        })),\n      ],\n    })\n\n    const success = balanceDefs.map(\n      (balanceDef, index): IBalance => ({\n        address: balanceDef.address,\n        tokenId: balanceDef.token.id,\n        value: erc20Balances[index].toString(),\n        source: MODULE_TYPE,\n        networkId: parseTokenId(balanceDef.token.id).networkId,\n        status: \"live\",\n      })\n    )\n    return { success, errors: [] }\n  } catch (err) {\n    const errors = balanceDefs.map((balanceDef): FetchBalanceErrors[number] => ({\n      tokenId: balanceDef.token.id,\n      address: balanceDef.address,\n      error: new BalanceFetchNetworkError(\n        `Failed to get balances for evm-erc20 tokens on chain ${client.chain?.id}`,\n        String(client.chain?.id),\n        err as Error\n      ),\n    }))\n    return { success: [], errors }\n  }\n}\n","import { isErrorOfName } from \"@talismn/util\"\nimport { type Abi, type Client, erc20Abi, erc20Abi_bytes32, getContract, hexToString } from \"viem\"\n\nexport const getErc20ContractData = async (\n  client: Client,\n  contractAddress: `0x${string}`\n): Promise<{ symbol: string; decimals: number; name: string }> => {\n  try {\n    const contract = getTypedContract(client, erc20Abi, contractAddress)\n\n    // biome-ignore lint/correctness/noInnerDeclarations: legacy\n    // biome-ignore lint/correctness/noUnusedVariables: legacy\n    var [symbol, decimals, name] = await Promise.all([\n      contract.read.symbol(),\n      contract.read.decimals(),\n      contract.read.name(),\n    ])\n  } catch (e) {\n    if (isErrorOfName(e, \"ContractFunctionExecutionError\")) {\n      // try to perform the contract read with bytes32 symbol\n      const contract = getTypedContract(client, erc20Abi_bytes32, contractAddress)\n\n      // biome-ignore lint/correctness/noInnerDeclarations: legacy\n      // biome-ignore lint/suspicious/noRedeclare: legacy\n      var [bytesSymbol, decimals, nameSymbol] = await Promise.all([\n        contract.read.symbol(),\n        contract.read.decimals(),\n        contract.read.name(),\n      ])\n      symbol = hexToString(bytesSymbol).replace(/\\0/g, \"\").trim() // remove NULL characters\n      name = hexToString(nameSymbol).replace(/\\0/g, \"\").trim() // remove NULL characters\n    } else throw e\n  }\n\n  return { symbol, decimals, name }\n}\n\nconst getTypedContract = <TAbi extends Abi>(\n  client: Client,\n  abi: TAbi,\n  contractAddress: `0x${string}`\n) =>\n  getContract({\n    address: contractAddress,\n    abi,\n    client: { public: client },\n  })\n","import {\n  type EvmErc20Token,\n  EvmErc20TokenSchema,\n  evmErc20TokenId,\n} from \"@talismn/chaindata-provider\"\nimport { assign, omit } from \"lodash-es\"\nimport type { BaseError } from \"viem\"\nimport z from \"zod/v4\"\n\nimport log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { getErc20ContractData } from \"./utils\"\n\nconst TokenCacheSchema = z.discriminatedUnion(\"isValid\", [\n  z.strictObject({\n    id: EvmErc20TokenSchema.shape.id,\n    isValid: z.literal(true),\n    ...EvmErc20TokenSchema.pick({ symbol: true, decimals: true, name: true }).shape,\n  }),\n  z.strictObject({\n    id: EvmErc20TokenSchema.shape.id,\n    isValid: z.literal(false),\n  }),\n])\n\ntype CachedToken = z.infer<typeof TokenCacheSchema>\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  connector,\n  cache,\n}) => {\n  const result: EvmErc20Token[] = []\n\n  for (const tokenConfig of tokens) {\n    const tokenId = evmErc20TokenId(networkId, tokenConfig.contractAddress)\n    const cached = (cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data) as\n      | CachedToken\n      | undefined\n\n    if (!cached) {\n      const client = await connector.getPublicClientForEvmNetwork(networkId)\n      if (!client) {\n        log.warn(`No client found for network ${networkId} while fetching EVM ERC20 tokens`)\n        continue\n      }\n\n      try {\n        const { name, decimals, symbol } = await getErc20ContractData(\n          client,\n          tokenConfig.contractAddress\n        )\n\n        cache[tokenId] = TokenCacheSchema.parse({\n          id: tokenId,\n          symbol,\n          decimals,\n          name,\n          isValid: true,\n        })\n      } catch (err) {\n        const msg = (err as BaseError).shortMessage\n        if (\n          msg.includes(\"returned no data\") ||\n          msg.includes(\"is out of bounds\") ||\n          msg.includes(\"reverted\")\n        )\n          cache[tokenId] = { id: tokenId, isValid: false }\n        else\n          log.warn(\n            `Failed to fetch ERC20 token data for ${networkId}:${tokenConfig.contractAddress}`,\n            (err as BaseError).shortMessage\n          )\n        continue\n      }\n    }\n\n    const base: Pick<EvmErc20Token, \"id\" | \"type\" | \"networkId\" | \"platform\"> = {\n      id: tokenId,\n      type: MODULE_TYPE,\n      platform: PLATFORM,\n      networkId,\n    }\n\n    const cached2 = (cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data) as\n      | CachedToken\n      | undefined\n\n    if (cached2?.isValid === false) continue\n\n    const token = assign(\n      base,\n      cached2?.isValid ? omit(cached2, [\"isValid\"]) : {},\n      tokenConfig\n    ) as EvmErc20Token\n\n    const parsed = EvmErc20TokenSchema.safeParse(token)\n    if (!parsed.success) {\n      log.warn(\"Ignoring token with invalid EvmErc20TokenSchema\", {\n        token,\n      })\n      continue\n    }\n\n    result.push(parsed.data)\n  }\n\n  return result\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = () => {\n  throw new Error(\"MiniMetadata is not supported for ethereum tokens\")\n}\n","import { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport { isEthereumAddress } from \"@talismn/crypto\"\nimport { encodeFunctionData, erc20Abi } from \"viem\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n  if (!isEthereumAddress(from)) throw new Error(\"Invalid from address\")\n  if (!isEthereumAddress(to)) throw new Error(\"Invalid to address\")\n\n  const data = encodeFunctionData({\n    abi: erc20Abi,\n    functionName: \"transfer\",\n    args: [to, BigInt(value)],\n  })\n\n  return { from, to: token.contractAddress, data }\n}\n","import type { BalancesResult } from \"../BalancesProvider\"\nimport type { IBalance, MiniMetadata } from \".\"\nimport type { FetchBalanceResults } from \"./IBalanceModule\"\n\n/**\n * Cheap change-detection for the high-frequency balance pipelines, replacing lodash\n * `isEqual` deep walks that previously ran on every block/poll emission at several\n * stacked pipeline stages.\n *\n * Each freshly-decoded balance object is serialized ONCE (WeakMap-cached JSON.stringify),\n * then every comparison against it — at the module stage, the network stage and the\n * aggregate stage — is a string compare against the cached fingerprint of the previous\n * emission's objects (already cached from their own emission).\n */\n\nconst fingerprints = new WeakMap<IBalance, string>()\n\n/** WeakMap-cached JSON serialization of a balance */\nexport const getBalanceFingerprint = (balance: IBalance): string => {\n  let fingerprint = fingerprints.get(balance)\n  if (fingerprint === undefined) {\n    fingerprint = JSON.stringify(balance)\n    fingerprints.set(balance, fingerprint)\n  }\n  return fingerprint\n}\n\nconst storageFingerprints = new WeakMap<IBalance, string>()\n\n/**\n * Status-agnostic variant: stored balances carry status \"cache\" while fresh results carry\n * \"live\", so comparisons between incoming results and stored entries must ignore status.\n */\nexport const getBalanceStorageFingerprint = (balance: IBalance): string => {\n  let fingerprint = storageFingerprints.get(balance)\n  if (fingerprint === undefined) {\n    fingerprint = JSON.stringify({ ...balance, status: undefined })\n    storageFingerprints.set(balance, fingerprint)\n  }\n  return fingerprint\n}\n\nexport const isEqualBalanceArrays = (a: IBalance[], b: IBalance[]): boolean => {\n  if (a === b) return true\n  if (a.length !== b.length) return false\n  for (let i = 0; i < a.length; i++) {\n    if (a[i] !== b[i] && getBalanceFingerprint(a[i]) !== getBalanceFingerprint(b[i])) return false\n  }\n  return true\n}\n\nconst isEqualStringArrays = (a: string[], b: string[]): boolean =>\n  a === b || (a.length === b.length && a.every((value, i) => value === b[i]))\n\n/** replaces distinctUntilChanged(isEqual) on BalancesResult streams */\nexport const isEqualBalancesResult = (a: BalancesResult, b: BalancesResult): boolean =>\n  a.status === b.status &&\n  isEqualStringArrays(a.failedBalanceIds, b.failedBalanceIds) &&\n  isEqualBalanceArrays(a.balances, b.balances)\n\n/**\n * Replaces distinctUntilChanged(isEqual) on module poll streams.\n * Errors are compared by (tokenId, address) and dynamic tokens by id — slightly MORE\n * dedupe than lodash isEqual (which compared Error instances), which is desirable: a\n * fresh-but-identical Error on every failing poll should not re-emit.\n */\nexport const isEqualModuleResults = (a: FetchBalanceResults, b: FetchBalanceResults): boolean =>\n  a.errors.length === b.errors.length &&\n  a.errors.every(\n    (error, i) => error.tokenId === b.errors[i].tokenId && error.address === b.errors[i].address\n  ) &&\n  (a.dynamicTokens?.length ?? 0) === (b.dynamicTokens?.length ?? 0) &&\n  (a.dynamicTokens ?? []).every((token, i) => token.id === b.dynamicTokens?.[i]?.id) &&\n  isEqualBalanceArrays(a.success, b.success)\n\n/**\n * Replaces distinctUntilChanged(isEqual) on MiniMetadata[] streams: id encodes\n * (source, chainId, specVersion, version) and data is the metadata hex, so comparing\n * those by === replaces a deep walk over large metadata strings and `extra` objects.\n */\nexport const isEqualMiniMetadatas = (\n  a: MiniMetadata[] | null,\n  b: MiniMetadata[] | null\n): boolean => {\n  if (a === b) return true\n  if (a === null || b === null) return false\n  return a.length === b.length && a.every((m, i) => m.id === b[i].id && m.data === b[i].data)\n}\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses: tokensWithAddresses,\n          connector,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n\n        setTimeout(poll, SUBSCRIPTION_INTERVAL)\n      } catch (error) {\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          addressesByToken: tokensWithAddresses,\n          error,\n        })\n        subscriber.error(error)\n      }\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(distinctUntilChanged(isEqualModuleResults))\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const EvmErc20BalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { TokenBaseSchema } from \"@talismn/chaindata-provider\"\n\nexport const TokenConfigBaseSchema = TokenBaseSchema.partial().omit({ id: true })\n","import { EvmErc20TokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const EvmErc20TokenConfigSchema = z.strictObject({\n  contractAddress: EvmErc20TokenSchema.shape.contractAddress,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type EvmErc20TokenConfig = z.infer<typeof EvmErc20TokenConfigSchema>\n","import { EvmNativeTokenSchema } from \"@talismn/chaindata-provider\"\n\nexport type { EvmNativeTokenConfig as TokenConfig } from \"./types\"\n\nexport const MODULE_TYPE = EvmNativeTokenSchema.shape.type.value\nexport const PLATFORM = EvmNativeTokenSchema.shape.platform.value\n","import { parseTokenId } from \"@talismn/chaindata-provider\"\nimport { isEthereumAddress } from \"@talismn/crypto\"\nimport type { PublicClient } from \"viem\"\n\nimport type { IBalance } from \"../../types\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { abiMulticall } from \"../abis\"\nimport { BalanceFetchError } from \"../shared/errors\"\nimport { type BalanceDef, getBalanceDefs } from \"../shared/types\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const client = await connector.getPublicClientForEvmNetwork(networkId)\n  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`)\n\n  for (const [token, addresses] of tokensWithAddresses) {\n    if (token.type !== MODULE_TYPE || token.networkId !== networkId)\n      throw new Error(\n        `Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`\n      )\n\n    for (const address of addresses)\n      if (!isEthereumAddress(address))\n        throw new Error(\n          `Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`\n        )\n  }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  // Prefer a single multicall3.getEthBalance aggregate when the chain advertises a multicall3\n  // contract and there's more than one balance to fetch. Fall back to direct eth_getBalance if\n  // the multicall throws — which happens when multicall3 is advertised (via viem's chain\n  // definitions) but not actually deployed at the active RPC: a custom or forked RPC for a\n  // well-known chain id, or a fresh dev node, where `aggregate3` returns \"0x\".\n  if (client.chain?.contracts?.multicall3 && balanceDefs.length > 1) {\n    try {\n      return await fetchWithMulticall(\n        client,\n        balanceDefs,\n        client.chain.contracts.multicall3.address\n      )\n    } catch {\n      // multicall3 unavailable at this RPC — fall through to direct balance queries\n    }\n  }\n\n  return fetchWithGetBalance(client, balanceDefs)\n}\n\n// Query `eth_getBalance` directly (not `client.getBalance(...)`): since viem 2.5x, getBalance\n// itself routes through multicall3.getEthBalance when the client has `batch.multicall` and the\n// chain advertises multicall3 — re-triggering the very failure this fallback exists for. The\n// raw request stays transport-batched (JSON-RPC array), so multiple addresses still coalesce.\nconst fetchWithGetBalance = async (\n  client: PublicClient,\n  balanceDefs: BalanceDef<typeof MODULE_TYPE>[]\n): Promise<FetchBalanceResults> => {\n  if (balanceDefs.length === 0) return { success: [], errors: [] }\n\n  const results = await Promise.allSettled(\n    balanceDefs.map(async ({ token, address }) => {\n      try {\n        const result = await client.request({\n          method: \"eth_getBalance\",\n          params: [address as `0x${string}`, \"latest\"],\n        })\n\n        const balance: IBalance = {\n          address,\n          tokenId: token.id,\n          value: BigInt(result).toString(),\n          source: MODULE_TYPE,\n          networkId: parseTokenId(token.id).networkId,\n          status: \"live\",\n        }\n\n        return balance\n      } catch (err) {\n        throw new BalanceFetchError(\n          `Failed to get balance for token ${token.id} and address ${address} on chain ${client.chain?.id}`,\n          token.id,\n          address,\n          err as Error\n        )\n      }\n    })\n  )\n\n  return results.reduce<FetchBalanceResults>(\n    (acc, result) => {\n      if (result.status === \"fulfilled\") acc.success.push(result.value as IBalance)\n      else {\n        const error = result.reason as BalanceFetchError\n        acc.errors.push({\n          tokenId: error.tokenId,\n          address: error.address,\n          error,\n        })\n      }\n      return acc\n    },\n    { success: [], errors: [] }\n  )\n}\n\n// `allowFailure: false` so a missing multicall3 (an RPC without it deployed → `aggregate3`\n// returns \"0x\") makes the whole call throw, letting the caller fall back to direct\n// eth_getBalance. getEthBalance never reverts per-address, so we don't lose per-call resilience\n// by disallowing failures.\nconst fetchWithMulticall = async (\n  client: PublicClient,\n  balanceDefs: BalanceDef<typeof MODULE_TYPE>[],\n  multicall3Address: `0x${string}`\n): Promise<FetchBalanceResults> => {\n  if (balanceDefs.length === 0) return { success: [], errors: [] }\n\n  const results = await client.multicall({\n    allowFailure: false,\n    contracts: balanceDefs.map(({ address }) => ({\n      address: multicall3Address,\n      abi: abiMulticall,\n      functionName: \"getEthBalance\",\n      args: [address],\n    })),\n  })\n\n  return {\n    success: results.map(\n      (value, index): IBalance => ({\n        address: balanceDefs[index].address,\n        tokenId: balanceDefs[index].token.id,\n        value: String(value),\n        source: MODULE_TYPE,\n        networkId: parseTokenId(balanceDefs[index].token.id).networkId,\n        status: \"live\",\n      })\n    ),\n    errors: [],\n  }\n}\n","import {\n  type EvmNativeToken,\n  EvmNativeTokenSchema,\n  evmNativeTokenId,\n} from \"@talismn/chaindata-provider\"\nimport { assign } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n}) => {\n  // assume there is one and only one token in the array\n  if (tokens.length !== 1)\n    throw new Error(\n      \"EVM Native module expects the nativeCurrency to be passed as a single token in the array\"\n    )\n\n  const token = assign(\n    {\n      id: evmNativeTokenId(networkId),\n      type: MODULE_TYPE,\n      platform: PLATFORM,\n      networkId,\n      isDefault: true,\n    },\n    tokens[0] as TokenConfig\n  ) as EvmNativeToken\n\n  const parsed = EvmNativeTokenSchema.safeParse(token)\n  if (!parsed.success) {\n    log.warn(\"Ignoring token with invalid schema\", token)\n    return []\n  }\n\n  return [parsed.data]\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = () => {\n  throw new Error(\"MiniMetadata is not supported for ethereum tokens\")\n}\n","import { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport { isEthereumAddress } from \"@talismn/crypto\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n  if (!isEthereumAddress(from)) throw new Error(\"Invalid from address\")\n  if (!isEthereumAddress(to)) throw new Error(\"Invalid to address\")\n\n  return { from, to, value, data: \"0x\" as `0x${string}` }\n}\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses: tokensWithAddresses,\n          connector,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n\n        setTimeout(poll, SUBSCRIPTION_INTERVAL)\n      } catch (error) {\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          addressesByToken: tokensWithAddresses,\n          error,\n        })\n        subscriber.error(error)\n      }\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(distinctUntilChanged(isEqualModuleResults))\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const EvmNativeBalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const EvmNativeTokenConfigSchema = z.strictObject({\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type EvmNativeTokenConfig = z.infer<typeof EvmNativeTokenConfigSchema>\n","import { EvmUniswapV2TokenSchema } from \"@talismn/chaindata-provider\"\n\nexport type { EvmUniswapV2TokenConfig as TokenConfig } from \"./types\"\n\nexport const MODULE_TYPE = EvmUniswapV2TokenSchema.shape.type.value\nexport const PLATFORM = EvmUniswapV2TokenSchema.shape.platform.value\n","import { parseTokenId } from \"@talismn/chaindata-provider\"\nimport { isEthereumAddress } from \"@talismn/crypto\"\nimport { keyBy, uniq } from \"lodash-es\"\nimport { getContract, type PublicClient } from \"viem\"\nimport BigNumber from \"../../configureBigNumber\"\n\nimport type { ExtraAmount } from \"../../types\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { uniswapV2PairAbi } from \"../abis\"\nimport { BalanceFetchError, BalanceFetchNetworkError } from \"../shared/errors\"\nimport { type BalanceDef, getBalanceDefs } from \"../shared/types\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const client = await connector.getPublicClientForEvmNetwork(networkId)\n  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`)\n\n  for (const [token, addresses] of tokensWithAddresses) {\n    if (token.type !== MODULE_TYPE || token.networkId !== networkId)\n      throw new Error(\n        `Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`\n      )\n\n    for (const address of addresses)\n      if (!isEthereumAddress(address))\n        throw new Error(\n          `Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`\n        )\n  }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  return fetchPoolBalances(client, balanceDefs)\n}\n\nconst fetchPoolBalances = async (\n  client: PublicClient,\n  balanceDefs: BalanceDef<typeof MODULE_TYPE>[]\n): Promise<FetchBalanceResults> => {\n  if (balanceDefs.length === 0) return { success: [], errors: [] }\n\n  // fetch pool specific info separately to prevent querying same contract info for multiple account addresses\n  const pools = uniq(balanceDefs.map((def) => def.token.contractAddress))\n\n  const [poolResults, balanceResults] = await Promise.all([\n    // pool supplies and reserves\n    Promise.allSettled(\n      pools.map(async (address) => {\n        const contract = getContract({ address, abi: uniswapV2PairAbi, client })\n\n        const [totalSupply, [reserve0, reserve1]] = await Promise.all([\n          contract.read.totalSupply(),\n          contract.read.getReserves(),\n        ])\n        return { address, totalSupply, reserve0, reserve1 }\n      })\n    ),\n    // balances for each address\n    Promise.allSettled(\n      balanceDefs.map(async ({ token, address }) => {\n        const balance = await client.readContract({\n          address: token.contractAddress,\n          abi: uniswapV2PairAbi,\n          functionName: \"balanceOf\",\n          args: [address],\n        } as const)\n\n        return { pool: token.contractAddress, address, balance }\n      })\n    ),\n  ])\n\n  const poolInfo = keyBy(\n    poolResults.filter((r) => r.status === \"fulfilled\").map((r) => r.value),\n    (p) => p.address\n  )\n\n  const results = balanceDefs.reduce<FetchBalanceResults>(\n    (acc, { token, address }, i) => {\n      const pool = poolInfo[token.contractAddress]\n      if (!pool) {\n        acc.errors.push({\n          tokenId: token.id,\n          address,\n          error: new BalanceFetchNetworkError(\n            `Pool data not found for token ${token.id} at address ${token.contractAddress}`,\n            parseTokenId(token.id).networkId\n          ),\n        })\n        return acc\n      }\n\n      const balanceResult = balanceResults[i]\n\n      if (balanceResult.status !== \"fulfilled\") {\n        acc.errors.push({\n          tokenId: token.id,\n          address,\n          error: new BalanceFetchError(\n            `Failed to fetch balance for token ${token.id} at address ${address}`,\n            token.id,\n            address,\n            balanceResult.reason as Error\n          ),\n        })\n        return acc\n      }\n\n      const { totalSupply, reserve0, reserve1 } = pool\n      const { balance } = balanceResult.value\n\n      const extraWithLabel = (label: string, amount: string): ExtraAmount<string> => ({\n        type: \"extra\",\n        label,\n        amount,\n      })\n\n      const ratio = BigNumber(String(balance)).div(totalSupply === 0n ? \"1\" : String(totalSupply))\n\n      acc.success.push({\n        address,\n        tokenId: token.id,\n        source: MODULE_TYPE,\n        networkId: parseTokenId(token.id).networkId,\n        status: \"live\",\n        values: [\n          { type: \"free\", label: \"free\", amount: String(balance) },\n          extraWithLabel(\"totalSupply\", String(totalSupply)),\n          extraWithLabel(\"reserve0\", String(reserve0)),\n          extraWithLabel(\"reserve1\", String(reserve1)),\n          extraWithLabel(\"holding0\", ratio.times(String(reserve0)).toString(10)),\n          extraWithLabel(\"holding1\", ratio.times(String(reserve1)).toString(10)),\n        ],\n      })\n\n      return acc\n    },\n    { success: [], errors: [] }\n  )\n\n  return results\n}\n","import { isErrorOfName } from \"@talismn/util\"\nimport { type Abi, type Client, erc20Abi, erc20Abi_bytes32, getContract, hexToString } from \"viem\"\n\nimport { uniswapV2PairAbi } from \"../abis\"\n\nexport const getErc20ContractData = async (\n  client: Client,\n  contractAddress: `0x${string}`\n): Promise<{ symbol: string; decimals: number; name: string }> => {\n  try {\n    const contract = getTypedContract(client, erc20Abi, contractAddress)\n\n    // biome-ignore lint/correctness/noInnerDeclarations: legacy\n    // biome-ignore lint/correctness/noUnusedVariables: legacy\n    var [symbol, decimals, name] = await Promise.all([\n      contract.read.symbol(),\n      contract.read.decimals(),\n      contract.read.name(),\n    ])\n  } catch (e) {\n    if (isErrorOfName(e, \"ContractFunctionExecutionError\")) {\n      // try to perform the contract read with bytes32 symbol\n      const contract = getTypedContract(client, erc20Abi_bytes32, contractAddress)\n\n      // biome-ignore lint/correctness/noInnerDeclarations: legacy\n      // biome-ignore lint/suspicious/noRedeclare: legacy\n      var [bytesSymbol, decimals, nameSymbol] = await Promise.all([\n        contract.read.symbol(),\n        contract.read.decimals(),\n        contract.read.name(),\n      ])\n      symbol = hexToString(bytesSymbol).replace(/\\0/g, \"\").trim() // remove NULL characters\n      name = hexToString(nameSymbol).replace(/\\0/g, \"\").trim() // remove NULL characters\n    } else throw e\n  }\n\n  return { symbol, decimals, name }\n}\n\nconst getTypedContract = <TAbi extends Abi>(\n  client: Client,\n  abi: TAbi,\n  contractAddress: `0x${string}`\n) =>\n  getContract({\n    address: contractAddress,\n    abi,\n    client: { public: client },\n  })\n\nexport const getUniswapV2PairContractData = async (\n  client: Client,\n  contractAddress: `0x${string}`\n) => {\n  const contract = getTypedContract(client, uniswapV2PairAbi, contractAddress)\n\n  var [token0, token1, decimals, name] = await Promise.all([\n    contract.read.token0(),\n    contract.read.token1(),\n    contract.read.decimals(),\n    contract.read.name(),\n  ])\n\n  return { token0, token1, decimals, name }\n}\n","import {\n  type EvmUniswapV2Token,\n  EvmUniswapV2TokenSchema,\n  evmUniswapV2TokenId,\n} from \"@talismn/chaindata-provider\"\nimport { assign, omit } from \"lodash-es\"\nimport type { BaseError } from \"viem\"\nimport z from \"zod/v4\"\n\nimport log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { getErc20ContractData, getUniswapV2PairContractData } from \"./utils\"\n\nconst TokenCacheSchema = z.discriminatedUnion(\"isValid\", [\n  z.strictObject({\n    id: EvmUniswapV2TokenSchema.shape.id,\n    isValid: z.literal(true),\n    ...EvmUniswapV2TokenSchema.pick({\n      symbol: true,\n      decimals: true,\n      name: true,\n      tokenAddress0: true,\n      tokenAddress1: true,\n      decimals0: true,\n      decimals1: true,\n      symbol0: true,\n      symbol1: true,\n    }).shape,\n  }),\n  z.strictObject({\n    id: EvmUniswapV2TokenSchema.shape.id,\n    isValid: z.literal(false),\n  }),\n])\n\ntype CachedToken = z.infer<typeof TokenCacheSchema>\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  connector,\n  cache,\n}) => {\n  const result: EvmUniswapV2Token[] = []\n\n  for (const tokenConfig of tokens) {\n    const tokenId = evmUniswapV2TokenId(networkId, tokenConfig.contractAddress)\n    const cached = (cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data) as\n      | CachedToken\n      | undefined\n\n    if (!cached) {\n      const client = await connector.getPublicClientForEvmNetwork(networkId)\n      if (!client) {\n        log.warn(`No client found for network ${networkId} while fetching EVM ERC20 tokens`)\n        continue\n      }\n\n      try {\n        const { token0, token1, name, decimals } = await getUniswapV2PairContractData(\n          client,\n          tokenConfig.contractAddress\n        )\n\n        const { symbol: symbol0, decimals: decimals0 } = await getErc20ContractData(client, token0)\n        const { symbol: symbol1, decimals: decimals1 } = await getErc20ContractData(client, token1)\n\n        cache[tokenId] = TokenCacheSchema.parse({\n          id: tokenId,\n          symbol: `${symbol0}/${symbol1}`,\n          decimals,\n          name,\n          tokenAddress0: token0,\n          tokenAddress1: token1,\n          decimals0,\n          decimals1,\n          symbol0,\n          symbol1,\n          isValid: true,\n        })\n      } catch (err) {\n        const msg = (err as BaseError).shortMessage\n        if (\n          msg.includes(\"returned no data\") ||\n          msg.includes(\"is out of bounds\") ||\n          msg.includes(\"reverted\")\n        ) {\n          cache[tokenId] = { id: tokenId, isValid: false }\n        } else {\n          log.warn(\n            `Failed to fetch UniswapV2 token data for ${tokenConfig.contractAddress}`,\n            (err as BaseError).shortMessage\n          )\n        }\n        continue\n      }\n    }\n\n    const base: Pick<EvmUniswapV2Token, \"id\" | \"type\" | \"networkId\" | \"platform\"> = {\n      id: tokenId,\n      type: MODULE_TYPE,\n      platform: PLATFORM,\n      networkId,\n    }\n\n    const cached2 = (cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data) as\n      | CachedToken\n      | undefined\n\n    if (cached2?.isValid === false) continue\n\n    const token = assign(\n      base,\n      cached2?.isValid ? omit(cached2, [\"isValid\"]) : {},\n      tokenConfig\n    ) as EvmUniswapV2Token\n\n    const parsed = EvmUniswapV2TokenSchema.safeParse(token)\n    if (!parsed.success) {\n      log.warn(\"Ignoring token with invalid schema\", token)\n      continue\n    }\n\n    result.push(parsed.data)\n  }\n\n  return result\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = () => {\n  throw new Error(\"MiniMetadata is not supported for ethereum tokens\")\n}\n","import { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport { isEthereumAddress } from \"@talismn/crypto\"\nimport { encodeFunctionData, erc20Abi } from \"viem\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n  if (!isEthereumAddress(from)) throw new Error(\"Invalid from address\")\n  if (!isEthereumAddress(to)) throw new Error(\"Invalid to address\")\n\n  const data = encodeFunctionData({\n    abi: erc20Abi,\n    functionName: \"transfer\",\n    args: [to, BigInt(value)],\n  })\n\n  return { from, to: token.contractAddress, data }\n}\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses: tokensWithAddresses,\n          connector,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n\n        setTimeout(poll, SUBSCRIPTION_INTERVAL)\n      } catch (error) {\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          addressesByToken: tokensWithAddresses,\n          error,\n        })\n        subscriber.error(error)\n      }\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(distinctUntilChanged(isEqualModuleResults))\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const EvmUniswapV2BalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { EvmUniswapV2TokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const EvmUniswapV2TokenConfigSchema = z.strictObject({\n  contractAddress: EvmUniswapV2TokenSchema.shape.contractAddress,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type EvmUniswapV2TokenConfig = z.infer<typeof EvmUniswapV2TokenConfigSchema>\n","import { SolNativeTokenSchema } from \"@talismn/chaindata-provider\"\n\nexport type { SolNativeTokenConfig as TokenConfig } from \"./types\"\n\nexport const MODULE_TYPE = SolNativeTokenSchema.shape.type.value\nexport const PLATFORM = SolNativeTokenSchema.shape.platform.value\n","import { address as solAddress } from \"@solana/kit\"\nimport { isSolanaAddress } from \"@talismn/crypto\"\n\nimport type { IBalance } from \"../../types\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { BalanceFetchError } from \"../shared/errors\"\nimport { getBalanceDefs } from \"../shared/types\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const rpc = await connector.getRpc(networkId)\n  if (!rpc) throw new Error(`Could not get rpc provider for sol network ${networkId}`)\n\n  for (const [token, addresses] of tokensWithAddresses) {\n    if (token.type !== MODULE_TYPE || token.networkId !== networkId)\n      throw new Error(\n        `Invalid token type or networkId for balance module: ${token.type} on ${token.networkId}`\n      )\n\n    for (const address of addresses)\n      if (!isSolanaAddress(address))\n        throw new Error(\n          `Invalid solana address for balance module: ${address} for token ${token.id}`\n        )\n  }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  const results = await Promise.allSettled(\n    balanceDefs.map(async ({ token, address }): Promise<IBalance> => {\n      try {\n        const { value: lamports } = await rpc.getBalance(solAddress(address)).send()\n\n        return {\n          address: address,\n          tokenId: token.id,\n          value: lamports.toString(),\n          source: MODULE_TYPE,\n          networkId: token.networkId,\n          status: \"live\",\n        }\n      } catch (err) {\n        throw new BalanceFetchError(\n          `Failed to get balance for token ${token.id} and address ${address} on chain ${networkId}`,\n          token.id,\n          address,\n          err as Error\n        )\n      }\n    })\n  )\n\n  return results.reduce<FetchBalanceResults>(\n    (acc, result) => {\n      if (result.status === \"fulfilled\") acc.success.push(result.value as IBalance)\n      else {\n        const error = result.reason as BalanceFetchError\n        acc.errors.push({\n          tokenId: error.tokenId,\n          address: error.address,\n          error,\n        })\n      }\n      return acc\n    },\n    { success: [], errors: [] }\n  )\n}\n","import {\n  type SolNativeToken,\n  SolNativeTokenSchema,\n  solNativeTokenId,\n} from \"@talismn/chaindata-provider\"\nimport { assign } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n}) => {\n  // assume there is one and only one token in the array\n  if (tokens.length !== 1)\n    throw new Error(\n      \"EVM Native module expects the nativeCurrency to be passed as a single token in the array\"\n    )\n\n  const token = assign(\n    {\n      id: solNativeTokenId(networkId),\n      type: MODULE_TYPE,\n      platform: PLATFORM,\n      networkId,\n      isDefault: true,\n    },\n    tokens[0] as TokenConfig\n  ) as SolNativeToken\n\n  const parsed = SolNativeTokenSchema.safeParse(token)\n  if (!parsed.success) {\n    log.warn(\"Ignoring token with invalid schema\", token)\n    return []\n  }\n\n  return [parsed.data]\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = () => {\n  throw new Error(\"MiniMetadata is not supported for sol-native tokens\")\n}\n","import { createNoopSigner, address as solAddress } from \"@solana/kit\"\nimport { getTransferSolInstruction } from \"@solana-program/system\"\nimport { isTokenOfType } from \"@talismn/chaindata-provider\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n  const transferIx = getTransferSolInstruction({\n    source: createNoopSigner(solAddress(from)), // signature is provided at signing time\n    destination: solAddress(to),\n    amount: BigInt(value),\n  })\n\n  return [transferIx]\n}\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses,\n          connector,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n\n        setTimeout(poll, SUBSCRIPTION_INTERVAL)\n      } catch (error) {\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          tokensWithAddresses,\n          error,\n        })\n        subscriber.error(error)\n      }\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(distinctUntilChanged(isEqualModuleResults))\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SolNativeBalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SolNativeTokenConfigSchema = z.strictObject({\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type SolNativeTokenConfig = z.infer<typeof SolNativeTokenConfigSchema>\n","import { SolSplTokenSchema } from \"@talismn/chaindata-provider\"\n\nexport const MODULE_TYPE = SolSplTokenSchema.shape.type.value\nexport const PLATFORM = SolSplTokenSchema.shape.platform.value\n\nexport type { SolSplTokenConfig as TokenConfig } from \"./types\"\n","import {\n  decAnyMetadata,\n  getDynamicBuilder,\n  getLookupFn,\n  type ScaleStorageCoder,\n  unifyMetadata,\n} from \"@talismn/scale\"\n\nimport log from \"../../log\"\nimport type { MiniMetadata } from \"../../types\"\n\ntype ScaleBuilder = ReturnType<typeof getDynamicBuilder>\n\n/**\n * Parsing chain metadata and building the dynamic scale builder\n * (unifyMetadata(decAnyMetadata(data)) + getDynamicBuilder(getLookupFn(...))) costs tens to\n * hundreds of ms and is a single indivisible synchronous call — it cannot be time-sliced.\n * Without caching it runs on EVERY balance subscription rebuild (i.e. every block for\n * substrate-native's nompool queries), which is the single largest JS-thread hog in this\n * package. With caching it runs once per (module, chain, specVersion).\n *\n * miniMetadata.id already hashes (source, chainId, specVersion); data.length is included in\n * the key as a cheap guard against config-driven content changes that don't bump the id.\n */\nconst getCacheKey = (miniMetadata: MiniMetadata): string | null =>\n  miniMetadata.data ? `${miniMetadata.id}:${miniMetadata.data.length}` : null\n\nconst BUILDER_CACHE_SIZE = 16\nconst builderCache = new Map<string, ScaleBuilder | null>()\n\n/** Returns the (memoized) dynamic scale builder for a miniMetadata, or null if it can't be built */\nexport const getCachedScaleBuilder = (miniMetadata: MiniMetadata): ScaleBuilder | null => {\n  const key = getCacheKey(miniMetadata)\n  if (key === null) return null\n\n  if (builderCache.has(key)) {\n    const cached = builderCache.get(key) ?? null\n    // refresh LRU recency (Map preserves insertion order)\n    builderCache.delete(key)\n    builderCache.set(key, cached)\n    return cached\n  }\n\n  let builder: ScaleBuilder | null = null\n  try {\n    // data is non-null here: getCacheKey returned a key\n    const metadata = unifyMetadata(decAnyMetadata(miniMetadata.data!))\n    builder = getDynamicBuilder(getLookupFn(metadata))\n  } catch (cause) {\n    // cache failures too, so a broken miniMetadata doesn't re-parse on every call\n    log.error(`Failed to build scale builder for chain ${miniMetadata.chainId}`, cause)\n  }\n\n  builderCache.set(key, builder)\n  while (builderCache.size > BUILDER_CACHE_SIZE)\n    builderCache.delete(builderCache.keys().next().value as string)\n\n  return builder\n}\n\nconst STORAGE_CODER_CACHE_SIZE = 256\nconst storageCoderCache = new Map<string, ScaleStorageCoder | undefined>()\n\n/** Returns the (memoized) storage coder for a (miniMetadata, pallet, entry), or undefined if it can't be built */\nexport const getCachedStorageCoder = (\n  miniMetadata: MiniMetadata,\n  pallet: string,\n  entry: string\n): ScaleStorageCoder | undefined => {\n  const metadataKey = getCacheKey(miniMetadata)\n  if (metadataKey === null) return undefined\n  const key = `${metadataKey}:${pallet}:${entry}`\n\n  if (storageCoderCache.has(key)) {\n    const cached = storageCoderCache.get(key)\n    storageCoderCache.delete(key)\n    storageCoderCache.set(key, cached)\n    return cached\n  }\n\n  let coder: ScaleStorageCoder | undefined\n  try {\n    coder = getCachedScaleBuilder(miniMetadata)?.buildStorage(pallet, entry)\n  } catch (cause) {\n    // cache failures too (some chains simply don't have the pallet/entry)\n    log.trace(\n      `Failed to build SCALE coder for chain ${miniMetadata.chainId} (${pallet}::${entry})`,\n      cause\n    )\n  }\n\n  storageCoderCache.set(key, coder)\n  while (storageCoderCache.size > STORAGE_CODER_CACHE_SIZE)\n    storageCoderCache.delete(storageCoderCache.keys().next().value as string)\n\n  return coder\n}\n","import type { DotNetworkId } from \"@talismn/chaindata-provider\"\nimport type { ScaleStorageCoder } from \"@talismn/scale\"\n\nimport type { MiniMetadata } from \"../../types\"\nimport { getCachedScaleBuilder, getCachedStorageCoder } from \"./scaleBuilderCache\"\n\ntype NetworkCoders = { [key: string]: [string, string] }\n\ntype NetworkStorageCoders<TCoders extends NetworkCoders> = {\n  [Property in keyof TCoders]: ScaleStorageCoder | undefined\n}\n\nexport const buildNetworkStorageCoders = <TCoders extends { [key: string]: [string, string] }>(\n  chainId: DotNetworkId,\n  miniMetadata: MiniMetadata,\n  coders: TCoders\n): NetworkStorageCoders<TCoders> | null => {\n  if (!miniMetadata.data) return null\n\n  // metadata parse + builder + per-entry coders are all memoized (see scaleBuilderCache):\n  // the expensive work runs once per (module, chain, specVersion) instead of per rebuild\n  if (getCachedScaleBuilder(miniMetadata) === null) return null\n\n  return Object.fromEntries(\n    Object.entries(coders).map(\n      ([key, moduleMethodOrFn]: [\n        keyof TCoders,\n        [string, string] | ((params: { chainId: string }) => [string, string]),\n      ]) => {\n        const [module, method] =\n          typeof moduleMethodOrFn === \"function\" ? moduleMethodOrFn({ chainId }) : moduleMethodOrFn\n        return [key, getCachedStorageCoder(miniMetadata, module, method)] as const\n      }\n    )\n  ) as NetworkStorageCoders<TCoders>\n}\n","import { parseMetadataRpc } from \"@talismn/scale\"\nimport { reportJsActivity } from \"@talismn/util\"\n\n/**\n * parseMetadataRpc does a full metadata decode + dynamic-builder build (tens to hundreds\n * of ms, indivisible). Modules that poll (e.g. substrate-dtao every 6s) call it with the\n * same metadata hex over and over — memoize by the hex string so it runs once per\n * metadata blob instead of several times per poll tick.\n *\n * WARNING: the returned objects are SHARED between callers. Callers must treat them as\n * read-only — in particular, do NOT pass the cached `metadata` to `compactMetadata`,\n * which mutates it in place (getMiniMetadata paths intentionally use the uncached\n * parseMetadataRpc for this reason).\n */\nconst CACHE_SIZE = 8\nconst cache = new Map<string, ReturnType<typeof parseMetadataRpc>>()\n\nexport const parseMetadataRpcCached = (\n  metadataRpc: `0x${string}`\n): ReturnType<typeof parseMetadataRpc> => {\n  const cached = cache.get(metadataRpc)\n  if (cached) {\n    // refresh LRU recency (Map preserves insertion order)\n    cache.delete(metadataRpc)\n    cache.set(metadataRpc, cached)\n    return cached\n  }\n\n  // cache misses are a prime JS-thread stall suspect: the parse is indivisible, and with\n  // more than CACHE_SIZE distinct metadata blobs live the LRU thrashes and re-parses on\n  // every rotation — report each miss (with duration + cache pressure) to the host\n  // watchdog so stalls can be attributed to it\n  const start = performance.now()\n  const result = parseMetadataRpc(metadataRpc)\n  reportJsActivity(\n    `parseMetadataRpc miss (~${Math.round(metadataRpc.length / 2048)}KB, cache ${cache.size}/${CACHE_SIZE})`,\n    performance.now() - start\n  )\n\n  cache.set(metadataRpc, result)\n  while (cache.size > CACHE_SIZE) cache.delete(cache.keys().next().value as string)\n\n  return result\n}\n","import type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport { type MetadataBuilder, toHex } from \"@talismn/scale\"\nimport { reportJsActivity } from \"@talismn/util\"\n\nimport { parseMetadataRpcCached } from \"./parseMetadataRpcCached\"\n\n// buildRuntimeCall compiles the arg/result codecs from the type graph — expensive and\n// allocation-heavy, and previously re-ran for EVERY call (pollers like substrate-hydration\n// issue several runtime calls per address per 6s poll). Memoized per (builder, api.method);\n// the builder key is reference-stable thanks to parseMetadataRpcCached.\nconst runtimeCallCache = new WeakMap<\n  MetadataBuilder,\n  Map<string, ReturnType<MetadataBuilder[\"buildRuntimeCall\"]>>\n>()\n\nconst getRuntimeCall = (builder: MetadataBuilder, apiName: string, method: string) => {\n  let byName = runtimeCallCache.get(builder)\n  if (!byName) {\n    byName = new Map()\n    runtimeCallCache.set(builder, byName)\n  }\n\n  const key = `${apiName}.${method}`\n  let call = byName.get(key)\n  if (!call) {\n    const start = performance.now()\n    call = builder.buildRuntimeCall(apiName, method)\n    reportJsActivity(`buildRuntimeCall ${key}`, performance.now() - start)\n    byName.set(key, call)\n  }\n  return call\n}\n\nexport const fetchRuntimeCallResult = async <T>(\n  connector: IChainConnectorDot,\n  networkId: string,\n  // pass a pre-parsed MetadataBuilder when issuing many calls: parsing the raw metadataRpc is expensive\n  metadataRpcOrBuilder: `0x${string}` | MetadataBuilder,\n  apiName: string,\n  method: string,\n  args: unknown[]\n): Promise<T> => {\n  try {\n    // MUST be the cached parse: substrate-hydration passes the raw hex once PER ADDRESS\n    // on every 6s poll — the uncached parse here was a full metadata decode+builder\n    // build (~200ms, indivisible) per call, i.e. a recurring near-second JS-thread stall\n    const builder =\n      typeof metadataRpcOrBuilder === \"string\"\n        ? parseMetadataRpcCached(metadataRpcOrBuilder).builder\n        : metadataRpcOrBuilder\n    const call = getRuntimeCall(builder, apiName, method)\n\n    const hex = await connector.send<string>(networkId, \"state_call\", [\n      `${apiName}_${method}`,\n      toHex(call.args.enc(args)),\n    ])\n\n    // the response decode is synchronous and indivisible — for large results (e.g.\n    // bittensor get_stake_info_for_coldkeys / get_all_dynamic_info, polled every 6s)\n    // this can block the JS thread for hundreds of ms. Report it so host stall\n    // watchdogs can attribute the block.\n    const start = performance.now()\n    const result = call.value.dec(hex) as T\n    reportJsActivity(\n      `runtimeCall decode ${networkId} ${apiName}.${method} (~${Math.round((hex?.length ?? 0) / 2048)}KB)`,\n      performance.now() - start\n    )\n    return result\n  } catch (cause) {\n    throw new Error(`Error fetching runtime call on ${networkId} for ${apiName}.${method}`, {\n      cause,\n    })\n  }\n}\n","import type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport type { DotNetworkId } from \"@talismn/chaindata-provider\"\nimport { type ChunkedOptions, isNotNil, mapWithYield, switchMapChunked } from \"@talismn/util\"\nimport { Observable, of } from \"rxjs\"\n\nimport type { QueryStorageResult } from \"./types\"\n\nexport type MaybeStateKey = `0x${string}` | null\n\nexport type RpcQueryPack<T> = {\n  stateKeys: MaybeStateKey[]\n  decodeResult: (changes: MaybeStateKey[]) => T\n}\n\ntype QueryStorageResultContent = QueryStorageResult[0]\n\ntype ChangesByKey = ReadonlyMap<`0x${string}`, `0x${string}`>\n\nexport const fetchRpcQueryPack = async <T>(\n  connector: IChainConnectorDot,\n  networkId: DotNetworkId,\n  queries: RpcQueryPack<T>[]\n) => {\n  const allStateKeys = queries.flatMap(({ stateKeys }) => stateKeys).filter(isNotNil)\n\n  // doing a query without keys would throw an error => return early\n  if (!allStateKeys.length)\n    return queries.map(({ stateKeys, decodeResult }) => decodeResult(stateKeys.map(() => null)))\n\n  const [result] = await connector.send<QueryStorageResult>(networkId, \"state_queryStorageAt\", [\n    allStateKeys,\n  ])\n\n  // a valid state_queryStorageAt response carries one entry per queried block — an empty\n  // response is a bad response, not absent values: decoding it would fabricate \"no value\"\n  // for every queried key (eg empty RootClaimable maps deleting claim-only balances)\n  if (!result) throw new Error(`Empty state_queryStorageAt response on ${networkId}`)\n\n  return decodeRpcQueryPackChunked(queries, new Map(result.changes), {\n    label: `rpcQueryPack decode ${networkId}`,\n  })\n}\n\n/**\n * Wraps the raw state_subscribeStorage subscription and emits, for every storage change\n * callback, a SNAPSHOT of the accumulated changes keyed by state key.\n *\n * A snapshot (shallow copy of string refs, cheap) is required because decoding is chunked\n * and asynchronous: a later websocket callback must not mutate the map that an in-flight\n * decode is reading.\n */\nconst getRawStorageUpdates$ = (\n  connector: IChainConnectorDot,\n  networkId: DotNetworkId,\n  allStateKeys: `0x${string}`[],\n  timeout: number | false\n): Observable<ChangesByKey> =>\n  new Observable<ChangesByKey>((subscriber) => {\n    // first subscription callback includes results for all state keys, but further callbacks will only include the ones that changed\n    // => we need to keep all results in memory and update them after each callback, so we can emit the full result set each time\n    const changesCache = new Map<`0x${string}`, `0x${string}`>()\n\n    const promUnsub = connector.subscribe(\n      networkId,\n      \"state_subscribeStorage\",\n      \"state_storage\",\n      [allStateKeys],\n      (error, result: QueryStorageResultContent) => {\n        if (error) subscriber.error(error)\n        else if (result) {\n          // update the cache\n          for (const [stateKey, encodedResult] of result.changes)\n            changesCache.set(stateKey, encodedResult)\n\n          subscriber.next(new Map(changesCache))\n        }\n      },\n      timeout\n    )\n\n    return () => {\n      promUnsub.then((unsub) => unsub(\"state_unsubscribeStorage\"))\n    }\n  })\n\nexport const getRpcQueryPack$ = <T>(\n  connector: IChainConnectorDot,\n  networkId: DotNetworkId,\n  queries: RpcQueryPack<T>[],\n  timeout: number | false = false\n): Observable<T[]> => {\n  const allStateKeys = queries.flatMap(({ stateKeys }) => stateKeys).filter(isNotNil)\n\n  // doing a query without keys would throw an error => return early\n  if (!allStateKeys.length)\n    return of(queries.map(({ stateKeys, decodeResult }) => decodeResult(stateKeys.map(() => null))))\n\n  // decode and emit results for all queries, chunked with latest-wins semantics: the\n  // per-query SCALE decode yields the thread on budget, and when a new block's changes\n  // arrive mid-decode the in-flight decode is aborted (the new snapshot contains the\n  // aborted block's changes too, so nothing is lost — emissions coalesce under load)\n  return getRawStorageUpdates$(connector, networkId, allStateKeys, timeout).pipe(\n    switchMapChunked(\n      (changesByKey, { slicer }) => decodeRpcQueryPackChunked(queries, changesByKey, { slicer }),\n      { label: `decode ${networkId}` }\n    )\n  )\n}\n\nconst decodeRpcQueryPackChunked = <T>(\n  queries: RpcQueryPack<T>[],\n  changesByKey: ChangesByKey,\n  options?: ChunkedOptions\n): Promise<T[]> =>\n  mapWithYield(\n    queries,\n    ({ stateKeys, decodeResult }) =>\n      decodeResult(stateKeys.map((stateKey) => (stateKey && changesByKey.get(stateKey)) ?? null)),\n    options\n  )\n","import { evmErc20TokenId, type NetworkList, type TokenList } from \"@talismn/chaindata-provider\"\nimport {\n  newTokenRates,\n  type TokenRateCurrency,\n  type TokenRates,\n  type TokenRatesList,\n} from \"@talismn/token-rates\"\nimport {\n  BigMath,\n  isArrayOf,\n  isBigInt,\n  type NonFunctionProperties,\n  planckToTokens,\n} from \"@talismn/util\"\nimport BigNumber from \"../configureBigNumber\"\n\nimport log from \"../log\"\nimport type {\n  Amount,\n  AmountWithLabel,\n  BalanceJson,\n  BalanceJsonList,\n  BalanceStatusTypes,\n  ExtraAmount,\n  IBalance,\n  LockedAmount,\n} from \"./balancetypes\"\n\ntype FormattedAmount<GenericAmount extends AmountWithLabel<TLabel>, TLabel extends string> = Omit<\n  GenericAmount,\n  \"amount\"\n> & {\n  amount: BalanceFormatter\n}\n\nexport function excludeFromTransferableAmount(\n  locks:\n    | Amount\n    | FormattedAmount<LockedAmount<string>, string>\n    | Array<FormattedAmount<LockedAmount<string>, string>>\n): bigint {\n  if (typeof locks === \"string\") return BigInt(locks)\n  if (!Array.isArray(locks)) locks = [locks]\n\n  return locks\n    .filter((lock) => lock.includeInTransferable !== true)\n    .map((lock) => lock.amount.planck)\n    .reduce((max, lock) => BigMath.max(max, lock), 0n)\n}\n\nexport function excludeFromFeePayableLocks(\n  locks: Amount | LockedAmount<string> | Array<LockedAmount<string>>\n): Array<LockedAmount<string>> {\n  if (typeof locks === \"string\") return []\n  if (!Array.isArray(locks)) locks = [locks]\n\n  return locks.filter((lock) => lock.excludeFromFeePayable)\n}\n\nexport function includeInTotalExtraAmount(\n  extra?:\n    | FormattedAmount<ExtraAmount<string>, string>\n    | Array<FormattedAmount<ExtraAmount<string>, string>>\n): bigint {\n  if (!extra) return 0n\n  if (!Array.isArray(extra)) extra = [extra]\n\n  return extra\n    .filter((extra) => extra.includeInTotal)\n    .map((extra) => extra.amount.planck)\n    .reduce((a, b) => a + b, 0n)\n}\n\n/** A utility type used to extract the underlying `BalanceType` of a specific source from a generalised `BalanceJson` */\nexport type NarrowBalanceType<S extends IBalance, P> = S extends { source: P } ? S : never\nexport type BalanceSource = BalanceJson[\"source\"]\n\n/** TODO: Remove this in favour of a frontend-friendly `ChaindataProvider` */\nexport type HydrateDb = Partial<{\n  networks: NetworkList\n  tokens: TokenList\n  tokenRates: TokenRatesList\n}>\n\nexport type BalanceSearchQuery =\n  | Partial<NonFunctionProperties<Balance>>\n  | ((balance: Balance) => boolean)\n\n/**\n * A collection of balances.\n */\nexport class Balances {\n  //\n  // Properties\n  //\n\n  #balancesMap: Map<string, Balance> = new Map()\n  #cachedArray: Balance[] | null = null\n  #cachedFilteredMirrorTokens: Balances | null = null\n  #cachedSumFormatter: SumBalancesFormatter | null = null\n\n  //\n  // Methods\n  //\n\n  constructor(\n    balances: Balances | BalanceJsonList | Balance[] | IBalance[] | BalanceJson[] | Balance,\n    hydrate?: HydrateDb\n  ) {\n    // biome-ignore lint/correctness/noConstructorReturn: legacy\n    if (balances == null) return this\n\n    // handle Balances (convert to Balance[])\n    // biome-ignore lint/correctness/noConstructorReturn: legacy\n    if (balances instanceof Balances) return new Balances([...balances], hydrate)\n\n    // handle Balance (convert to Balance[])\n    // biome-ignore lint/correctness/noConstructorReturn: legacy\n    if (balances instanceof Balance) return new Balances([balances], hydrate)\n\n    // handle BalanceJsonList (the only remaining non-array type of balances) (convert to BalanceJson[])\n    // biome-ignore lint/correctness/noConstructorReturn: legacy\n    if (!Array.isArray(balances)) return new Balances(Object.values(balances), hydrate)\n\n    // handle no balances\n    // biome-ignore lint/correctness/noConstructorReturn: legacy\n    if (balances.length === 0) return this\n\n    // handle BalanceJson[]\n    if (!isArrayOf(balances, Balance))\n      // biome-ignore lint/correctness/noConstructorReturn: legacy\n      return new Balances(\n        balances.map((storage) => new Balance(storage)),\n        hydrate\n      )\n\n    // handle Balance[]\n    this.#balancesMap = new Map(balances.map((b) => [b.id, b]))\n    if (hydrate !== undefined) this.hydrate(hydrate)\n  }\n\n  /**\n   * Calling toJSON on a collection of balances will return the underlying BalanceJsonList.\n   */\n  toJSON = (): BalanceJsonList =>\n    Object.fromEntries(\n      [...this.#balancesMap.values()]\n        .map((balance) => {\n          try {\n            return [balance.id, balance.toJSON()]\n          } catch (error) {\n            log.error(\"Failed to convert balance to JSON\", error, { id: balance.id, balance })\n            return null\n          }\n        })\n        .filter(Array.isArray)\n    );\n\n  /**\n   * Allows the collection to be iterated over.\n   *\n   * @example\n   * [...balances].forEach(balance => { // do something // })\n   *\n   * @example\n   * for (const balance of balances) {\n   *   // do something\n   * }\n   */\n  [Symbol.iterator] = () => this.#balancesMap.values()[Symbol.iterator]()\n\n  /**\n   * Hydrates all balances in this collection.\n   *\n   * @param sources - The sources to hydrate from.\n   */\n  hydrate = (sources: HydrateDb) => {\n    // Invalidate caches — hydrate mutates Balance objects, so derived caches become stale\n    this.#cachedArray = null\n    this.#cachedFilteredMirrorTokens = null\n    this.#cachedSumFormatter = null\n    for (const balance of this.#balancesMap.values()) balance.hydrate(sources)\n  }\n\n  /**\n   * Retrieve a balance from this collection by id.\n   *\n   * @param id - The id of the balance to fetch.\n   * @returns The balance if one exists, or none.\n   */\n  get = (id: string): Balance | null => this.#balancesMap.get(id) ?? null\n\n  /**\n   * Retrieve balances from this collection by search query.\n   *\n   * @param query - The search query.\n   * @returns All balances which match the query.\n   */\n  find = (query: BalanceSearchQuery | BalanceSearchQuery[]): Balances => {\n    // construct filter\n    const queryArray: BalanceSearchQuery[] = Array.isArray(query) ? query : [query]\n    const orQueries = queryArray.map((query) =>\n      typeof query === \"function\" ? query : Object.entries(query)\n    )\n\n    // filter balances\n    const filter = (balance: Balance) =>\n      orQueries.some((query) =>\n        typeof query === \"function\"\n          ? query(balance)\n          : query.every(([key, value]) => balance[key as keyof BalanceSearchQuery] === value)\n      )\n\n    // return filter matches\n    return new Balances(this.#toArray().filter(filter))\n  }\n\n  /**\n   * Filters this collection to exclude token balances where the token has a `mirrorOf` field\n   * and another balance exists in this collection for the token specified by the `mirrorOf` field.\n   */\n  filterMirrorTokens = (): Balances => {\n    if (!this.#cachedFilteredMirrorTokens) {\n      const balances = this.#toArray()\n      const tokenIds = new Set<string>()\n      for (const b of balances) {\n        if (b.tokenId) tokenIds.add(b.tokenId)\n      }\n      this.#cachedFilteredMirrorTokens = new Balances(\n        balances.filter((balance) => {\n          const mirrorOf = balance.token?.mirrorOf\n          return !mirrorOf || !tokenIds.has(mirrorOf)\n        })\n      )\n    }\n    return this.#cachedFilteredMirrorTokens\n  }\n\n  /**\n   * Filters this collection to only include balances which are not zero AND have a fiat conversion rate.\n   */\n  filterNonZeroFiat = (\n    type:\n      | \"total\"\n      | \"free\"\n      | \"reserved\"\n      | \"locked\"\n      | \"frozen\"\n      | \"transferable\"\n      | \"unavailable\"\n      | \"feePayable\",\n    currency: TokenRateCurrency\n  ): Balances => {\n    const filter = (balance: Balance) => (balance[type].fiat(currency) ?? 0) > 0\n    return this.find(filter)\n  }\n\n  /**\n   * Add some balances to this collection.\n   * Added balances take priority over existing balances.\n   * The aggregation of the two collections is returned.\n   * The original collection is not mutated.\n   *\n   * @param balances - Either a balance or collection of balances to add.\n   * @returns The new collection of balances.\n   */\n  add = (balances: Balances | Balance): Balances => {\n    if (balances instanceof Balance) return this.add(new Balances(balances))\n    const mergedMap = new Map(this.#balancesMap)\n    for (const balance of balances) mergedMap.set(balance.id, balance)\n    return new Balances([...mergedMap.values()])\n  }\n\n  /**\n   * Remove balances from this collection by id.\n   * A new collection without these balances is returned.\n   * The original collection is not mutated.\n   *\n   * @param ids - The id(s) of the balances to remove.\n   * @returns The new collection of balances.\n   */\n  remove = (ids: string[] | string): Balances => {\n    if (!Array.isArray(ids)) return this.remove([ids])\n    const idSet = new Set(ids)\n    return new Balances(this.#toArray().filter((balance) => !idSet.has(balance.id)))\n  }\n\n  // TODO: Add some more useful aggregator methods\n\n  #toArray = (): Balance[] => {\n    if (!this.#cachedArray) this.#cachedArray = [...this.#balancesMap.values()]\n    return this.#cachedArray\n  }\n\n  get each() {\n    return this.#toArray()\n  }\n\n  /** @deprecated use each instead */\n  get sorted() {\n    return this.each\n  }\n\n  /**\n   * Get the number of balances in this collection.\n   *\n   * @returns The number of balances in this collection.\n   */\n  get count() {\n    return this.#balancesMap.size\n  }\n\n  /**\n   * Get the summed value of balances in this collection.\n   * TODO: Sum up token amounts AND fiat amounts\n   *\n   * @example\n   * // Get the sum of all transferable balances in usd.\n   * balances.sum.fiat('usd').transferable\n   */\n  get sum() {\n    if (!this.#cachedSumFormatter) this.#cachedSumFormatter = new SumBalancesFormatter(this)\n    return this.#cachedSumFormatter\n  }\n}\n\nexport const getBalanceId = (balance: Pick<IBalance, \"address\" | \"tokenId\">) => {\n  const { address, tokenId } = balance\n  return [address, tokenId].join(\"::\")\n}\n\n/**\n * An individual balance.\n */\nexport class Balance {\n  //\n  // Properties\n  //\n\n  /** The underlying data for this balance */\n  readonly #storage: BalanceJson\n  readonly #valueGetter: BalanceValueGetter\n\n  #db: HydrateDb | null = null\n\n  // lazily-computed caches for the hot accessors: sorting/summing/filtering loops read\n  // these repeatedly, and each uncached access re-derives values and allocates several\n  // BalanceFormatters. `undefined` = not yet computed. #storage is immutable in practice\n  // (the only mutator, addValue, is unused legacy), so caches only invalidate when the\n  // hydrate db changes (rates/tokens affect every derived value).\n  #cachedRates: TokenRates | null | undefined = undefined\n  #cachedTotal: BalanceFormatter | undefined = undefined\n  #cachedFree: BalanceFormatter | undefined = undefined\n  #cachedReserved: BalanceFormatter | undefined = undefined\n  #cachedLocked: BalanceFormatter | undefined = undefined\n  #cachedTransferable: BalanceFormatter | undefined = undefined\n  #cachedUnavailable: BalanceFormatter | undefined = undefined\n  #cachedFeePayable: BalanceFormatter | undefined = undefined\n\n  #invalidateComputed = () => {\n    this.#cachedRates = undefined\n    this.#cachedTotal = undefined\n    this.#cachedFree = undefined\n    this.#cachedReserved = undefined\n    this.#cachedLocked = undefined\n    this.#cachedTransferable = undefined\n    this.#cachedUnavailable = undefined\n    this.#cachedFeePayable = undefined\n  }\n\n  //\n  // Methods\n  //\n\n  constructor(storage: BalanceJson | IBalance, hydrate?: HydrateDb) {\n    this.#storage = storage as BalanceJson\n    this.#valueGetter = new BalanceValueGetter(this.#storage)\n    if (hydrate !== undefined) this.hydrate(hydrate)\n  }\n\n  toJSON = (): BalanceJson => this.#storage\n\n  isSource = (source: BalanceSource) => this.#storage.source === source\n  // // TODO: Fix this method, the types don't work with our plugin architecture.\n  // // Specifically, the `BalanceJson` type is compiled down to `IBalance` in the following way:\n  // //\n  // //     toJSON: () => BalanceJson // works\n  // //     isSource: (source: BalanceSource) => boolean // works\n  // //     asSource: <P extends string>(source: P) => NarrowBalanceType<IBalance, P> | null // Doesn't work! IBalance should just be BalanceJson!\n  // //\n  // // `IBalance` won't match the type of `BalanceSource` after `PluginBalanceTypes` has been extended by balance plugins.\n  // // As a result, typescript will think that the returned #storage is not a BalanceJson.\n  // asSource = <P extends BalanceSource>(source: P): NarrowBalanceType<BalanceJson, P> | null => {\n  //   if (this.#storage.source === source) return this.#storage as NarrowBalanceType<BalanceJson, P>\n  //   return null\n  // }\n\n  hydrate = (hydrate?: HydrateDb) => {\n    if (hydrate !== undefined && hydrate !== this.#db) {\n      this.#db = hydrate\n      this.#invalidateComputed()\n    }\n  }\n\n  #format = (balance: bigint | string) =>\n    new BalanceFormatter(\n      isBigInt(balance) ? balance.toString() : balance,\n      this.decimals || undefined,\n      this.rates\n    )\n\n  //\n  // Accessors\n  //\n\n  get id(): string {\n    return getBalanceId(this.#storage)\n  }\n\n  get source() {\n    return this.#storage.source\n  }\n\n  get status() {\n    return this.#storage.status\n  }\n\n  get address() {\n    return this.#storage.address\n  }\n\n  get networkId() {\n    return this.#storage.networkId\n  }\n\n  get network() {\n    return this.#db?.networks?.[this.networkId] || null\n  }\n\n  get tokenId() {\n    return this.#storage.tokenId\n  }\n  get token() {\n    return this.#db?.tokens?.[this.tokenId] || null\n  }\n  get decimals() {\n    return this.token?.decimals || null\n  }\n  get rates(): TokenRates | null {\n    if (this.#cachedRates === undefined) this.#cachedRates = this.#computeRates()\n    return this.#cachedRates\n  }\n\n  #computeRates = (): TokenRates | null => {\n    // uniswap v2 lp tokens need the rates from the underlying pool assets\n    //\n    // To note: `@talismn/token-rates` knows to fetch the `coingeckoId0` and `coingeckoId1` rates for evm-uniswapv2 tokens.\n    // They are then stored in `this.#db.tokenRates` using the `tokenId0` and `tokenId1` keys.\n    //\n    // This means that those rates are always available for calculating the uniswapv2 rates,\n    // regardless of whether or not the underlying erc20s are actually in chaindata and enabled.\n    if (this.isSource(\"evm-uniswapv2\") && this.token?.type === \"evm-uniswapv2\") {\n      const tokenId0 = evmErc20TokenId(this.networkId, this.token.tokenAddress0)\n      const tokenId1 = evmErc20TokenId(this.networkId, this.token.tokenAddress1)\n\n      const decimals = this.token.decimals\n      const decimals0 = this.token.decimals0\n      const decimals1 = this.token.decimals1\n\n      const rates0 = this.#db?.tokenRates?.[tokenId0]\n      const rates1 = this.#db?.tokenRates?.[tokenId1]\n\n      if (rates0 === undefined || rates1 === undefined) return null\n\n      const extra = this.#valueGetter.get(\"extra\")\n      const extras = Array.isArray(extra) ? extra : extra !== undefined ? [extra] : []\n      const totalSupply = extras.find((extra) => extra.label === \"totalSupply\")?.amount ?? \"0\"\n      const reserve0 = extras.find((extra) => extra.label === \"reserve0\")?.amount ?? \"0\"\n      const reserve1 = extras.find((extra) => extra.label === \"reserve1\")?.amount ?? \"0\"\n\n      const totalSupplyTokens = BigNumber(totalSupply).times(10 ** (-1 * decimals))\n      const reserve0Tokens = BigNumber(reserve0).times(10 ** (-1 * decimals0))\n      const reserve1Tokens = BigNumber(reserve1).times(10 ** (-1 * decimals1))\n\n      const rates0Currencies = new Set(Object.keys(rates0) as TokenRateCurrency[])\n      const rates1Currencies = new Set(Object.keys(rates1) as TokenRateCurrency[])\n      // `Set.prototype.intersection` can eventually replace this\n      // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/intersection\n      const currencies = [...rates0Currencies].filter((c) => rates1Currencies.has(c))\n\n      const totalValueLocked = currencies.map(\n        (currency) =>\n          [\n            currency,\n            // tvl (in a given currency) == reserve0*currencyRate0 + reserve1*currencyRate1\n            BigNumber.sum(\n              reserve0Tokens.times(rates0[currency]?.price ?? 0),\n              reserve1Tokens.times(rates1[currency]?.price ?? 0)\n            ),\n          ] as const\n      )\n\n      const lpTokenRates = newTokenRates()\n      totalValueLocked.forEach(([currency, tvl]) => {\n        // divide `the value of all lp tokens` by `the number of lp tokens` to get `the value per token`\n        if (!totalSupplyTokens.eq(0))\n          lpTokenRates[currency] = { price: tvl.div(totalSupplyTokens).toNumber() }\n      })\n\n      return lpTokenRates\n    }\n\n    // other tokens (including dtao alpha tokens, whose rates the host computes from the\n    // subnet pool price) can just pick from the tokenRates db using the tokenId\n    return this.#db?.tokenRates?.[this.tokenId] || null\n  }\n\n  /**\n   * A general method to get formatted values matching a certain type from this balance.\n   * @param valueType - The type of value to get.\n   * @returns An array of the values matching the type with formatted amounts.\n   */\n  private getValue(\n    valueType: BalanceStatusTypes\n  ): Array<FormattedAmount<AmountWithLabel<string>, string>> {\n    return this.getRawValue(valueType).map((value) => ({\n      ...value,\n      amount: this.#format(value.amount),\n    }))\n  }\n\n  /**\n   * A general method to get values matching a certain type from this balance.\n   * @param valueType - The type of value to get.\n   * @returns An array of the values matching the type.\n   */\n  private getRawValue(valueType: BalanceStatusTypes): Array<AmountWithLabel<string>> {\n    return this.#valueGetter.get(valueType)\n  }\n\n  /**\n   * A general method to add a value to the array of values for this balance.\n   * @param valueType - The type of value to add.\n   * @returns A function which can be used to add a value to the array of values for this balance.\n   */\n\n  // biome-ignore lint/correctness/noUnusedPrivateClassMembers: legacy\n  private addValue(valueType: BalanceStatusTypes) {\n    return (value: Omit<AmountWithLabel<string>, \"type\">) => this.#valueGetter.add(valueType, value)\n  }\n  /**\n   * The total balance of this token.\n   * Includes the free and the reserved amount.\n   * The balance will be reaped if this goes below the existential deposit.\n   */\n  get total() {\n    if (this.#cachedTotal === undefined) this.#cachedTotal = this.#computeTotal()\n    return this.#cachedTotal\n  }\n\n  #computeTotal = () => {\n    const extra = this.getValue(\"extra\") as FormattedAmount<ExtraAmount<string>, string>[]\n\n    // if there is a DelegatedStaking hold (new model: polkadot, kusama), nom pool staked amount is included in reserved\n    // if not (old model: vara, avail, cere), staked amount is not in the account and it needs to be added to the total\n    const nomPoolStakedPlancks = this.locks.some(\n      (lock) => lock.source === \"substrate-native-holds\" && lock.label === \"DelegatedStaking\"\n    )\n      ? 0n\n      : this.nompools.map(({ amount }) => amount.planck).reduce((a, b) => a + b, 0n)\n\n    return this.#format(\n      this.free.planck +\n        this.reserved.planck +\n        nomPoolStakedPlancks +\n        includeInTotalExtraAmount(extra)\n    )\n  }\n  /** The non-reserved balance of this token. Includes the frozen amount. Is included in the total. */\n  get free() {\n    if (this.#cachedFree === undefined) this.#cachedFree = this.#computeFree()\n    return this.#cachedFree\n  }\n\n  #computeFree = () => {\n    // for simple balances\n    if (\"value\" in this.#storage && this.#storage.value) return this.#format(this.#storage.value)\n\n    // for complex balances\n    const freeValues = this.getValue(\"free\")\n    const totalFree = freeValues.map(({ amount }) => amount.planck).reduce((a, b) => a + b, 0n)\n    return this.#format(totalFree)\n  }\n  /** The reserved balance of this token. Is included in the total. */\n  get reserved() {\n    if (this.#cachedReserved === undefined) this.#cachedReserved = this.#computeReserved()\n    return this.#cachedReserved\n  }\n\n  #computeReserved = () => {\n    const reservedValues = this.getValue(\"reserved\")\n    if (reservedValues.length === 0) return this.#format(0n)\n\n    return this.#format(\n      reservedValues.map(({ amount }) => amount.planck).reduce((a, b) => a + b, 0n)\n    )\n  }\n  get reserves() {\n    return this.getValue(\"reserved\")\n  }\n  /** The frozen balance of this token. Is included in the free amount. */\n  get locked() {\n    if (this.#cachedLocked === undefined)\n      this.#cachedLocked = this.#format(\n        this.locks.map(({ amount }) => amount.planck).reduce((a, b) => BigMath.max(a, b), 0n)\n      )\n    return this.#cachedLocked\n  }\n\n  get locks() {\n    return this.getValue(\"locked\")\n  }\n\n  get nompools() {\n    return this.getValue(\"nompool\")\n  }\n\n  /** The extra balance of this token */\n  get extra() {\n    const extra = this.getRawValue(\"extra\")\n    if (extra.length > 0) return extra as ExtraAmount<string>[]\n    return undefined\n  }\n\n  /** @deprecated Use balance.locked */\n  get frozen() {\n    return this.locked\n  }\n  /** The transferable balance of this token. Is generally the free amount - the miscFrozen amount. */\n  get transferable() {\n    if (this.#cachedTransferable === undefined)\n      this.#cachedTransferable = this.#computeTransferable()\n    return this.#cachedTransferable\n  }\n\n  #computeTransferable = () => {\n    /**\n     * As you can see here, `locked` is subtracted from `free` in order to derive `transferable`.\n     *\n     * |--------------------------total--------------------------|\n     * |-------------------free-------------------|---reserved---|\n     * |----locked-----|-------transferable-------|\n     */\n    const oldTransferableCalculation = () => {\n      // if no locks exist, transferable is equal to the free amount\n      if (this.locks.length === 0) return this.free\n\n      // find the largest lock (but ignore any locks which are marked as `includeInTransferable`)\n      const excludeAmount = excludeFromTransferableAmount(this.locks)\n\n      // subtract the lock from the free amount (but don't go below 0)\n      return this.#format(BigMath.max(this.free.planck - excludeAmount, 0n))\n    }\n\n    /**\n     * As you can see here, `locked` is subtracted from `free + reserved` in order to derive `transferable`.\n     *\n     * Alternatively, `reserved` is subtracted from `locked` in order to derive `untouchable`,\n     * which is then subtracted from `free` in order to derive `transferable`.\n     *\n     * |--------------------------total--------------------------|\n     * |---reserved---|-------------------free-------------------|\n     *                |--untouchable--|\n     * |------------locked------------|-------transferable-------|\n     */\n    const newTransferableCalculation = () => {\n      // if no locks exist, transferable is equal to the free amount\n      if (this.locks.length === 0) return this.free\n\n      // find the largest lock (but ignore any locks which are marked as `includeInTransferable`)\n      // subtract the reserved amount, because locks now act upon the total balance - not just the free balance\n      const untouchableAmount = BigMath.max(\n        excludeFromTransferableAmount(this.locks) - this.reserved.planck,\n        0n\n      )\n\n      // subtract the untouchable amount from the free amount (but don't go below 0)\n      return this.#format(BigMath.max(this.free.planck - untouchableAmount, 0n))\n    }\n\n    if (this.#storage.useLegacyTransferableCalculation) return oldTransferableCalculation()\n    return newTransferableCalculation()\n  }\n  /**\n   * The unavailable balance of this token.\n   * Prior to the Fungible trait, this was the locked amount + the reserved amount, i.e. `locked + reserved`.\n   * Now, it is the bigger of the locked amount and the reserved amounts, i.e. `max(locked, reserved)`.\n   */\n  get unavailable() {\n    if (this.#cachedUnavailable === undefined) this.#cachedUnavailable = this.#computeUnavailable()\n    return this.#cachedUnavailable\n  }\n\n  #computeUnavailable = () => {\n    const oldCalculation = () => this.locked.planck + this.reserved.planck\n    const newCalculation = () => BigMath.max(this.locked.planck, this.reserved.planck)\n    const baseUnavailable = this.#storage.useLegacyTransferableCalculation\n      ? oldCalculation()\n      : newCalculation()\n\n    // if there is a DelegatedStaking hold (new model: polkadot, kusama), nom pool staked amount is included in reserved\n    // if not (old model: vara, avail, cere), staked amount is not in the account and it needs to be added to the total\n    const nomPoolStakedPlancks = this.locks.some(\n      (lock) => lock.source === \"substrate-native-holds\" && lock.label === \"DelegatedStaking\"\n    )\n      ? 0n\n      : this.nompools.map(({ amount }) => amount.planck).reduce((a, b) => a + b, 0n)\n\n    return this.#format(baseUnavailable + nomPoolStakedPlancks)\n  }\n\n  /** The feePayable balance of this token. Is generally the free amount - the feeFrozen amount. */\n  get feePayable() {\n    if (this.#cachedFeePayable === undefined) this.#cachedFeePayable = this.#computeFeePayable()\n    return this.#cachedFeePayable\n  }\n\n  #computeFeePayable = () => {\n    // if no locks exist, feePayable is equal to the free amount\n    if (this.locks.length === 0) return this.free\n\n    // find the largest lock which can't be used to pay tx fees\n    const excludeAmount = excludeFromFeePayableLocks(this.locked.planck.toString())\n      .map((lock) => BigInt(lock.amount))\n      .reduce((max, lock) => BigMath.max(max, lock), 0n)\n\n    // subtract the lock from the free amount (but don't go below 0)\n    return this.#format(BigMath.max(this.free.planck - excludeAmount, 0n))\n  }\n}\n\n/** raw values of a given type, straight from the IBalance JSON (no Balance/formatter allocation) */\nconst getRawValues = (\n  balance: IBalance,\n  valueType: BalanceStatusTypes\n): AmountWithLabel<string>[] =>\n  \"values\" in balance && balance.values\n    ? balance.values.filter(({ type }) => type === valueType)\n    : []\n\n/** raw \"locked\" values, straight from the IBalance JSON (see getRawTotalPlanck) */\nexport const getRawLocks = (balance: IBalance): AmountWithLabel<string>[] =>\n  getRawValues(balance, \"locked\")\n\nconst sumPlancks = (values: AmountWithLabel<string>[]): bigint =>\n  values.reduce((sum, { amount }) => sum + BigInt(amount), 0n)\n\n/**\n * Computes `new Balance(b).total.planck` without constructing a Balance (which allocates\n * several BalanceFormatters per access) — used for high-frequency zero-balance filtering.\n * MUST mirror Balance.total exactly, including the DelegatedStaking-hold/nompool rule\n * (guarded by a parity test in balance-raw-helpers.test.ts).\n */\nexport const getRawTotalPlanck = (balance: IBalance): bigint => {\n  const free =\n    \"value\" in balance && balance.value\n      ? BigInt(balance.value)\n      : sumPlancks(getRawValues(balance, \"free\"))\n  const reserved = sumPlancks(getRawValues(balance, \"reserved\"))\n\n  // if there is a DelegatedStaking hold (new model: polkadot, kusama), nom pool staked amount is included in reserved\n  // if not (old model: vara, avail, cere), staked amount is not in the account and it needs to be added to the total\n  const nomPoolStakedPlancks = getRawLocks(balance).some(\n    (lock) => lock.source === \"substrate-native-holds\" && lock.label === \"DelegatedStaking\"\n  )\n    ? 0n\n    : sumPlancks(getRawValues(balance, \"nompool\"))\n\n  const extra = (getRawValues(balance, \"extra\") as ExtraAmount<string>[])\n    .filter((extra) => extra.includeInTotal)\n    .reduce((sum, { amount }) => sum + BigInt(amount), 0n)\n\n  return free + reserved + nomPoolStakedPlancks + extra\n}\n\nexport class BalanceValueGetter {\n  #storage: BalanceJson\n\n  constructor(storage: BalanceJson) {\n    this.#storage = storage\n  }\n\n  get(valueType: BalanceStatusTypes) {\n    if (\"values\" in this.#storage && this.#storage.values)\n      return this.#storage.values.filter(({ type }) => type === valueType)\n    return []\n  }\n\n  add(valueType: BalanceStatusTypes, amount: Omit<AmountWithLabel<string>, \"type\">) {\n    if (\"values\" in this.#storage && this.#storage.values)\n      this.#storage.values.push({ type: valueType, ...amount })\n  }\n}\n\nexport class BalanceFormatter {\n  #planck: string\n  #decimals: number\n  #tokenRates: TokenRates | null\n\n  constructor(\n    planck: string | bigint | undefined,\n    decimals?: number | undefined,\n    fiatRatios?: TokenRates | null\n  ) {\n    this.#planck = isBigInt(planck) ? planck.toString() : (planck ?? \"0\")\n    this.#decimals = decimals || 0\n    this.#tokenRates = fiatRatios || null\n  }\n\n  toJSON = () => this.#planck\n\n  get planck() {\n    return BigInt(this.#planck)\n  }\n\n  get tokens() {\n    return planckToTokens(this.#planck, this.#decimals)\n  }\n\n  fiat(currency: TokenRateCurrency) {\n    if (!this.#tokenRates) return null\n\n    const ratio = this.#tokenRates[currency]\n    if (!ratio) return null\n\n    return parseFloat(this.tokens) * ratio.price\n  }\n}\n\nexport class PlanckSumBalancesFormatter {\n  #balances: Balances\n\n  constructor(balances: Balances) {\n    this.#balances = balances\n  }\n\n  #sum = (\n    balanceField: {\n      [K in keyof Balance]: Balance[K] extends BalanceFormatter ? K : never\n    }[keyof Balance]\n  ) => {\n    // a function to get a planck amount from a balance\n    const planck = (balance: Balance) => balance[balanceField].planck ?? 0n\n\n    return this.#balances.filterMirrorTokens().each.reduce(\n      // add the total amount to the planck amount of each balance\n      (total, balance) => total + planck(balance),\n      // start with a total of 0\n      0n\n    )\n  }\n\n  /**\n   * The total balance of these tokens. Includes the free and the reserved amount.\n   */\n  get total() {\n    return this.#sum(\"total\")\n  }\n  /** The non-reserved balance of these tokens. Includes the frozen amount. Is included in the total. */\n  get free() {\n    return this.#sum(\"free\")\n  }\n  /** The reserved balance of these tokens. Is included in the total. */\n  get reserved() {\n    return this.#sum(\"reserved\")\n  }\n  /** The frozen balance of these tokens. Is included in the free amount. */\n  get locked() {\n    return this.#sum(\"locked\")\n  }\n  /** @deprecated Use balances.locked */\n  get frozen() {\n    return this.locked\n  }\n  /** The transferable balance of these tokens. Is generally the free amount - the miscFrozen amount. */\n  get transferable() {\n    return this.#sum(\"transferable\")\n  }\n  /** The unavailable balance of these tokens. */\n  get unavailable() {\n    return this.#sum(\"unavailable\")\n  }\n\n  /** The feePayable balance of these tokens. Is generally the free amount - the feeFrozen amount. */\n  get feePayable() {\n    return this.#sum(\"feePayable\")\n  }\n}\n\nexport class FiatSumBalancesFormatter {\n  #balances: Balances\n  #currency: TokenRateCurrency\n\n  constructor(balances: Balances, currency: TokenRateCurrency) {\n    this.#balances = balances\n    this.#currency = currency\n  }\n\n  #sum = (\n    balanceField: {\n      [K in keyof Balance]: Balance[K] extends BalanceFormatter ? K : never\n    }[keyof Balance]\n  ) => {\n    // a function to get a fiat amount from a balance\n    const fiat = (balance: Balance) => balance[balanceField].fiat(this.#currency) ?? 0\n\n    return this.#balances.filterMirrorTokens().each.reduce(\n      // add the total amount to the fiat amount of each balance\n      (total, balance) => total + fiat(balance),\n      // start with a total of 0\n      0\n    )\n  }\n\n  /**\n   * The total balance of these tokens. Includes the free and the reserved amount.\n   */\n  get total() {\n    return this.#sum(\"total\")\n  }\n  /** The non-reserved balance of these tokens. Includes the frozen amount. Is included in the total. */\n  get free() {\n    return this.#sum(\"free\")\n  }\n  /** The reserved balance of these tokens. Is included in the total. */\n  get reserved() {\n    return this.#sum(\"reserved\")\n  }\n  /** The frozen balance of these tokens. Is included in the free amount. */\n  get locked() {\n    return this.#sum(\"locked\")\n  }\n  /** @deprecated Use balances.locked */\n  get frozen() {\n    return this.locked\n  }\n  /** The transferable balance of these tokens. Is generally the free amount - the miscFrozen amount. */\n  get transferable() {\n    return this.#sum(\"transferable\")\n  }\n  /** The unavailable balance of these tokens. */\n  get unavailable() {\n    return this.#sum(\"unavailable\")\n  }\n  /** The feePayable balance of these tokens. Is generally the free amount - the feeFrozen amount. */\n  get feePayable() {\n    return this.#sum(\"feePayable\")\n  }\n}\n\nexport class SumBalancesFormatter {\n  #balances: Balances\n\n  constructor(balances: Balances) {\n    this.#balances = balances\n  }\n\n  get planck() {\n    return new PlanckSumBalancesFormatter(this.#balances)\n  }\n\n  fiat(currency: TokenRateCurrency) {\n    return new FiatSumBalancesFormatter(this.#balances, currency)\n  }\n\n  change24h(currency: TokenRateCurrency) {\n    return new Change24hCurrencyFormatter(this.#balances, currency)\n  }\n}\n\nexport class Change24hCurrencyFormatter {\n  #balances: Balances\n  #currency: TokenRateCurrency\n\n  constructor(balances: Balances, currency: TokenRateCurrency) {\n    this.#balances = balances\n    this.#currency = currency\n  }\n\n  #change24h = (\n    balanceField: {\n      [K in keyof Balance]: Balance[K] extends BalanceFormatter ? K : never\n    }[keyof Balance]\n  ) => {\n    const output = this.#balances.filterMirrorTokens().each.reduce(\n      // add the total amount to the fiat amount of each balance\n      (acc, balance) => {\n        const change24h = balance.rates?.[this.#currency]?.change24h\n        if (typeof change24h !== \"number\") return acc\n        const fiat = balance[balanceField].fiat(this.#currency)\n        if (!fiat) return acc\n\n        return {\n          totalFiatDiff: acc.totalFiatDiff + fiat * change24h,\n          totalFiat: acc.totalFiat + fiat,\n        }\n      },\n      // start with a total of 0\n      { totalFiatDiff: 0, totalFiat: 0 }\n    )\n\n    return output.totalFiat === 0\n      ? null\n      : {\n          diff: output.totalFiatDiff / 100,\n          ratio: output.totalFiatDiff / output.totalFiat,\n        }\n  }\n\n  get total() {\n    return this.#change24h(\"total\")\n  }\n  get free() {\n    return this.#change24h(\"free\")\n  }\n  get reserved() {\n    return this.#change24h(\"reserved\")\n  }\n  get locked() {\n    return this.#change24h(\"locked\")\n  }\n  get frozen() {\n    return this.#change24h(\"frozen\")\n  }\n  get transferable() {\n    return this.#change24h(\"transferable\")\n  }\n  get unavailable() {\n    return this.#change24h(\"unavailable\")\n  }\n  get feePayable() {\n    return this.#change24h(\"feePayable\")\n  }\n}\n\nexport const filterMirrorTokens = (balance: Balance, _i: number, balances: Balance[]) => {\n  const mirrorOf = balance.token?.mirrorOf\n  return !mirrorOf || !balances.find((b) => b.tokenId === mirrorOf)\n}\n","import type { NetworkId, TokenId } from \"@talismn/chaindata-provider\"\n\nimport type { Address } from \"./addresses\"\n\nexport type BalanceStatus =\n  // balance is subscribed to the on-chain value and up to date\n  | \"live\"\n  // balance was retrieved from the chain and the stored value is being displayed.\n  // This balance is currently awaiting updates from the chain.\n  | \"cache\"\n  // balance was retrieved from the chain but we're unable to create a new subscription\n  | \"stale\"\n\ntype IBalanceBase = {\n  /** The module that this balance was retrieved by */\n  source: string\n\n  useLegacyTransferableCalculation?: boolean\n\n  /** Has this balance never been fetched, or is it from a cache, or is it up to date? */\n  status: BalanceStatus\n\n  /** The address of the account which owns this balance */\n  address: Address\n  /** The token this balance is for */\n  tokenId: TokenId\n\n  networkId: NetworkId\n}\n\ntype IBalanceSimpleValues = {\n  /** For balance types with a simple value, this is the value of the balance (eg, evm native token balance) */\n  value: Amount\n  values?: Array<AmountWithLabel<string>>\n}\n\ntype IBalanceComplexValues = {\n  /** For balance types with multple possible states, these are the values of the balance (eg, substrate native token balance) */\n  values: Array<AmountWithLabel<string>>\n  value?: undefined\n}\n\n/** `IBalance` is a common interface which all balance types must implement. */\nexport type IBalance = IBalanceBase & (IBalanceSimpleValues | IBalanceComplexValues)\n\nexport type BalanceJson = IBalance\n\n/** A collection of `BalanceJson` objects */\nexport type BalanceJsonList = Record<string, BalanceJson>\n\n/** An unlabelled amount of a balance */\nexport type Amount = string\n\nexport type BalanceStatusTypes = \"free\" | \"reserved\" | \"locked\" | \"extra\" | \"nompool\"\n\n/** A labelled amount of a balance */\ntype BaseAmountWithLabel<TLabel extends string> = {\n  type: BalanceStatusTypes\n  /**\n   * For modules which fetch balances via module sources, the source is equivalent to previous 'subSource' field\n   * on the parent balance object\n   * e.g. `staking`\n   **/\n  source?: string\n  label: TLabel\n  amount: Amount\n  meta?: unknown // TODO type this with an object that has a discriminator property\n}\n\nexport const getValueId = (amount: AmountWithLabel<string>) => {\n  const getMetaId = () => {\n    const meta = amount.meta as { poolId?: number; paraId?: number } | undefined\n    if (!meta) return \"\"\n    if (amount.type === \"nompool\") return meta.poolId?.toString() ?? \"\"\n\n    return \"\"\n  }\n\n  return [amount.label, amount.type, amount.source, getMetaId()].join(\"::\")\n}\n\n/** A labelled locked amount of a balance */\nexport type LockedAmount<TLabel extends string> = BaseAmountWithLabel<TLabel> & {\n  /**\n   * By default, the largest locked amount is subtrated from the transferable amount of this balance.\n   * If this property is set to true, this particular lock will be skipped when making this calculation.\n   * As such, this locked amount will be included in the calculated transferable amount.\n   */\n  includeInTransferable?: boolean\n\n  /**\n   * By default, tx fees can be deducted from locked amounts of balance.\n   * As such, locked amounts are ignored when calculating if the user has enough funds to pay tx fees.\n   * If this property is set to true, this particular lock will be subtracted from the available funds when making this calculation.\n   * As such, this locked amount will not be included in the calculated available funds.\n   */\n  excludeFromFeePayable?: boolean\n}\n\nexport type AmountWithLabel<TLabel extends string> =\n  | BaseAmountWithLabel<TLabel>\n  | LockedAmount<TLabel>\n  | ExtraAmount<TLabel>\n\n/** A labelled extra amount of a balance */\nexport type ExtraAmount<TLabel extends string> = BaseAmountWithLabel<TLabel> & {\n  type: \"extra\"\n  /** If set to true, this extra amount will be included in the calculation of the total amount of this balance. */\n  includeInTotal?: boolean\n}\n","import { type AnyMiniMetadata, MINIMETADATA_VERSION } from \"@talismn/chaindata-provider\"\nimport { Twox128, toHex } from \"@talismn/scale\"\n\n/** For fast db access, you can calculate the primary key for a miniMetadata using this method */\nexport const deriveMiniMetadataId = ({\n  source,\n  chainId,\n  specVersion,\n}: Pick<AnyMiniMetadata, \"source\" | \"chainId\" | \"specVersion\">): string =>\n  toHex(\n    Twox128(new TextEncoder().encode(`${source}${chainId}${specVersion}${MINIMETADATA_VERSION}`))\n  ).slice(-32)\n\nexport type MiniMetadata<Extra = unknown> = Omit<AnyMiniMetadata, \"extra\"> & { extra: Extra }\n","import type { MonoTypeOperatorFunction, Observable } from \"rxjs\"\nimport { defer, map } from \"rxjs\"\n\nimport type { IBalance } from \"../../types\"\nimport { getBalanceId } from \"../../types\"\nimport { getBalanceFingerprint } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults } from \"../../types/IBalanceModule\"\n\n/**\n * How a freshly fetched balance relates to the last EMITTED balance with the same id:\n * - \"equal\": no meaningful difference — keep emitting the previous object\n * - \"drift\": only continuously-moving values differ (e.g. an AMM price, an accruing\n *   dividend). Real, but not worth re-emitting on every poll — the stabilizer re-emits\n *   drift at most once per `driftRefreshMs`.\n * - \"changed\": a structural change (amounts, status, locks) — emit immediately\n */\nexport type BalanceEquivalence = \"equal\" | \"drift\" | \"changed\"\n\n/**\n * Optional module-specific equivalence for drift-prone values (e.g. substrate-dtao's\n * per-block AMM price). Called with the last EMITTED balance and the freshly fetched one\n * for the same balance id. Boolean returns are supported for simple comparators\n * (true = \"equal\", false = fall back to the exact fingerprint compare).\n */\nexport type IsEffectivelyEqualBalance = (\n  previous: IBalance,\n  next: IBalance\n) => boolean | BalanceEquivalence\n\nexport type BalanceStabilizerOptions = {\n  /**\n   * Minimum interval between emissions caused ONLY by \"drift\"-classified changes.\n   * Bounds both staleness (a drifting value is never more than this out of date once\n   * past the comparator's tolerance) and emission frequency (a fast-moving value can't\n   * force a re-emission on every poll).\n   */\n  driftRefreshMs?: number\n  /** injectable clock for tests; defaults to performance.now, falling back to Date.now */\n  now?: () => number\n}\n\nconst DEFAULT_DRIFT_REFRESH_MS = 30_000\n\nconst defaultNow: () => number =\n  typeof performance !== \"undefined\" ? () => performance.now() : () => Date.now()\n\n/**\n * Reuses the previous emission's IBalance object whenever the freshly fetched one is\n * equivalent, so that unchanged balances stay REFERENCE-STABLE across emissions.\n *\n * Why this matters: every fetch/decode allocates brand-new balance objects, and all\n * downstream change-detection (fingerprint WeakMaps, distinctUntilChanged item compares,\n * storage no-op detection, UI memoization) is keyed on object identity. With stable\n * references, a poll where one balance changed produces an array where the other N-1\n * items compare by `===` everywhere downstream.\n *\n * Equivalence checks, in order of cost:\n * 1. reference equality\n * 2. `isEffectivelyEqual` (when provided — cheap, targeted field compare; also lets\n *    modules classify sub-threshold or continuous movement as \"equal\"/\"drift\")\n * 3. fingerprint equality (WeakMap-cached JSON.stringify — exact)\n *\n * Because reuse is always judged against the last EMITTED object, tolerated drift\n * accumulates and re-emits once it crosses the module's threshold — and even then,\n * drift-only changes re-emit at most once per `driftRefreshMs`.\n */\nexport const createBalanceStabilizer = (\n  isEffectivelyEqual?: IsEffectivelyEqualBalance,\n  options?: BalanceStabilizerOptions\n): ((balances: IBalance[]) => IBalance[]) => {\n  const driftRefreshMs = options?.driftRefreshMs ?? DEFAULT_DRIFT_REFRESH_MS\n  const now = options?.now ?? defaultNow\n\n  type Entry = { balance: IBalance; emittedAt: number }\n  let previousById = new Map<string, Entry>()\n\n  const classify = (previous: IBalance, next: IBalance): BalanceEquivalence => {\n    if (previous === next) return \"equal\"\n\n    if (isEffectivelyEqual) {\n      const result = isEffectivelyEqual(previous, next)\n      if (result === true) return \"equal\"\n      if (result !== false) return result\n      // false → fall through to the exact fingerprint compare\n    }\n\n    return getBalanceFingerprint(previous) === getBalanceFingerprint(next) ? \"equal\" : \"changed\"\n  }\n\n  return (balances: IBalance[]): IBalance[] => {\n    const nextById = new Map<string, Entry>()\n\n    // pass 1: classify everything against the last emitted objects\n    const classified = balances.map((balance) => {\n      const id = getBalanceId(balance)\n      const previousEntry = previousById.get(id)\n      const equivalence: BalanceEquivalence = previousEntry\n        ? classify(previousEntry.balance, balance)\n        : \"changed\"\n      return { id, balance, previousEntry, equivalence }\n    })\n\n    // batch-aligned drift release: when any drift window has expired, refresh EVERY\n    // drift-classified balance in the same pass. Per-balance windows start at different\n    // times, so without alignment many drifting positions dribble out as frequent small\n    // emissions; with it they coalesce into one batched emission per refresh interval.\n    //\n    // Deliberately NOT triggered by \"changed\" balances: ids toggling in/out of the\n    // result set classify as \"changed\" (no previous entry), and piggybacking on those\n    // released the whole drift pool on nearly every poll — defeating the interval.\n    const releaseDrift = classified.some(\n      ({ previousEntry, equivalence }) =>\n        equivalence === \"drift\" &&\n        previousEntry !== undefined &&\n        now() - previousEntry.emittedAt >= driftRefreshMs\n    )\n\n    // pass 2: reuse or release\n    const stabilized = classified.map(({ id, balance, previousEntry, equivalence }): IBalance => {\n      const reusePrevious =\n        previousEntry !== undefined &&\n        (equivalence === \"equal\" || (equivalence === \"drift\" && !releaseDrift))\n\n      if (reusePrevious) {\n        nextById.set(id, previousEntry)\n        return previousEntry.balance\n      }\n\n      nextById.set(id, { balance, emittedAt: now() })\n      return balance\n    })\n\n    // only ids present in the latest emission are kept, so removed balances don't leak\n    previousById = nextById\n\n    return stabilized\n  }\n}\n\n/**\n * Default cross-module drift classifier: balances whose SHAPE is identical (same\n * address/token/status, same value set with same types/labels/metas) but whose amounts\n * moved by no more than `toleranceBps` classify as \"drift\" — continuously-moving\n * positions (LP shares, yield-bearing tokens, rebasing assets) otherwise re-emit on\n * every poll and defeat all downstream dedup. Anything structural, or any amount move\n * beyond the tolerance, classifies as \"changed\" and emits immediately.\n */\nexport const classifySmallAmountDrift =\n  (toleranceBps: bigint): IsEffectivelyEqualBalance =>\n  (previous: IBalance, next: IBalance): BalanceEquivalence => {\n    if (previous.address !== next.address) return \"changed\"\n    if (previous.tokenId !== next.tokenId) return \"changed\"\n    if (previous.networkId !== next.networkId) return \"changed\"\n    if (previous.source !== next.source) return \"changed\"\n    if (previous.status !== next.status) return \"changed\"\n\n    let drift = false\n\n    const classifyAmount = (a: string | undefined, b: string | undefined): boolean => {\n      if (a === b) return true\n      let prevAmount: bigint\n      let nextAmount: bigint\n      try {\n        prevAmount = BigInt(a ?? \"0\")\n        nextAmount = BigInt(b ?? \"0\")\n      } catch {\n        return false\n      }\n      // zero → non-zero (and vice versa) is always a real transition\n      if (prevAmount === 0n || nextAmount === 0n) return false\n      const diff = prevAmount > nextAmount ? prevAmount - nextAmount : nextAmount - prevAmount\n      const max = prevAmount > nextAmount ? prevAmount : nextAmount\n      if (diff * 10_000n > max * toleranceBps) return false\n      drift = true\n      return true\n    }\n\n    // simple balances carry a single `value` amount\n    const previousValue = \"value\" in previous ? previous.value : undefined\n    const nextValue = \"value\" in next ? next.value : undefined\n    if (!classifyAmount(previousValue, nextValue)) return \"changed\"\n\n    const previousValues = (\"values\" in previous ? previous.values : undefined) ?? []\n    const nextValues = (\"values\" in next ? next.values : undefined) ?? []\n    if (previousValues.length !== nextValues.length) return \"changed\"\n\n    for (let i = 0; i < previousValues.length; i++) {\n      const prevEntry = previousValues[i]\n      const nextEntry = nextValues[i]\n      if (prevEntry.type !== nextEntry.type) return \"changed\"\n      if (prevEntry.label !== nextEntry.label) return \"changed\"\n      if (!classifyAmount(prevEntry.amount, nextEntry.amount)) return \"changed\"\n      // metas and variant flags must match exactly (compared cheaply by JSON — only runs\n      // for balances that already failed the fingerprint fast path)\n      const { amount: _prevAmount, ...prevRest } = prevEntry\n      const { amount: _nextAmount, ...nextRest } = nextEntry\n      if (JSON.stringify(prevRest) !== JSON.stringify(nextRest)) return \"changed\"\n    }\n\n    return drift ? \"drift\" : \"equal\"\n  }\n\n/**\n * Operator form of createBalanceStabilizer for module result streams: stabilizes\n * `success` (errors/dynamicTokens pass through). One stabilizer per subscription.\n *\n * Place BEFORE `distinctUntilChanged(isEqualModuleResults)` so the gate's per-item\n * compares hit the `===` fast path (and, with `isEffectivelyEqual`, so tolerated drift\n * cannot hold the gate open).\n */\nexport const stabilizeModuleResults = (\n  isEffectivelyEqual?: IsEffectivelyEqualBalance,\n  options?: BalanceStabilizerOptions\n): MonoTypeOperatorFunction<FetchBalanceResults> => {\n  return (source: Observable<FetchBalanceResults>) =>\n    defer(() => {\n      const stabilize = createBalanceStabilizer(isEffectivelyEqual, options)\n      return source.pipe(map((results) => ({ ...results, success: stabilize(results.success) })))\n    })\n}\n","import { parseMetadataRpc, type UnifiedMetadata } from \"@talismn/scale\"\n\nexport const hasStorageItem = (\n  metadata: UnifiedMetadata,\n  palletName: string,\n  itemName: string\n): boolean => {\n  const pallet = metadata.pallets.find((p) => p.name === palletName)\n  if (!pallet?.storage) return false\n  return pallet.storage.items.some((item) => item.name === itemName)\n}\n\nexport const hasStorageItems = (\n  metadata: UnifiedMetadata,\n  palletName: string,\n  itemNames: string[]\n): boolean => {\n  const pallet = metadata.pallets.find((p) => p.name === palletName)\n  if (!pallet?.storage) return false\n  return itemNames.every((itemName) => pallet.storage?.items.some((item) => item.name === itemName))\n}\n\nexport const hasRuntimeApi = (\n  metadata: UnifiedMetadata,\n  apiName: string,\n  method: string\n): boolean => {\n  const api = metadata.apis.find((api) => api.name === apiName)\n  if (!api?.methods) return false\n  return api.methods.some((m) => m.name === method)\n}\n\nexport const getConstantValue = <T>(\n  metadataRpc: `0x${string}`,\n  pallet: string,\n  constant: string\n) => {\n  const { unifiedMetadata, builder } = parseMetadataRpc(metadataRpc)\n\n  const codec = builder.buildConstant(pallet, constant)\n\n  const encodedValue = unifiedMetadata.pallets\n    .find(({ name }) => name === pallet)\n    ?.constants.find(({ name }) => name === constant)?.value\n\n  if (!encodedValue) throw new Error(`Constant ${pallet}.${constant} not found`)\n\n  return codec.dec(encodedValue) as T\n}\n\nexport const tryGetConstantValue = <T>(\n  metadataRpc: `0x${string}`,\n  pallet: string,\n  constant: string\n) => {\n  const { unifiedMetadata, builder } = parseMetadataRpc(metadataRpc)\n\n  const encodedValue = unifiedMetadata.pallets\n    .find(({ name }) => name === pallet)\n    ?.constants.find(({ name }) => name === constant)?.value\n\n  if (!encodedValue) return null\n\n  const codec = builder.buildConstant(pallet, constant)\n\n  return codec.dec(encodedValue) as T\n}\n","import { parseTokenId, type TokenId, type TokenType } from \"@talismn/chaindata-provider\"\nimport { isEqual } from \"lodash-es\"\nimport { BehaviorSubject, distinctUntilChanged, map } from \"rxjs\"\n\nconst tokenIdsByAddress = new BehaviorSubject<Record<string, TokenId[]>>({})\n\nexport const setDetectedTokenIds = (address: string, type: TokenType, tokenIds: TokenId[]) => {\n  // keep token ids from other token types (will be useful once we add token2022)\n  const otherTokens =\n    tokenIdsByAddress.value[address]?.filter((id) => parseTokenId(id).type !== type) ?? []\n\n  tokenIdsByAddress.next({\n    ...tokenIdsByAddress.value,\n    [address]: otherTokens.concat(tokenIds).sort(),\n  })\n}\n\nexport const getDetectedTokensIds$ = (address: string) =>\n  tokenIdsByAddress.pipe(\n    map((ownedTokens) => ownedTokens[address] ?? []),\n    distinctUntilChanged<TokenId[]>(isEqual)\n  )\n","import { deserializeMetadata } from \"@metaplex-foundation/mpl-token-metadata\"\nimport { publicKey, sol } from \"@metaplex-foundation/umi\"\nimport { getAddressEncoder, getProgramDerivedAddress, address as solAddress } from \"@solana/kit\"\nimport type { SolRpc } from \"@talismn/chain-connectors\"\n\nconst METAPLEX_PROGRAM_ID = solAddress(\"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s\")\n\n/** Derives the Metaplex metadata PDA for a mint. */\nconst deriveMetaplexMetadataPda = async (mintAddress: string) => {\n  const addressEncoder = getAddressEncoder()\n  const [metadataPDA] = await getProgramDerivedAddress({\n    programAddress: METAPLEX_PROGRAM_ID,\n    seeds: [\n      \"metadata\",\n      addressEncoder.encode(METAPLEX_PROGRAM_ID),\n      addressEncoder.encode(solAddress(mintAddress)),\n    ],\n  })\n  return metadataPDA\n}\n\n/**\n * Fetches and decodes the Metaplex metadata account for a mint.\n * Returns the trimmed symbol/name, or null when no metadata account exists.\n */\nexport const fetchMetaplexMetadata = async (\n  rpc: SolRpc,\n  mintAddress: string\n): Promise<{ symbol: string; name: string } | null> => {\n  const metadataPDA = await deriveMetaplexMetadataPda(mintAddress)\n\n  const { value: metadataAccount } = await rpc\n    .getAccountInfo(metadataPDA, { encoding: \"base64\" })\n    .send()\n  if (!metadataAccount) return null\n\n  const metadata = deserializeMetadata({\n    publicKey: publicKey(metadataPDA),\n    executable: metadataAccount.executable,\n    owner: publicKey(metadataAccount.owner),\n    lamports: sol(Number(metadataAccount.lamports)),\n    data: Buffer.from(metadataAccount.data[0], \"base64\"),\n  })\n\n  return { symbol: metadata.symbol.trim(), name: metadata.name.trim() }\n}\n","import type { Address } from \"@solana/kit\"\nimport type { SolRpc } from \"@talismn/chain-connectors\"\n\n/**\n * Checks whether an associated token account already exists for the given token program.\n *\n * encoding must be explicit: the node rejects base58 (its default) for account data >128 bytes,\n * and the owner check is enough — skip the data entirely. An account not owned by the token\n * program (e.g. a rent-dusted system account squatting the ATA address) must go through the\n * create instruction, which handles pre-funded addresses; a bare transfer to it fails on-chain.\n */\nexport const tokenAccountExists = async (rpc: SolRpc, address: Address, tokenProgram: Address) => {\n  const { value } = await rpc\n    .getAccountInfo(address, { encoding: \"base64\", dataSlice: { offset: 0, length: 0 } })\n    .send()\n  return value !== null && value.owner === tokenProgram\n}\n","export const ERROR_NO_MINT = \"No mint info available\"\nexport const ERROR_NO_METADATA = \"No metadata account found\"\nexport const ERROR_INVALID_DATA = \"Invalid on-chain data\"\n\n/** True when the message is one of the sentinel errors that map to an `isValid: false` cache entry. */\nexport const isTokenDataError = (msg: string): boolean =>\n  [ERROR_NO_MINT, ERROR_NO_METADATA, ERROR_INVALID_DATA].includes(msg)\n","import { address as solAddress } from \"@solana/kit\"\nimport { getMintDecoder } from \"@solana-program/token\"\nimport type { IChainConnectorSol } from \"@talismn/chain-connectors\"\nimport { parseSolSplTokenId, SolSplTokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport log from \"../../log\"\nimport {\n  ERROR_INVALID_DATA,\n  ERROR_NO_METADATA,\n  ERROR_NO_MINT,\n  fetchMetaplexMetadata,\n  isTokenDataError,\n} from \"../sol-shared\"\n\nexport const TokenCacheSchema = z.discriminatedUnion(\"isValid\", [\n  z.strictObject({\n    id: SolSplTokenSchema.shape.id,\n    isValid: z.literal(true),\n    ...SolSplTokenSchema.pick({ symbol: true, decimals: true, name: true, logo: true }).shape,\n  }),\n  z.strictObject({\n    id: SolSplTokenSchema.shape.id,\n    isValid: z.literal(false),\n  }),\n])\n\nexport type CachedToken = z.infer<typeof TokenCacheSchema>\n\nexport const fetchOnChainTokenData = async (\n  connector: IChainConnectorSol,\n  tokenId: string\n): Promise<CachedToken | null> => {\n  try {\n    const { networkId, mintAddress } = parseSolSplTokenId(tokenId)\n\n    const rpc = await connector.getRpc(networkId)\n    if (!rpc) {\n      log.warn(`No connection found for network ${networkId}`)\n      return null\n    }\n\n    const { value: mintInfo } = await rpc\n      .getAccountInfo(solAddress(mintAddress), { encoding: \"base64\" })\n      .send()\n    if (!mintInfo?.data) throw new Error(ERROR_NO_MINT)\n    const mint = getMintDecoder().decode(Buffer.from(mintInfo.data[0], \"base64\"))\n\n    const metadata = await fetchMetaplexMetadata(rpc, mintAddress)\n    if (!metadata) throw new Error(ERROR_NO_METADATA)\n\n    const parsed = TokenCacheSchema.safeParse({\n      id: tokenId,\n      symbol: metadata.symbol,\n      name: metadata.name,\n      decimals: mint.decimals,\n      isValid: true,\n    })\n\n    if (!parsed.success) throw new Error(ERROR_INVALID_DATA)\n\n    return parsed.data\n  } catch (err) {\n    const msg = (err as Error).message\n\n    if (isTokenDataError(msg))\n      return TokenCacheSchema.parse({\n        id: tokenId,\n        isValid: false,\n      })\n\n    log.warn(\"Failed to fetch sol-spl token data for %s\", tokenId, { err })\n  }\n\n  return null\n}\n","import { address as solAddress } from \"@solana/kit\"\nimport { type SolSplToken, SolSplTokenSchema, solSplTokenId } from \"@talismn/chaindata-provider\"\nimport { isNotNil, LruMap } from \"@talismn/util\"\nimport { keyBy, uniq } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { IBalance } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getBalanceDefs } from \"../shared\"\nimport { setDetectedTokenIds } from \"../shared/detectedTokens\"\nimport { MODULE_TYPE, PLATFORM } from \"./config\"\nimport { type CachedToken, fetchOnChainTokenData } from \"./onChainTokenMetadata\"\n\nconst SPL_PROGRAM_ID = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\"\n\n// In-memory metadata cache for unknown mints discovered during balance polling.\n// Keyed by tokenId. Stores both successful metadata and known-invalid mints\n// so we don't re-fetch the same mint on every 6s poll. LRU-bounded: spam airdrops\n// mint new tokens indefinitely, and an evicted entry only costs one re-fetch.\nconst dynamicTokenMetadataCache = new LruMap<string, CachedToken>(1024)\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const rpc = await connector.getRpc(networkId)\n  if (!rpc) throw new Error(`Could not get connection for Solana network ${networkId}`)\n\n  const accountAddresses = uniq(tokensWithAddresses.flatMap(([, addresses]) => addresses))\n  const knownTokenIds = new Set(tokensWithAddresses.map(([token]) => token.id))\n\n  // mints discovered on-chain that are not yet in chaindata (deduped across addresses)\n  const unknownMints = new Set<string>()\n\n  const balancesPerAddress = await Promise.all(\n    accountAddresses.map(async (address) => {\n      const tokenAccounts = await rpc\n        .getTokenAccountsByOwner(\n          solAddress(address),\n          { programId: solAddress(SPL_PROGRAM_ID) }, // SPL Token Program ID\n          { encoding: \"jsonParsed\" }\n        )\n        .send()\n\n      const balances = tokenAccounts.value\n        .map((d): IBalance | null => {\n          try {\n            const mintAddress = d.account.data.parsed.info.mint\n            const value = d.account.data.parsed.info.tokenAmount.amount ?? \"0\"\n            const tokenId = solSplTokenId(networkId, mintAddress)\n\n            // Only register mints with non-zero balance to avoid storing every\n            // airdropped/spam token an account has ever received with 0 balance.\n            if (!knownTokenIds.has(tokenId) && value !== \"0\") unknownMints.add(mintAddress)\n\n            return {\n              tokenId,\n              networkId,\n              address,\n              source: MODULE_TYPE,\n              status: \"live\",\n              value,\n            }\n          } catch {\n            log.warn(\"Failed to parse token amount\", {\n              address,\n              d,\n            })\n            return null\n          }\n        })\n        .filter(isNotNil)\n\n      // allows the wallet to detect new tokens, and enable them automatically\n      setDetectedTokenIds(\n        address,\n        MODULE_TYPE,\n        balances.map((b) => b.tokenId)\n      )\n\n      return [address, balances] as const\n    })\n  )\n\n  // Fetch metadata for newly-discovered mints (skipping any already cached).\n  // Cached entries (both valid and invalid) are reused to avoid re-querying every poll.\n  const dynamicTokens: SolSplToken[] = []\n  if (unknownMints.size) {\n    await Promise.all(\n      Array.from(unknownMints).map(async (mintAddress) => {\n        const tokenId = solSplTokenId(networkId, mintAddress)\n\n        let cached = dynamicTokenMetadataCache.get(tokenId)\n        if (!cached) {\n          const fetched = await fetchOnChainTokenData(connector, tokenId)\n          if (fetched) {\n            dynamicTokenMetadataCache.set(tokenId, fetched)\n            cached = fetched\n          }\n        }\n\n        // Skip mints whose metadata fetch failed or returned invalid data.\n        if (!cached?.isValid) return\n\n        const token: SolSplToken = {\n          id: tokenId,\n          type: MODULE_TYPE,\n          platform: PLATFORM,\n          networkId,\n          mintAddress,\n          isDefault: true,\n          symbol: cached.symbol,\n          decimals: cached.decimals,\n          ...(cached.name !== undefined ? { name: cached.name } : {}),\n          ...(cached.logo !== undefined ? { logo: cached.logo } : {}),\n        }\n\n        const parsed = SolSplTokenSchema.safeParse(token)\n        if (!parsed.success) {\n          log.warn(\"Ignoring dynamic sol-spl token with invalid schema\", { token })\n          return\n        }\n\n        dynamicTokens.push(parsed.data)\n      })\n    )\n  }\n\n  // Set of token ids we successfully registered as dynamic this run; used to\n  // include their balances in `success` immediately rather than waiting for the\n  // next poll cycle.\n  const registeredDynamicIds = new Set(dynamicTokens.map((t) => t.id))\n\n  const allBalancesByKey = keyBy(\n    balancesPerAddress.flatMap(([, addressBalances]) => addressBalances),\n    (b) => getBalanceKey(b.tokenId, b.address)\n  )\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  // return a balance entry for all token/address pairs that were requested\n  const success: IBalance[] = balanceDefs.map((bd): IBalance => {\n    const found = allBalancesByKey[getBalanceKey(bd.token.id, bd.address)]\n    return (\n      found ?? {\n        tokenId: bd.token.id,\n        networkId: bd.token.networkId,\n        address: bd.address,\n        source: MODULE_TYPE,\n        status: \"live\",\n        value: \"0\",\n      }\n    )\n  })\n\n  // also surface balances for newly-registered dynamic tokens so their value\n  // appears on the same emission that triggers their registration\n  for (const balance of balancesPerAddress.flatMap(([, addressBalances]) => addressBalances)) {\n    if (registeredDynamicIds.has(balance.tokenId)) success.push(balance)\n  }\n\n  return { success, errors: [], dynamicTokens } // TODO output errors if any\n}\n\nconst getBalanceKey = (tokenId: string, address: string) => `${tokenId}:${address}`\n","import { type SolSplToken, SolSplTokenSchema, solSplTokenId } from \"@talismn/chaindata-provider\"\nimport { assign, omit } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { type CachedToken, fetchOnChainTokenData, TokenCacheSchema } from \"./onChainTokenMetadata\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  connector,\n  cache,\n}) => {\n  const result: SolSplToken[] = []\n\n  for (const tokenConfig of tokens) {\n    const tokenId = solSplTokenId(networkId, tokenConfig.mintAddress)\n    let cached = (cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data) as\n      | CachedToken\n      | undefined\n\n    if (!cached) {\n      const tokenInfo = await fetchOnChainTokenData(connector, tokenId)\n      if (tokenInfo) cache[tokenId] = tokenInfo\n    }\n\n    cached = (cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data) as\n      | CachedToken\n      | undefined\n\n    if (cached?.isValid === false) continue\n\n    const base: Pick<SolSplToken, \"id\" | \"type\" | \"networkId\" | \"platform\"> = {\n      id: tokenId,\n      type: MODULE_TYPE,\n      platform: PLATFORM,\n      networkId,\n    }\n\n    const token = assign(\n      base,\n      cached?.isValid ? omit(cached, [\"isValid\"]) : {},\n      tokenConfig\n    ) as SolSplToken\n\n    const parsed = SolSplTokenSchema.safeParse(token)\n    if (!parsed.success) {\n      log.warn(\"Ignoring token with invalid SolSplTokenSchema\", {\n        token,\n      })\n      continue\n    }\n\n    result.push(parsed.data)\n  }\n\n  return result\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = () => {\n  throw new Error(\"MiniMetadata is not supported for solana tokens\")\n}\n","import type { Instruction } from \"@solana/kit\"\nimport { createNoopSigner, address as solAddress } from \"@solana/kit\"\nimport {\n  findAssociatedTokenPda,\n  getCreateAssociatedTokenInstruction,\n  getTransferInstruction,\n  TOKEN_PROGRAM_ADDRESS,\n} from \"@solana-program/token\"\nimport { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport { isOnCurveSolanaAddress } from \"@talismn/crypto\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { tokenAccountExists } from \"../sol-shared/tokenAccountExists\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] =\n  async ({ from, to, value, token, connector }) => {\n    if (!isTokenOfType(token, MODULE_TYPE))\n      throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n    const rpc = await connector.getRpc(token.networkId)\n\n    const instructions: Instruction[] = []\n\n    const mint = solAddress(token.mintAddress)\n    const fromWallet = solAddress(from)\n    const toWallet = solAddress(to)\n\n    // off-curve (program-derived) recipients get an ATA no private key can control — tokens\n    // sent there are unrecoverable by a regular wallet (spl-token's getAssociatedTokenAddress\n    // enforced this; findAssociatedTokenPda does not)\n    if (!isOnCurveSolanaAddress(to))\n      throw new Error(\"Transfers to program-derived (off-curve) addresses are not supported.\")\n\n    // Get associated token accounts\n    const [fromTokenAccount] = await findAssociatedTokenPda({\n      mint,\n      owner: fromWallet,\n      tokenProgram: TOKEN_PROGRAM_ADDRESS,\n    })\n    const [toTokenAccount] = await findAssociatedTokenPda({\n      mint,\n      owner: toWallet,\n      tokenProgram: TOKEN_PROGRAM_ADDRESS,\n    })\n\n    // Create the target token account if it doesn't exist\n    if (!(await tokenAccountExists(rpc, toTokenAccount, TOKEN_PROGRAM_ADDRESS))) {\n      instructions.push(\n        getCreateAssociatedTokenInstruction({\n          payer: createNoopSigner(fromWallet), // funder — signature is provided at signing time\n          ata: toTokenAccount,\n          owner: toWallet,\n          mint,\n        })\n      )\n    }\n\n    // Transfer the tokens\n    instructions.push(\n      getTransferInstruction({\n        source: fromTokenAccount,\n        destination: toTokenAccount,\n        authority: fromWallet,\n        amount: BigInt(value),\n      })\n    )\n\n    return instructions\n  }\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses: tokensWithAddresses,\n          connector,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n\n        setTimeout(poll, SUBSCRIPTION_INTERVAL)\n      } catch (error) {\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          addressesByToken: tokensWithAddresses,\n          error,\n        })\n        subscriber.error(error)\n      }\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(distinctUntilChanged(isEqualModuleResults))\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SolSplBalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { SolSplTokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SolSplTokenConfigSchema = z.strictObject({\n  mintAddress: SolSplTokenSchema.shape.mintAddress,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type SolSplTokenConfig = z.infer<typeof SolSplTokenConfigSchema>\n","import { SolToken2022TokenSchema } from \"@talismn/chaindata-provider\"\n\nexport const MODULE_TYPE = SolToken2022TokenSchema.shape.type.value\nexport const PLATFORM = SolToken2022TokenSchema.shape.platform.value\n\nexport type { SolToken2022TokenConfig as TokenConfig } from \"./types\"\n","import { unwrapOption } from \"@solana/kit\"\nimport type { Mint } from \"@solana-program/token-2022\"\n\ntype Extension = NonNullable<ReturnType<typeof getMintExtensions>>[number]\n\nexport const getMintExtensions = (mint: Mint) => unwrapOption(mint.extensions) ?? []\n\nexport const getExtension = <TKind extends Extension[\"__kind\"]>(mint: Mint, kind: TKind) =>\n  (getMintExtensions(mint).find((ext) => ext.__kind === kind) ?? null) as Extract<\n    Extension,\n    { __kind: TKind }\n  > | null\n\nexport const getTransferFeeConfig = (mint: Mint) => getExtension(mint, \"TransferFeeConfig\")\n\nexport const getTransferHook = (mint: Mint) => getExtension(mint, \"TransferHook\")\n\nexport const isNonTransferable = (mint: Mint) => getExtension(mint, \"NonTransferable\") !== null\n\nexport const getTokenMetadata = (mint: Mint) => getExtension(mint, \"TokenMetadata\")\n","import type { AccountMeta, Address, Instruction } from \"@solana/kit\"\nimport {\n  AccountRole,\n  fetchEncodedAccount,\n  getAddressDecoder,\n  getAddressEncoder,\n  getProgramDerivedAddress,\n  address as solAddress,\n} from \"@solana/kit\"\nimport type { SolRpc } from \"@talismn/chain-connectors\"\n\n/**\n * Ported from @solana/spl-token 0.4.14 `extensions/transferHook` (state.js, seeds.js,\n * pubkeyData.js, instructions.js), rewritten on kit primitives. The token-2022 kit client\n * (@solana-program/token-2022 0.12.0) has no equivalent of `addExtraAccountMetasForExecute`\n * — it only ships the initialize/update admin instructions — so the extra-account\n * resolution for transfer-hook tokens must live here.\n */\n\ntype ResolvedMeta = { address: Address; isSigner: boolean; isWritable: boolean }\n\n// `ExecuteInstruction` discriminator\nconst EXECUTE_DISCRIMINATOR = Uint8Array.from([105, 37, 101, 197, 75, 251, 102, 26])\n\nconst PUBLIC_KEY_LENGTH = 32\nconst EXTRA_ACCOUNT_META_SIZE = 35 // u8 discriminator + 32-byte addressConfig + bool isSigner + bool isWritable\n\nconst addressEncoder = getAddressEncoder()\nconst addressDecoder = getAddressDecoder()\n\nexport const getExtraAccountMetaAddress = async (\n  mint: string,\n  hookProgramId: Address\n): Promise<Address> => {\n  const [pda] = await getProgramDerivedAddress({\n    programAddress: hookProgramId,\n    seeds: [\"extra-account-metas\", addressEncoder.encode(solAddress(mint))],\n  })\n  return pda\n}\n\n/** Unpack an extra account metas account into a list of raw ExtraAccountMeta entries */\nconst getExtraAccountMetas = (data: Uint8Array) => {\n  const view = new DataView(data.buffer, data.byteOffset, data.byteLength)\n  // layout: u64 instructionDiscriminator, u32 length, u32 count, count × 35-byte entries\n  const count = view.getUint32(12, true)\n  const metas: {\n    discriminator: number\n    addressConfig: Uint8Array\n    isSigner: boolean\n    isWritable: boolean\n  }[] = []\n  for (let i = 0; i < count; i++) {\n    const offset = 16 + i * EXTRA_ACCOUNT_META_SIZE\n    metas.push({\n      discriminator: data[offset]!,\n      addressConfig: data.subarray(offset + 1, offset + 33),\n      isSigner: data[offset + 33] !== 0,\n      isWritable: data[offset + 34] !== 0,\n    })\n  }\n  return metas\n}\n\nconst getAccountData = async (rpc: SolRpc, address: Address): Promise<Uint8Array | null> => {\n  // kit's fetchEncodedAccount already fetches with base64 and decodes the bytes for us\n  const account = await fetchEncodedAccount(rpc, address)\n  return account.exists ? new Uint8Array(account.data) : null\n}\n\nconst unpackSeeds = async (\n  rpc: SolRpc,\n  seeds: Uint8Array,\n  previousMetas: ResolvedMeta[],\n  instructionData: Uint8Array\n): Promise<Uint8Array[]> => {\n  const unpacked: Uint8Array[] = []\n  let i = 0\n  while (i < 32) {\n    const discriminator = seeds[i]!\n    const rest = seeds.subarray(i + 1)\n    switch (discriminator) {\n      case 0:\n        return unpacked\n      case 1: {\n        // literal: u8 length + bytes\n        const length = rest[0]!\n        if (rest.length < 1 + length) throw new Error(\"Invalid transfer hook seed\")\n        unpacked.push(rest.subarray(1, 1 + length))\n        i += 2 + length\n        break\n      }\n      case 2: {\n        // instruction arg: u8 offset + u8 length\n        const [offset, length] = [rest[0]!, rest[1]!]\n        if (instructionData.length < offset + length) throw new Error(\"Invalid transfer hook seed\")\n        unpacked.push(instructionData.subarray(offset, offset + length))\n        i += 3\n        break\n      }\n      case 3: {\n        // account key at index\n        const index = rest[0]!\n        const meta = previousMetas[index]\n        if (!meta) throw new Error(\"Invalid transfer hook seed\")\n        unpacked.push(new Uint8Array(addressEncoder.encode(meta.address)))\n        i += 2\n        break\n      }\n      case 4: {\n        // account data: u8 accountIndex + u8 dataOffset + u8 length\n        const [accountIndex, dataOffset, length] = [rest[0]!, rest[1]!, rest[2]!]\n        const meta = previousMetas[accountIndex]\n        if (!meta) throw new Error(\"Invalid transfer hook seed\")\n        const accountData = await getAccountData(rpc, meta.address)\n        if (!accountData) throw new Error(\"Transfer hook seed account data not found\")\n        if (accountData.length < dataOffset + length) throw new Error(\"Invalid transfer hook seed\")\n        unpacked.push(accountData.subarray(dataOffset, dataOffset + length))\n        i += 4\n        break\n      }\n      default:\n        throw new Error(\"Invalid transfer hook seed\")\n    }\n  }\n  return unpacked\n}\n\nconst unpackPubkeyData = async (\n  rpc: SolRpc,\n  keyDataConfig: Uint8Array,\n  previousMetas: ResolvedMeta[],\n  instructionData: Uint8Array\n): Promise<Address> => {\n  const discriminator = keyDataConfig[0]!\n  const rest = keyDataConfig.subarray(1)\n  switch (discriminator) {\n    case 1: {\n      // pubkey from instruction data at offset\n      const dataIndex = rest[0]!\n      if (instructionData.length < dataIndex + PUBLIC_KEY_LENGTH)\n        throw new Error(\"Transfer hook pubkey data too small\")\n      return addressDecoder.decode(\n        instructionData.subarray(dataIndex, dataIndex + PUBLIC_KEY_LENGTH)\n      )\n    }\n    case 2: {\n      // pubkey from account data\n      const [accountIndex, dataIndex] = [rest[0]!, rest[1]!]\n      const meta = previousMetas[accountIndex]\n      if (!meta) throw new Error(\"Transfer hook account data not found\")\n      const accountData = await getAccountData(rpc, meta.address)\n      if (!accountData) throw new Error(\"Transfer hook account not found\")\n      if (accountData.length < dataIndex + PUBLIC_KEY_LENGTH)\n        throw new Error(\"Transfer hook pubkey data too small\")\n      return addressDecoder.decode(accountData.subarray(dataIndex, dataIndex + PUBLIC_KEY_LENGTH))\n    }\n    default:\n      throw new Error(\"Invalid transfer hook pubkey data\")\n  }\n}\n\nconst resolveExtraAccountMeta = async (\n  rpc: SolRpc,\n  extraMeta: ReturnType<typeof getExtraAccountMetas>[number],\n  previousMetas: ResolvedMeta[],\n  instructionData: Uint8Array,\n  hookProgramId: Address\n): Promise<ResolvedMeta> => {\n  const { discriminator, addressConfig, isSigner, isWritable } = extraMeta\n\n  if (discriminator === 0)\n    return { address: addressDecoder.decode(addressConfig), isSigner, isWritable }\n\n  if (discriminator === 2) {\n    const address = await unpackPubkeyData(rpc, addressConfig, previousMetas, instructionData)\n    return { address, isSigner, isWritable }\n  }\n\n  let programAddress: Address\n  if (discriminator === 1) {\n    programAddress = hookProgramId\n  } else {\n    const accountIndex = discriminator - (1 << 7)\n    const meta = previousMetas[accountIndex]\n    if (!meta) throw new Error(\"Transfer hook account not found\")\n    programAddress = meta.address\n  }\n\n  const seeds = await unpackSeeds(rpc, addressConfig, previousMetas, instructionData)\n  const [address] = await getProgramDerivedAddress({ programAddress, seeds })\n  return { address, isSigner, isWritable }\n}\n\n/** Demote privileges if the account already appears in the list with lower privileges */\nconst deEscalate = (meta: ResolvedMeta, previousMetas: ResolvedMeta[]): ResolvedMeta => {\n  const highest = previousMetas\n    .filter((x) => x.address === meta.address)\n    .reduce<{ isSigner: boolean; isWritable: boolean } | undefined>(\n      (acc, x) =>\n        acc\n          ? { isSigner: acc.isSigner || x.isSigner, isWritable: acc.isWritable || x.isWritable }\n          : { isSigner: x.isSigner, isWritable: x.isWritable },\n      undefined\n    )\n  if (!highest) return meta\n  return {\n    address: meta.address,\n    isSigner: meta.isSigner && highest.isSigner,\n    isWritable: meta.isWritable && highest.isWritable,\n  }\n}\n\nconst toAccountRole = ({ isSigner, isWritable }: ResolvedMeta): AccountRole =>\n  isSigner\n    ? isWritable\n      ? AccountRole.WRITABLE_SIGNER\n      : AccountRole.READONLY_SIGNER\n    : isWritable\n      ? AccountRole.WRITABLE\n      : AccountRole.READONLY\n\n/**\n * Appends all the extra accounts required by a transfer-hook token to a\n * transferChecked(WithFee) instruction: the resolved extra metas, the hook\n * program and the validation state account.\n *\n * Returns the instruction unchanged when the hook has no validation state account.\n */\nexport const addExtraAccountMetasForTransferHook = async <T extends Instruction>(args: {\n  rpc: SolRpc\n  instruction: T\n  hookProgramId: Address\n  source: Address\n  mint: Address\n  destination: Address\n  authority: Address\n  amount: bigint\n}): Promise<T> => {\n  const { rpc, instruction, hookProgramId, source, mint, destination, authority, amount } = args\n\n  const validateStateAddress = await getExtraAccountMetaAddress(mint, hookProgramId)\n  const validateStateData = await getAccountData(rpc, validateStateAddress)\n  if (!validateStateData) return instruction\n\n  const extraMetas = getExtraAccountMetas(validateStateData)\n\n  // resolution happens against the hook's `Execute` instruction, not the transfer instruction\n  const executeData = new Uint8Array(16)\n  executeData.set(EXECUTE_DISCRIMINATOR, 0)\n  new DataView(executeData.buffer).setBigUint64(8, amount, true)\n\n  const executeMetas: ResolvedMeta[] = [\n    source,\n    mint,\n    destination,\n    authority,\n    validateStateAddress,\n  ].map((address) => ({ address, isSigner: false, isWritable: false }))\n\n  for (const extraMeta of extraMetas) {\n    const resolved = await resolveExtraAccountMeta(\n      rpc,\n      extraMeta,\n      executeMetas,\n      executeData,\n      hookProgramId\n    )\n    executeMetas.push(deEscalate(resolved, executeMetas))\n  }\n\n  const extraAccounts: AccountMeta[] = [\n    // only the extra accounts resolved from the validation state\n    ...executeMetas.slice(5).map((meta) => ({ address: meta.address, role: toAccountRole(meta) })),\n    // then the transfer hook program and the validation state account\n    { address: hookProgramId, role: AccountRole.READONLY },\n    { address: validateStateAddress, role: AccountRole.READONLY },\n  ]\n\n  return {\n    ...instruction,\n    accounts: [...(instruction.accounts ?? []), ...extraAccounts],\n  }\n}\n","import type { Instruction } from \"@solana/kit\"\nimport { createNoopSigner, address as solAddress } from \"@solana/kit\"\nimport { findAssociatedTokenPda, getCreateAssociatedTokenInstruction } from \"@solana-program/token\"\nimport type { TransferFee } from \"@solana-program/token-2022\"\nimport {\n  fetchMint,\n  getTransferCheckedInstruction,\n  getTransferCheckedWithFeeInstruction,\n  TOKEN_2022_PROGRAM_ADDRESS,\n} from \"@solana-program/token-2022\"\nimport type { SolRpc } from \"@talismn/chain-connectors\"\nimport { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport { isOnCurveSolanaAddress } from \"@talismn/crypto\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { tokenAccountExists } from \"../sol-shared/tokenAccountExists\"\nimport { MODULE_TYPE } from \"./config\"\nimport { getTransferFeeConfig, getTransferHook, isNonTransferable } from \"./mintExtensions\"\nimport { addExtraAccountMetasForTransferHook } from \"./transferHook\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] =\n  async ({ from, to, value, token, connector }) => {\n    if (!isTokenOfType(token, MODULE_TYPE))\n      throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n    const rpc = await connector.getRpc(token.networkId)\n\n    const mint = solAddress(token.mintAddress)\n    const fromWallet = solAddress(from)\n    const toWallet = solAddress(to)\n\n    // off-curve (program-derived) recipients get an ATA no private key can control — tokens\n    // sent there are unrecoverable by a regular wallet (spl-token's getAssociatedTokenAddress\n    // enforced this; findAssociatedTokenPda does not)\n    if (!isOnCurveSolanaAddress(to))\n      throw new Error(\"Transfers to program-derived (off-curve) addresses are not supported.\")\n\n    // Fetch the mint account to detect extensions\n    const mintAccount = await fetchMint(rpc, mint)\n\n    // Block non-transferable tokens\n    if (isNonTransferable(mintAccount.data)) throw new Error(\"This token is non-transferable.\")\n\n    const transferFeeConfig = getTransferFeeConfig(mintAccount.data)\n    const transferHook = getTransferHook(mintAccount.data)\n\n    const instructions: Instruction[] = []\n\n    // Token 2022 ATAs use the same ATA program but with the token-2022 program as the programId seed\n    const [fromTokenAccount] = await findAssociatedTokenPda({\n      mint,\n      owner: fromWallet,\n      tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,\n    })\n    const [toTokenAccount] = await findAssociatedTokenPda({\n      mint,\n      owner: toWallet,\n      tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,\n    })\n\n    // Create the target token account if it doesn't exist\n    if (!(await tokenAccountExists(rpc, toTokenAccount, TOKEN_2022_PROGRAM_ADDRESS))) {\n      instructions.push(\n        getCreateAssociatedTokenInstruction({\n          payer: createNoopSigner(fromWallet), // signature is provided at signing time, not at instruction build time\n          ata: toTokenAccount,\n          owner: toWallet,\n          mint,\n          tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,\n        })\n      )\n    }\n\n    const amount = BigInt(value)\n\n    const transferInstruction = transferFeeConfig\n      ? getTransferCheckedWithFeeInstruction({\n          source: fromTokenAccount,\n          mint,\n          destination: toTokenAccount,\n          authority: fromWallet,\n          amount,\n          decimals: token.decimals,\n          // fee must be exact or the transaction fails\n          fee: await calculateCurrentEpochTransferFee(rpc, transferFeeConfig, amount),\n        })\n      : getTransferCheckedInstruction({\n          source: fromTokenAccount,\n          mint,\n          destination: toTokenAccount,\n          authority: fromWallet,\n          amount,\n          decimals: token.decimals,\n        })\n\n    instructions.push(\n      transferHook\n        ? // Transfer hook — resolves and appends the hook's extra accounts\n          await addExtraAccountMetasForTransferHook({\n            rpc,\n            instruction: transferInstruction,\n            hookProgramId: transferHook.programId,\n            source: fromTokenAccount,\n            mint,\n            destination: toTokenAccount,\n            authority: fromWallet,\n            amount,\n          })\n        : transferInstruction\n    )\n\n    return instructions\n  }\n\nconst ONE_IN_BASIS_POINTS = 10_000n\n\n/** Selects the transfer-fee schedule (older vs newer) that applies to a given epoch. */\nexport const getEpochTransferFee = (\n  transferFeeConfig: { olderTransferFee: TransferFee; newerTransferFee: TransferFee },\n  epoch: bigint\n): TransferFee =>\n  epoch >= transferFeeConfig.newerTransferFee.epoch\n    ? transferFeeConfig.newerTransferFee\n    : transferFeeConfig.olderTransferFee\n\n/**\n * Calculates the transfer fee for a given amount using the current epoch's fee configuration.\n *\n * Same math as @solana/spl-token's `calculateEpochFee`: pick the fee schedule for the epoch,\n * apply basis points with ceiling rounding, cap at `maximumFee`.\n */\nexport const calculateToken2022TransferFee = (\n  transferFeeConfig: { olderTransferFee: TransferFee; newerTransferFee: TransferFee },\n  epoch: bigint,\n  amount: bigint\n): bigint => {\n  const { transferFeeBasisPoints, maximumFee } = getEpochTransferFee(transferFeeConfig, epoch)\n\n  if (transferFeeBasisPoints === 0 || amount === 0n) return 0n\n\n  const numerator = amount * BigInt(transferFeeBasisPoints)\n  const rawFee = (numerator + ONE_IN_BASIS_POINTS - 1n) / ONE_IN_BASIS_POINTS // ceil division\n\n  return rawFee > maximumFee ? maximumFee : rawFee\n}\n\nconst calculateCurrentEpochTransferFee = async (\n  rpc: SolRpc,\n  transferFeeConfig: { olderTransferFee: TransferFee; newerTransferFee: TransferFee },\n  amount: bigint\n): Promise<bigint> => {\n  const { epoch } = await rpc.getEpochInfo().send()\n  return calculateToken2022TransferFee(transferFeeConfig, epoch, amount)\n}\n","import { address as solAddress } from \"@solana/kit\"\nimport { getMintDecoder } from \"@solana-program/token-2022\"\nimport type { IChainConnectorSol } from \"@talismn/chain-connectors\"\nimport { parseSolToken2022TokenId, SolToken2022TokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport log from \"../../log\"\nimport {\n  ERROR_INVALID_DATA,\n  ERROR_NO_METADATA,\n  ERROR_NO_MINT,\n  fetchMetaplexMetadata,\n  isTokenDataError,\n} from \"../sol-shared\"\nimport { getTokenMetadata } from \"./mintExtensions\"\n\nexport const TokenCacheSchema = z.discriminatedUnion(\"isValid\", [\n  z.strictObject({\n    id: SolToken2022TokenSchema.shape.id,\n    isValid: z.literal(true),\n    ...SolToken2022TokenSchema.pick({ symbol: true, decimals: true, name: true, logo: true }).shape,\n  }),\n  z.strictObject({\n    id: SolToken2022TokenSchema.shape.id,\n    isValid: z.literal(false),\n  }),\n])\n\nexport type CachedToken = z.infer<typeof TokenCacheSchema>\n\nexport const fetchOnChainTokenData = async (\n  connector: IChainConnectorSol,\n  tokenId: string\n): Promise<CachedToken | null> => {\n  try {\n    const { networkId, mintAddress } = parseSolToken2022TokenId(tokenId)\n\n    const rpc = await connector.getRpc(networkId)\n    if (!rpc) {\n      log.warn(`No connection found for network ${networkId}`)\n      return null\n    }\n\n    const { value: mintInfo } = await rpc\n      .getAccountInfo(solAddress(mintAddress), { encoding: \"base64\" })\n      .send()\n    if (!mintInfo?.data) throw new Error(ERROR_NO_MINT)\n    const mintData = Buffer.from(mintInfo.data[0], \"base64\")\n\n    // decodes the base mint layout plus all TLV extensions (including TokenMetadata)\n    const mint = getMintDecoder().decode(mintData)\n\n    // Try on-chain Token 2022 metadata extension first (stored in the mint account itself)\n    const token2022Metadata = getTokenMetadata(mint)\n    if (token2022Metadata) {\n      const parsed = TokenCacheSchema.safeParse({\n        id: tokenId,\n        symbol: token2022Metadata.symbol.trim(),\n        name: token2022Metadata.name.trim(),\n        decimals: mint.decimals,\n        isValid: true,\n      })\n\n      if (parsed.success) return parsed.data\n    }\n\n    // Fall back to Metaplex metadata PDA (many T22 tokens still use Metaplex)\n    const metadata = await fetchMetaplexMetadata(rpc, mintAddress)\n    if (!metadata) throw new Error(ERROR_NO_METADATA)\n\n    const parsed = TokenCacheSchema.safeParse({\n      id: tokenId,\n      symbol: metadata.symbol,\n      name: metadata.name,\n      decimals: mint.decimals,\n      isValid: true,\n    })\n\n    if (!parsed.success) throw new Error(ERROR_INVALID_DATA)\n\n    return parsed.data\n  } catch (err) {\n    const msg = (err as Error).message\n\n    if (isTokenDataError(msg))\n      return TokenCacheSchema.parse({\n        id: tokenId,\n        isValid: false,\n      })\n\n    log.warn(\"Failed to fetch sol-token2022 token data for %s\", tokenId, { err })\n  }\n\n  return null\n}\n","import { address as solAddress } from \"@solana/kit\"\nimport {\n  type SolToken2022Token,\n  SolToken2022TokenSchema,\n  solToken2022TokenId,\n} from \"@talismn/chaindata-provider\"\nimport { isNotNil } from \"@talismn/util\"\nimport { keyBy, uniq } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { IBalance } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getBalanceDefs } from \"../shared\"\nimport { setDetectedTokenIds } from \"../shared/detectedTokens\"\nimport { MODULE_TYPE, PLATFORM } from \"./config\"\nimport { type CachedToken, fetchOnChainTokenData } from \"./onChainTokenMetadata\"\n\nconst TOKEN_2022_PROGRAM_ID = \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\"\n\n// In-memory metadata cache for unknown mints discovered during balance polling.\n// Keyed by tokenId. Stores both successful metadata and known-invalid mints\n// so we don't re-fetch the same mint on every 6s poll.\nconst dynamicTokenMetadataCache = new Map<string, CachedToken>()\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const rpc = await connector.getRpc(networkId)\n  if (!rpc) throw new Error(`Could not get connection for Solana network ${networkId}`)\n\n  const accountAddresses = uniq(tokensWithAddresses.flatMap(([, addresses]) => addresses))\n  const knownTokenIds = new Set(tokensWithAddresses.map(([token]) => token.id))\n\n  // mints discovered on-chain that are not yet in chaindata (deduped across addresses)\n  const unknownMints = new Set<string>()\n\n  const balancesPerAddress = await Promise.all(\n    accountAddresses.map(async (address) => {\n      const tokenAccounts = await rpc\n        .getTokenAccountsByOwner(\n          solAddress(address),\n          { programId: solAddress(TOKEN_2022_PROGRAM_ID) },\n          { encoding: \"jsonParsed\" }\n        )\n        .send()\n\n      const balances = tokenAccounts.value\n        .map((d): IBalance | null => {\n          try {\n            const mintAddress = d.account.data.parsed.info.mint\n            const value = d.account.data.parsed.info.tokenAmount.amount ?? \"0\"\n            const tokenId = solToken2022TokenId(networkId, mintAddress)\n\n            // Only register mints with non-zero balance to avoid storing every\n            // airdropped/spam token an account has ever received with 0 balance.\n            if (!knownTokenIds.has(tokenId) && value !== \"0\") unknownMints.add(mintAddress)\n\n            return {\n              tokenId,\n              networkId,\n              address,\n              source: MODULE_TYPE,\n              status: \"live\",\n              value,\n            }\n          } catch {\n            log.warn(\"Failed to parse token amount\", {\n              address,\n              d,\n            })\n            return null\n          }\n        })\n        .filter(isNotNil)\n\n      setDetectedTokenIds(\n        address,\n        MODULE_TYPE,\n        balances.map((b) => b.tokenId)\n      )\n\n      return [address, balances] as const\n    })\n  )\n\n  // Fetch metadata for newly-discovered mints (skipping any already cached).\n  // Cached entries (both valid and invalid) are reused to avoid re-querying every poll.\n  const dynamicTokens: SolToken2022Token[] = []\n  if (unknownMints.size) {\n    await Promise.all(\n      Array.from(unknownMints).map(async (mintAddress) => {\n        const tokenId = solToken2022TokenId(networkId, mintAddress)\n\n        let cached = dynamicTokenMetadataCache.get(tokenId)\n        if (!cached) {\n          const fetched = await fetchOnChainTokenData(connector, tokenId)\n          if (fetched) {\n            dynamicTokenMetadataCache.set(tokenId, fetched)\n            cached = fetched\n          }\n        }\n\n        // Skip mints whose metadata fetch failed or returned invalid data.\n        if (!cached?.isValid) return\n\n        const token: SolToken2022Token = {\n          id: tokenId,\n          type: MODULE_TYPE,\n          platform: PLATFORM,\n          networkId,\n          mintAddress,\n          isDefault: true,\n          symbol: cached.symbol,\n          decimals: cached.decimals,\n          ...(cached.name !== undefined ? { name: cached.name } : {}),\n          ...(cached.logo !== undefined ? { logo: cached.logo } : {}),\n        }\n\n        const parsed = SolToken2022TokenSchema.safeParse(token)\n        if (!parsed.success) {\n          log.warn(\"Ignoring dynamic sol-token2022 token with invalid schema\", { token })\n          return\n        }\n\n        dynamicTokens.push(parsed.data)\n      })\n    )\n  }\n\n  // Set of token ids we successfully registered as dynamic this run; used to\n  // include their balances in `success` immediately rather than waiting for the\n  // next poll cycle.\n  const registeredDynamicIds = new Set(dynamicTokens.map((t) => t.id))\n\n  const allBalancesByKey = keyBy(\n    balancesPerAddress.flatMap(([, addressBalances]) => addressBalances),\n    (b) => getBalanceKey(b.tokenId, b.address)\n  )\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  const success: IBalance[] = balanceDefs.map((bd): IBalance => {\n    const found = allBalancesByKey[getBalanceKey(bd.token.id, bd.address)]\n    return (\n      found ?? {\n        tokenId: bd.token.id,\n        networkId: bd.token.networkId,\n        address: bd.address,\n        source: MODULE_TYPE,\n        status: \"live\",\n        value: \"0\",\n      }\n    )\n  })\n\n  // also surface balances for newly-registered dynamic tokens so their value\n  // appears on the same emission that triggers their registration\n  for (const balance of balancesPerAddress.flatMap(([, addressBalances]) => addressBalances)) {\n    if (registeredDynamicIds.has(balance.tokenId)) success.push(balance)\n  }\n\n  return { success, errors: [], dynamicTokens }\n}\n\nconst getBalanceKey = (tokenId: string, address: string) => `${tokenId}:${address}`\n","import {\n  type SolToken2022Token,\n  SolToken2022TokenSchema,\n  solToken2022TokenId,\n} from \"@talismn/chaindata-provider\"\nimport { assign, omit } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { type CachedToken, fetchOnChainTokenData, TokenCacheSchema } from \"./onChainTokenMetadata\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  connector,\n  cache,\n}) => {\n  const result: SolToken2022Token[] = []\n\n  for (const tokenConfig of tokens) {\n    const tokenId = solToken2022TokenId(networkId, tokenConfig.mintAddress)\n    let cached = (cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data) as\n      | CachedToken\n      | undefined\n\n    if (!cached) {\n      const tokenInfo = await fetchOnChainTokenData(connector, tokenId)\n      if (tokenInfo) cache[tokenId] = tokenInfo\n    }\n\n    cached = (cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data) as\n      | CachedToken\n      | undefined\n\n    if (cached?.isValid === false) continue\n\n    const base: Pick<SolToken2022Token, \"id\" | \"type\" | \"networkId\" | \"platform\"> = {\n      id: tokenId,\n      type: MODULE_TYPE,\n      platform: PLATFORM,\n      networkId,\n    }\n\n    const token = assign(\n      base,\n      cached?.isValid ? omit(cached, [\"isValid\"]) : {},\n      tokenConfig\n    ) as SolToken2022Token\n\n    const parsed = SolToken2022TokenSchema.safeParse(token)\n    if (!parsed.success) {\n      log.warn(\"Ignoring token with invalid SolToken2022TokenSchema\", {\n        token,\n      })\n      continue\n    }\n\n    result.push(parsed.data)\n  }\n\n  return result\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = () => {\n  throw new Error(\"MiniMetadata is not supported for solana tokens\")\n}\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses: tokensWithAddresses,\n          connector,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n\n        setTimeout(poll, SUBSCRIPTION_INTERVAL)\n      } catch (error) {\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          addressesByToken: tokensWithAddresses,\n          error,\n        })\n        subscriber.error(error)\n      }\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(distinctUntilChanged(isEqualModuleResults))\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SolToken2022BalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { SolToken2022TokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\nexport const SolToken2022TokenConfigSchema = z.strictObject({\n  mintAddress: SolToken2022TokenSchema.shape.mintAddress,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type SolToken2022TokenConfig = z.infer<typeof SolToken2022TokenConfigSchema>\n","import { SubAssetsTokenSchema } from \"@talismn/chaindata-provider\"\nimport type z from \"zod/v4\"\n\nimport type { SubAssetsTokenConfigSchema } from \"./types\"\n\nexport const MODULE_TYPE = SubAssetsTokenSchema.shape.type.value\nexport const PLATFORM = SubAssetsTokenSchema.shape.platform.value\n\nexport type TokenConfig = z.infer<typeof SubAssetsTokenConfigSchema>\n","import { decodeScale, type MetadataBuilder } from \"@talismn/scale\"\nimport { isNotNil } from \"@talismn/util\"\n\nimport log from \"../../log\"\nimport type { AmountWithLabel, IBalance, MiniMetadata } from \"../../types\"\nimport { type BalanceDef, buildNetworkStorageCoders } from \"../shared\"\nimport type { MaybeStateKey, RpcQueryPack } from \"../shared/rpcQueryPack\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const buildQueries = (\n  networkId: string,\n  balanceDefs: BalanceDef<typeof MODULE_TYPE>[],\n  miniMetadata: MiniMetadata\n): Array<RpcQueryPack<IBalance>> => {\n  const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {\n    storage: [\"Assets\", \"Account\"],\n  })\n\n  return balanceDefs\n    .map(({ token, address }): RpcQueryPack<IBalance> | null => {\n      const scaleCoder = networkStorageCoders?.storage\n      const stateKey =\n        tryEncode(scaleCoder, Number(token.assetId), address) ?? // Asset Hub\n        tryEncode(scaleCoder, BigInt(token.assetId), address) // Astar\n\n      if (!stateKey) {\n        log.warn(\n          `Invalid assetId / address in ${networkId} storage query ${token.assetId} / ${address}`\n        )\n        return null\n      }\n\n      const decodeResult = (changes: MaybeStateKey[]) => {\n        /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n        type DecodedType = {\n          balance?: bigint\n\n          // On other networks than Astar\n          is_frozen?: boolean\n\n          // Astar specific fields\n          reason?: { type?: \"Sufficient\" }\n          status?: { type?: \"Liquid\" } | { type?: \"Frozen\" }\n          extra?: undefined\n        }\n\n        const decoded = decodeScale<DecodedType>(\n          scaleCoder,\n          changes[0],\n          `Failed to decode substrate-assets balance on chain ${networkId}`\n        ) ?? {\n          balance: 0n,\n          is_frozen: false,\n          reason: { type: \"Sufficient\" },\n          status: { type: \"Liquid\" },\n          extra: undefined,\n        }\n\n        const isFrozen = decoded?.status?.type === \"Frozen\"\n        const amount = (decoded?.balance ?? 0n).toString()\n\n        // due to the following balance calculations, which are made in the `Balance` type:\n        //\n        // total balance        = (free balance) + (reserved balance)\n        // transferable balance = (free balance) - (frozen balance)\n        //\n        // when `isFrozen` is true we need to set **both** the `free` and `frozen` amounts\n        // of this balance to the value we received from the RPC.\n        //\n        // if we only set the `frozen` amount, then the `total` calculation will be incorrect!\n        const free = amount\n        const frozen = token.isFrozen || isFrozen ? amount : \"0\"\n\n        // include balance values even if zero, so that newly-zero values overwrite old values\n        const balanceValues: Array<AmountWithLabel<string>> = [\n          { type: \"free\", label: \"free\", amount: free.toString() },\n          { type: \"locked\", label: \"frozen\", amount: frozen.toString() },\n        ]\n\n        const balance: IBalance = {\n          source: \"substrate-assets\",\n          status: \"live\",\n          address,\n          networkId,\n          tokenId: token.id,\n          values: balanceValues,\n        }\n\n        return balance\n      }\n\n      return {\n        stateKeys: [stateKey],\n        decodeResult,\n      }\n    })\n    .filter(isNotNil)\n}\n\ntype ScaleStorageCoder = ReturnType<MetadataBuilder[\"buildStorage\"]>\n\nconst tryEncode = (scaleCoder: ScaleStorageCoder | undefined, ...args: unknown[]) => {\n  try {\n    return scaleCoder?.keys?.enc?.(...args) as MaybeStateKey\n  } catch {\n    return null\n  }\n}\n","import log from \"../../log\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { fetchRpcQueryPack } from \"../shared/rpcQueryPack\"\nimport { getBalanceDefs } from \"../shared/types\"\nimport { buildQueries } from \"./buildQueries\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  if (!miniMetadata?.data) {\n    log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(\"Minimetadata is required for fetching balances\"),\n      })),\n    }\n  }\n  if (miniMetadata.source !== MODULE_TYPE) {\n    log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE}`),\n      })),\n    }\n  }\n  if (miniMetadata.chainId !== networkId) {\n    log.warn(\n      `Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE}. Expected chainId is ${networkId}`\n    )\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: Expected chainId is ${networkId}`),\n      })),\n    }\n  }\n\n  const queries = buildQueries(networkId, balanceDefs, miniMetadata)\n\n  const balances = await fetchRpcQueryPack(connector, networkId, queries)\n\n  return balanceDefs.reduce<FetchBalanceResults>(\n    (acc, def) => {\n      const balance = balances.find(\n        (b) => b?.address === def.address && b?.tokenId === def.token.id\n      )\n      if (balance) acc.success.push(balance)\n      //if no entry consider empty balance\n      else\n        acc.success.push({\n          address: def.address,\n          networkId,\n          tokenId: def.token.id,\n          source: MODULE_TYPE,\n          status: \"live\",\n          values: [\n            { type: \"free\", label: \"free\", amount: \"0\" },\n            { type: \"locked\", label: \"frozen\", amount: \"0\" },\n          ],\n        })\n      return acc\n    },\n    { success: [], errors: [] }\n  )\n}\n","import { Binary } from \"@polkadot-api/substrate-bindings\"\nimport {\n  type AnyMiniMetadata,\n  type SubAssetsToken,\n  SubAssetsTokenSchema,\n  subAssetTokenId,\n} from \"@talismn/chaindata-provider\"\nimport { getStorageKeyPrefix } from \"@talismn/scale\"\nimport { assign, keyBy, keys } from \"lodash-es\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { QueryStorageResult } from \"../shared\"\nimport { parseMetadataRpcCached } from \"../shared/parseMetadataRpcCached\"\nimport { MODULE_TYPE, type TokenConfig } from \"./config\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  connector,\n  miniMetadata,\n}) => {\n  const anyMiniMetadata = miniMetadata as AnyMiniMetadata\n  if (!anyMiniMetadata?.data) return []\n\n  const { builder } = parseMetadataRpcCached(anyMiniMetadata.data)\n  const assetCodec = builder.buildStorage(\"Assets\", \"Asset\")\n  const metadataCodec = builder.buildStorage(\"Assets\", \"Metadata\")\n\n  const [allAssetStorageKeys, allMetadataStorageKeys] = await Promise.all([\n    connector.send<`0x${string}`[]>(networkId, \"state_getKeys\", [\n      getStorageKeyPrefix(\"Assets\", \"Asset\"),\n    ]),\n    connector.send<`0x${string}`[]>(networkId, \"state_getKeys\", [\n      getStorageKeyPrefix(\"Assets\", \"Metadata\"),\n    ]),\n  ])\n\n  const [assetStorageResults, metadataStorageResults] = await Promise.all([\n    connector.send<QueryStorageResult>(networkId, \"state_queryStorageAt\", [allAssetStorageKeys]),\n    connector.send<QueryStorageResult>(networkId, \"state_queryStorageAt\", [allMetadataStorageKeys]),\n  ])\n\n  const assetStorageEntries = assetStorageResults.length ? assetStorageResults[0].changes : []\n  const metadataStorageEntries = metadataStorageResults.length\n    ? metadataStorageResults[0].changes\n    : []\n\n  const assetByAssetId = keyBy(\n    assetStorageEntries.map(([key, value]) => {\n      const [assetId] = assetCodec.keys.dec(key) as [number]\n      const asset = assetCodec.value.dec(value) as {\n        is_sufficient: boolean\n        min_balance: bigint\n      }\n      return { assetId, existentialDeposit: asset.min_balance, isSufficient: asset.is_sufficient }\n    }),\n    (a) => a.assetId\n  )\n\n  const metadataByAssetId = keyBy(\n    metadataStorageEntries.map(([key, value]) => {\n      const [assetId] = metadataCodec.keys.dec(key) as [number]\n      const metadata = metadataCodec.value.dec(value) as {\n        decimals?: number\n        deposit?: bigint\n        is_frozen?: boolean\n        name?: Uint8Array\n        symbol?: Uint8Array\n      }\n      return {\n        assetId,\n        decimals: metadata.decimals,\n        isFrozen: metadata.is_frozen,\n        name: metadata.name ? Binary.toText(metadata.name) : undefined,\n        symbol: metadata.symbol ? Binary.toText(metadata.symbol) : undefined,\n      }\n    }),\n    (a) => a.assetId\n  )\n\n  const allTokens = keys(assetByAssetId).map((assetId) =>\n    assign({}, assetByAssetId[assetId], metadataByAssetId[assetId] ?? undefined)\n  )\n\n  const configTokenByAssetId = keyBy(tokens, (t) => t.assetId)\n\n  return (\n    allTokens\n      .map(\n        (asset): SubAssetsToken => ({\n          id: subAssetTokenId(networkId, String(asset.assetId)),\n          type: MODULE_TYPE,\n          platform: \"polkadot\",\n          networkId,\n          assetId: String(asset.assetId),\n          isSufficient: asset.isSufficient,\n          isFrozen: asset.isFrozen,\n          name: asset.name,\n          symbol: asset.symbol as string,\n          decimals: asset.decimals ?? 0,\n          existentialDeposit: String(asset.existentialDeposit),\n          isDefault: true,\n        })\n      )\n      // keep all tokens listed in the config + all tokens marked as sufficient\n      .filter((token) => {\n        const configToken = configTokenByAssetId[token.assetId]\n        return configToken || token.isSufficient\n      })\n      // apply config overrides\n      .map((token) => {\n        const configToken = configTokenByAssetId[token.assetId]\n        return configToken ? assign({}, token, configToken) : token\n      })\n      // validate results\n      .filter((t) => {\n        const parsed = SubAssetsTokenSchema.safeParse(t)\n        // if (!parsed.success) log.warn(`Ignoring invalid token ${MODULE_TYPE}`, t)\n\n        return parsed.success\n      })\n  )\n}\n","import { type AnyMiniMetadata, MINIMETADATA_VERSION } from \"@talismn/chaindata-provider\"\nimport { compactMetadata, encodeMetadata, parseMetadataRpc } from \"@talismn/scale\"\n\nimport { deriveMiniMetadataId } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getConstantValue, hasStorageItems } from \"../shared\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = ({\n  networkId,\n  specVersion,\n  metadataRpc,\n}) => {\n  const source = MODULE_TYPE\n  const chainId = networkId\n\n  const systemVersion = getConstantValue<{ spec_version: number }>(metadataRpc, \"System\", \"Version\")\n  if (specVersion !== systemVersion.spec_version)\n    throw new Error(\n      `specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`\n    )\n\n  const id = deriveMiniMetadataId({ source, chainId, specVersion })\n\n  const { unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  if (unifiedMetadata.version < 14)\n    throw new Error(\n      `Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`\n    )\n\n  return {\n    id,\n    source,\n    chainId,\n    specVersion,\n    version: MINIMETADATA_VERSION,\n    data: getData(metadataRpc),\n    extra: null,\n  } as AnyMiniMetadata\n}\n\nconst getData = (metadataRpc: `0x${string}`): `0x${string}` | null => {\n  const { metadata, unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  // ensure the network has all the required bits\n  if (!hasStorageItems(unifiedMetadata, \"Assets\", [\"Account\", \"Asset\", \"Metadata\"])) return null\n\n  compactMetadata(metadata, [{ pallet: \"Assets\", items: [\"Account\", \"Asset\", \"Metadata\"] }])\n\n  return encodeMetadata(metadata)\n}\n","import { Binary, type Codec, Enum } from \"@polkadot-api/substrate-bindings\"\nimport { mergeUint8 } from \"@polkadot-api/utils\"\nimport { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport { parseMetadataRpc } from \"@talismn/scale\"\n\nimport type { BalanceTransferType, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n  type,\n  metadataRpc,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n  const { builder } = parseMetadataRpc(metadataRpc)\n  const method = getTransferMethod(type)\n  const { codec, location } = builder.buildCall(\"Assets\", method)\n  const args = getEncodedArgs(method, token.assetId, to, value, codec)\n  const callData = mergeUint8([new Uint8Array(location), args])\n\n  return {\n    address: from,\n    method: Binary.toHex(callData) as `0x${string}`,\n  }\n}\n\nconst getTransferMethod = (type: BalanceTransferType) => {\n  // TODO handle the case where transfer_all does not exist\n  switch (type) {\n    case \"keep-alive\":\n      return \"transfer_keep_alive\"\n    case \"all\":\n      return \"transfer_all\"\n    case \"allow-death\":\n      return \"transfer\"\n  }\n}\n\nconst getEncodedArgs = (\n  method: ReturnType<typeof getTransferMethod>,\n  assetId: string,\n  to: string,\n  value: string,\n  argsCodec: Codec<unknown>\n): Uint8Array => {\n  try {\n    switch (method) {\n      case \"transfer_keep_alive\":\n      case \"transfer\":\n        return getTransferEncodedArgs(assetId, to, value, argsCodec)\n      case \"transfer_all\":\n        return getTransferAllEncodedArgs(assetId, to, argsCodec)\n    }\n  } catch {\n    throw new Error(`Failed to encode arguments for method ${method}: ${assetId}, ${to}, ${value}`)\n  }\n}\n\nconst getEncodedValue = (codec: Codec<unknown>, possibleValue: Array<() => unknown>) => {\n  for (const getArgs of possibleValue) {\n    try {\n      return codec.enc(getArgs())\n    } catch {\n      // wrong inputs, ignore and try the next one\n    }\n  }\n\n  throw new Error(\"Failed to encode\")\n}\n\n// same inputs for both KeepAlive and allowDeath\nconst getTransferEncodedArgs = (\n  assetId: string,\n  to: string,\n  value: string,\n  codec: Codec<unknown>\n) => {\n  return getEncodedValue(codec, [\n    () => ({\n      id: Number(assetId), // for most networks\n      target: Enum(\"Id\", to),\n      amount: BigInt(value),\n    }),\n    () => ({\n      id: BigInt(assetId), // for Astar\n      target: Enum(\"Id\", to),\n      amount: BigInt(value),\n    }),\n    () => ({\n      id: BigInt(assetId), // for Neuroweb\n      target: to,\n      amount: BigInt(value),\n    }),\n  ])\n}\n\nconst getTransferAllEncodedArgs = (assetId: string, to: string, codec: Codec<unknown>) => {\n  return getEncodedValue(codec, [\n    () => ({\n      id: Number(assetId), // for most networks\n      dest: Enum(\"Id\", to),\n      keep_alive: false,\n    }),\n    () => ({\n      id: BigInt(assetId), // for Astar\n      dest: Enum(\"Id\", to),\n      keep_alive: false,\n    }),\n    () => ({\n      id: BigInt(assetId), // for Neuroweb (although transfer_all does not exist)\n      dest: to,\n      keep_alive: false,\n    }),\n  ])\n}\n","import { yieldToEventLoop } from \"@talismn/util\"\nimport { defer, map, of, switchMap } from \"rxjs\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getBalanceDefs } from \"../shared\"\nimport { getRpcQueryPack$ } from \"../shared/rpcQueryPack\"\nimport { buildQueries } from \"./buildQueries\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  return defer(async () => {\n    // on a scale-builder cache miss, query building parses/builds the chain metadata\n    // (expensive, indivisible) — give it its own macrotask so it doesn't stack with\n    // the current tick's other work\n    await yieldToEventLoop()\n    return buildQueries(networkId, balanceDefs, miniMetadata)\n  }).pipe(\n    switchMap((queries) => getRpcQueryPack$(connector, networkId, queries)),\n    map((balances) => ({\n      success: balances,\n      errors: [],\n    }))\n  )\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SubAssetsBalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { SubAssetsTokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SubAssetsTokenConfigSchema = z.strictObject({\n  assetId: SubAssetsTokenSchema.shape.assetId,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type SubAssetsTokenConfig = z.infer<typeof SubAssetsTokenConfigSchema>\n","export const TAO_DECIMALS = 9n\n\n// manipulating price as bigint requires using at least as many decimals as TAO itself\nexport const ALPHA_PRICE_SCALE = 10n ** TAO_DECIMALS\n\nexport const alphaToTao = (alpha: bigint, scaledAlphaPrice: bigint): bigint => {\n  if (!alpha || !scaledAlphaPrice) return 0n\n  return (alpha * scaledAlphaPrice) / ALPHA_PRICE_SCALE\n}\n\nexport const taoToAlpha = (tao: bigint, scaledAlphaPrice: bigint): bigint => {\n  if (!tao || !scaledAlphaPrice) return 0n\n  return (tao * ALPHA_PRICE_SCALE) / scaledAlphaPrice\n}\n\n/**\n * Like taoToAlpha but rounds up. Use for \"must keep / must send at least this much alpha\"\n * thresholds: the chain floors the alpha→TAO conversion when checking its TAO-denominated\n * minimums, so a floored alpha threshold can sit one planck below the real bound — an amount\n * meeting it exactly would still fail the on-chain check (or get the position force-swept).\n * Guarantees alphaToTao(taoToAlphaCeil(tao, price), price) >= tao.\n */\nexport const taoToAlphaCeil = (tao: bigint, scaledAlphaPrice: bigint): bigint => {\n  if (!tao || !scaledAlphaPrice) return 0n\n  return (tao * ALPHA_PRICE_SCALE + scaledAlphaPrice - 1n) / scaledAlphaPrice\n}\n","import type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport { decodeScale, type MetadataBuilder, type ScaleStorageCoder } from \"@talismn/scale\"\n\nimport log from \"../../log\"\nimport { fetchRuntimeCallResult, hasRuntimeApi, hasStorageItems } from \"../shared\"\nimport { parseMetadataRpcCached } from \"../shared/parseMetadataRpcCached\"\nimport { fetchRpcQueryPack, type MaybeStateKey, type RpcQueryPack } from \"../shared/rpcQueryPack\"\nimport type {\n  GetColdkeyLockResult,\n  SubDTaoBalanceMeta,\n  SubDTaoConvictionLock,\n  SubDTaoConvictionLockType,\n} from \"./types\"\n\n/** A decoded SubtensorModule.Lock storage key: (coldkey, netuid, hotkey) */\ntype ConvictionLockStorageKey = {\n  address: string\n  netuid: number\n  hotkey: string\n}\n\nexport type FetchedConvictionLock = {\n  address: string\n  netuid: number\n  lock: SubDTaoConvictionLock\n}\n\nconst convictionLockKey = (address: string, netuid: number) => `${address}:${netuid}`\n\nexport const getConvictionLockLabel = (lockType: SubDTaoConvictionLockType): string =>\n  lockType === \"perpetual\" ? \"Perpetual Conviction Lock\" : \"Decaying Conviction Lock\"\n\nexport type DTaoConvictionLockInfo = {\n  amount: bigint\n  /** the hotkey the lock is keyed on: required to top-up (the chain rejects a different hotkey) */\n  hotkey: string\n  lockType: SubDTaoConvictionLockType\n  label: string\n}\n\n// structural subset of the formatted locks exposed by Balance#locks,\n// kept loose to avoid a circular dependency on the Balance class\ntype BalanceLockLike = {\n  amount: { planck: bigint }\n  meta?: unknown\n}\n\n/**\n * Extracts the dtao conviction lock from a Balance locks array (Balance#locks), if any.\n * The locked amount cannot be unstaked until the lock decays (or ever, if perpetual);\n * transferring it is allowed but moves the lock and its conviction to the recipient.\n */\nexport const findDTaoConvictionLock = (\n  locks: BalanceLockLike[] | null | undefined\n): DTaoConvictionLockInfo | null => {\n  for (const lock of locks ?? []) {\n    const meta = lock.meta as SubDTaoBalanceMeta | undefined\n    if (meta?.convictionLock?.type !== \"conviction-lock\") continue\n\n    const lockType = meta.convictionLock.lockType\n    return {\n      amount: lock.amount.planck,\n      hotkey: meta.convictionLock.hotkey,\n      lockType,\n      label: getConvictionLockLabel(lockType),\n    }\n  }\n\n  return null\n}\n\n/**\n * Coerces a dynamically-decoded numeric field to bigint. Fixed-point newtypes (eg the U64F64\n * conviction) decode as a plain bigint when the builder unwraps the wrapper struct, or as\n * `{ bits }` when it doesn't — accept both; anything else is 0n.\n */\nexport const toBigIntValue = (value: unknown): bigint => {\n  if (typeof value === \"bigint\") return value\n  if (value && typeof value === \"object\" && \"bits\" in value) {\n    const bits = (value as { bits: unknown }).bits\n    if (typeof bits === \"bigint\") return bits\n  }\n  return 0n\n}\n\n/**\n * Fetches Bittensor conviction locks (SubtensorModule.Lock) for the given coldkey addresses.\n *\n * On-chain, a lock constrains the coldkey's TOTAL alpha on the subnet across all of its hotkeys\n * (available_to_unstake = Σ stakes - locked_mass), with at most one locked hotkey per (coldkey, netuid).\n * The lock is reported with the hotkey it is keyed on (used for conviction credit and lock top-ups),\n * and is attached to the subnet's base token balance rather than to a staking position.\n *\n * Locks are discovered with one storage prefix scan per coldkey, independently of staking positions:\n * the chain keeps a zero-mass Lock entry alive while it still carries conviction (\"ghost\" lock),\n * even after the coldkey fully unstaked from the subnet.\n */\nexport const fetchConvictionLocks = async (\n  connector: IChainConnectorDot,\n  networkId: string,\n  metadataRpc: `0x${string}`,\n  addresses: string[]\n): Promise<FetchedConvictionLock[]> => {\n  if (!addresses.length) return []\n\n  const { unifiedMetadata, builder } = parseMetadataRpcCached(metadataRpc)\n  if (\n    !hasRuntimeApi(unifiedMetadata, \"StakeInfoRuntimeApi\", \"get_coldkey_lock\") ||\n    !hasStorageItems(unifiedMetadata, \"SubtensorModule\", [\"Lock\", \"DecayingLock\"])\n  ) {\n    return []\n  }\n\n  try {\n    const lockStorageCoder = builder.buildStorage(\"SubtensorModule\", \"Lock\")\n    const decayingLockStorageCoder = builder.buildStorage(\"SubtensorModule\", \"DecayingLock\")\n\n    const lockStorageKeys = await fetchConvictionLockStorageKeys(\n      connector,\n      networkId,\n      addresses,\n      lockStorageCoder\n    )\n    if (!lockStorageKeys.length) return []\n\n    const hotkeyByPair = new Map(\n      lockStorageKeys.map(({ address, netuid, hotkey }) => [\n        convictionLockKey(address, netuid),\n        hotkey,\n      ])\n    )\n\n    const [lockModesByPair, lockStates] = await Promise.all([\n      fetchConvictionLockModes(connector, networkId, lockStorageKeys, decayingLockStorageCoder),\n      fetchColdkeyLockStates(connector, networkId, builder, lockStorageKeys),\n    ])\n\n    return lockStates.flatMap(({ address, netuid, lockState }) => {\n      const amount = lockState?.locked_mass ?? 0n\n      const convictionRaw = toBigIntValue(lockState?.conviction)\n      // keep zero-mass locks that still carry conviction (\"ghost\" locks): the chain keeps the\n      // Lock entry alive and pins future lock_stake calls to its hotkey (LockHotkeyMismatch)\n      if (amount <= 0n && convictionRaw <= 0n) return []\n\n      const hotkey = hotkeyByPair.get(convictionLockKey(address, netuid))\n      if (!hotkey) return []\n\n      return [\n        {\n          address,\n          netuid,\n          lock: {\n            amount,\n            hotkey,\n            lockType: lockModesByPair.get(convictionLockKey(address, netuid)) ?? \"decaying\",\n            convictionRaw: convictionRaw.toString(),\n          },\n        },\n      ]\n    })\n  } catch (cause) {\n    // propagate instead of returning []: an empty result reads as \"no locks\", the provider\n    // deletes the stored lock-only balances, and the rows flap back in on the next\n    // successful poll. Throwing fails the whole poll so those balances go stale instead\n    log.warn(`Failed to fetch Bittensor conviction locks on ${networkId}`, { cause })\n    throw cause\n  }\n}\n\n/**\n * Discovers all Lock entries of the given coldkeys, with one storage prefix scan per coldkey.\n * Encoding only the first map key (the coldkey) yields the storage key prefix covering all of the\n * coldkey's (netuid, hotkey) entries, using the hashers declared in metadata.\n */\nconst fetchConvictionLockStorageKeys = async (\n  connector: IChainConnectorDot,\n  networkId: string,\n  addresses: string[],\n  storageCoder: ScaleStorageCoder\n): Promise<ConvictionLockStorageKey[]> => {\n  const keysPerAddress = await Promise.all(\n    addresses.map(async (address): Promise<ConvictionLockStorageKey[]> => {\n      let keyPrefix: string\n      try {\n        keyPrefix = storageCoder.keys.enc(address)\n      } catch (cause) {\n        // an unencodable key prefix (metadata drift) would make the address read as lock-free\n        // and delete its lock-only balances — fail the poll (stale) instead, like decode failures\n        log.warn(\n          `Failed to encode conviction Lock key prefix (address=${address}) on ${networkId}`,\n          { cause }\n        )\n        throw cause\n      }\n\n      let stateKeys: `0x${string}`[]\n      try {\n        stateKeys = await connector.send<`0x${string}`[]>(networkId, \"state_getKeys\", [keyPrefix])\n      } catch (cause) {\n        // transient RPC failure: swallowing it would make every lock of this address read\n        // as removed for one poll (delete + re-add flap downstream) — fail the poll instead\n        log.warn(`Failed to fetch conviction Lock keys (address=${address}) on ${networkId}`, {\n          cause,\n        })\n        throw cause\n      }\n\n      return stateKeys.flatMap((stateKey) => {\n        try {\n          const [, netuid, hotkey] = storageCoder.keys.dec(stateKey) as [string, number, string]\n          // report the lock under the requested address (the prefix guarantees it is the\n          // coldkey) to keep the address format consistent with the rest of the pipeline\n          return [{ address, netuid, hotkey }]\n        } catch (cause) {\n          // a returned state key that fails decode is a bad response (or metadata drift),\n          // not an absent lock — fail the poll (stale) instead of silently dropping it\n          log.warn(`Failed to decode conviction Lock key ${stateKey} on ${networkId}`, { cause })\n          throw cause\n        }\n      })\n    })\n  )\n\n  return keysPerAddress.flat()\n}\n\nconst fetchConvictionLockModes = async (\n  connector: IChainConnectorDot,\n  networkId: string,\n  pairs: Array<Pick<ConvictionLockStorageKey, \"address\" | \"netuid\">>,\n  storageCoder: ScaleStorageCoder\n): Promise<Map<string, SubDTaoConvictionLockType>> => {\n  const queries = pairs.map(\n    ({ address, netuid }): RpcQueryPack<[string, SubDTaoConvictionLockType]> => {\n      let stateKey: MaybeStateKey\n      try {\n        stateKey = storageCoder.keys.enc(address, netuid) as MaybeStateKey\n      } catch (cause) {\n        // an unencodable key (metadata drift) would silently default the pair to \"decaying\"\n        // below, mislabeling a perpetual lock — fail the poll instead, like decode failures\n        log.warn(\n          `Failed to encode conviction DecayingLock key (netuid=${netuid}, address=${address}) on ${networkId}`,\n          { cause }\n        )\n        throw cause\n      }\n\n      const key = convictionLockKey(address, netuid)\n\n      return {\n        stateKeys: [stateKey],\n        decodeResult: (changes) => {\n          const hexValue = changes[0]\n          if (!hexValue) return [key, \"decaying\"]\n\n          const decoded = decodeScale<boolean | null>(\n            storageCoder,\n            hexValue,\n            `Failed to decode DecayingLock for (netuid=${netuid}, address=${address}) on ${networkId}`\n          )\n          // present-but-undecodable: defaulting to \"decaying\" would mislabel a perpetual lock\n          if (decoded === null)\n            throw new Error(\n              `Failed to decode DecayingLock for (netuid=${netuid}, address=${address}) on ${networkId}`\n            )\n\n          return [key, decoded === false ? \"perpetual\" : \"decaying\"]\n        },\n      }\n    }\n  )\n\n  return new Map(await fetchRpcQueryPack(connector, networkId, queries))\n}\n\nconst fetchColdkeyLockStates = async (\n  connector: IChainConnectorDot,\n  networkId: string,\n  builder: MetadataBuilder,\n  pairs: Array<Pick<ConvictionLockStorageKey, \"address\" | \"netuid\">>\n): Promise<Array<{ address: string; netuid: number; lockState: GetColdkeyLockResult }>> => {\n  return Promise.all(\n    pairs.map(async ({ address, netuid }) => {\n      try {\n        const lockState = await fetchRuntimeCallResult<GetColdkeyLockResult>(\n          connector,\n          networkId,\n          builder,\n          \"StakeInfoRuntimeApi\",\n          \"get_coldkey_lock\",\n          [address, netuid]\n        )\n        return { address, netuid, lockState }\n      } catch (cause) {\n        // a null lockState decodes as zero mass + zero conviction and the lock is silently\n        // dropped — transient RPC failures must fail the poll, not erase the lock\n        log.warn(\n          `Failed to fetch get_coldkey_lock for (netuid=${netuid}, address=${address}) on ${networkId}`,\n          { cause }\n        )\n        throw cause\n      }\n    })\n  )\n}\n","import { SubDTaoTokenSchema } from \"@talismn/chaindata-provider\"\nimport type z from \"zod/v4\"\n\nimport type { SubDTaoTokenConfigSchema } from \"./types\"\n\nexport const MODULE_TYPE = SubDTaoTokenSchema.shape.type.value\nexport const PLATFORM = SubDTaoTokenSchema.shape.platform.value\n\nexport type TokenConfig = z.infer<typeof SubDTaoTokenConfigSchema>\n","import { subDTaoTokenId } from \"@talismn/chaindata-provider\"\n\nimport type { SubDTaoBalance } from \"./types\"\n\nexport const calculatePendingRootClaimable = ({\n  stake,\n  hotkey,\n  address,\n  networkId,\n  validatorRootClaimableRate,\n  alreadyClaimedByNetuid,\n}: {\n  stake: bigint\n  hotkey: string\n  address: string\n  networkId: string\n  validatorRootClaimableRate: Map<number, bigint>\n  alreadyClaimedByNetuid: Map<number, bigint>\n}): SubDTaoBalance[] => {\n  const pendingRootClaimBalances: SubDTaoBalance[] = []\n\n  for (const [netuid, claimableRate] of validatorRootClaimableRate) {\n    if (claimableRate === 0n) {\n      continue\n    }\n    // Calculate claimable = claimable_rate * root_stake\n    // Note: claimableRate is a I96F32, a fixed-point number format\n\n    // Multiply claimable_rate by root_stake\n    // I96F32 multiplication: round((a * b) / 2^32)\n    const totalClaimable = (stake * claimableRate + (1n << 31n)) >> 32n\n\n    // Subtract already claimed amount to get net pending claimable\n    const alreadyClaimed = alreadyClaimedByNetuid.get(netuid) ?? 0n\n    const pendingRootClaim = totalClaimable > alreadyClaimed ? totalClaimable - alreadyClaimed : 0n\n\n    pendingRootClaimBalances.push({\n      address,\n      tokenId: subDTaoTokenId(networkId, netuid, hotkey),\n      baseTokenId: subDTaoTokenId(networkId, netuid),\n      hotkey: hotkey,\n      netuid: netuid,\n      pendingRootClaim,\n      stake: 0n,\n    })\n  }\n\n  return pendingRootClaimBalances\n}\n","import type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport {\n  getCleanToken,\n  type SubDTaoToken,\n  subDTaoTokenId,\n  TokenSchema,\n} from \"@talismn/chaindata-provider\"\nimport { decodeScale, type parseMetadataRpc } from \"@talismn/scale\"\nimport {\n  createTimeSlicer,\n  forEachWithYield,\n  isAbortError,\n  isNotNil,\n  mapWithYield,\n} from \"@talismn/util\"\nimport { keyBy, uniq } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { AmountWithLabel, IBalance } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { fetchRuntimeCallResult } from \"../shared\"\nimport { parseMetadataRpcCached } from \"../shared/parseMetadataRpcCached\"\nimport { fetchRpcQueryPack, type MaybeStateKey, type RpcQueryPack } from \"../shared/rpcQueryPack\"\nimport { getBalanceDefs } from \"../shared/types\"\nimport { calculatePendingRootClaimable } from \"./calculatePendingRootClaimable\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchConvictionLocks, getConvictionLockLabel } from \"./convictionLocks\"\nimport type { GetStakeInfosResult, SubDTaoBalance, SubDTaoBalanceMeta } from \"./types\"\n\nconst ROOT_NETUID = 0\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n  signal,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  if (!miniMetadata?.data) {\n    log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`, {\n      tokensWithAddresses,\n    })\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(\"Minimetadata is required for fetching balances\"),\n      })),\n    }\n  }\n  if (miniMetadata.source !== MODULE_TYPE) {\n    log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE}`),\n      })),\n    }\n  }\n  if (miniMetadata.chainId !== networkId) {\n    log.warn(\n      `Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE}. Expected chainId is ${networkId}`\n    )\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: Expected chainId is ${networkId}`),\n      })),\n    }\n  }\n\n  const addresses = uniq(balanceDefs.map((def) => def.address))\n\n  try {\n    // pre-parse once (memoized) — parsing the raw metadataRpc per call is expensive\n    const { builder } = parseMetadataRpcCached(miniMetadata.data!)\n\n    const stakeInfos = await fetchRuntimeCallResult<GetStakeInfosResult>(\n      connector,\n      networkId,\n      builder,\n      \"StakeInfoRuntimeApi\",\n      \"get_stake_info_for_coldkeys\",\n      [addresses]\n    )\n\n    const rootHotkeys = uniq(\n      stakeInfos.flatMap(([, stakes]) =>\n        stakes.filter((stake) => stake.netuid === ROOT_NETUID).map((stake) => stake.hotkey)\n      )\n    )\n    const rootClaimableRatesByHotkey =\n      rootHotkeys.length && miniMetadata.data\n        ? await fetchRootClaimableRates(connector, networkId, miniMetadata.data, rootHotkeys)\n        : new Map<string, Map<number, bigint>>()\n\n    // Collect all (address, hotkey, netuid) pairs for root stakes to fetch RootClaimed amounts\n    const addressHotkeyNetuidPairs: Array<[address: string, hotkey: string, netuid: number]> = []\n    for (const [address, stakes] of stakeInfos) {\n      for (const stake of stakes) {\n        if (stake.netuid === ROOT_NETUID) {\n          const claimableRates = rootClaimableRatesByHotkey.get(stake.hotkey)\n          if (claimableRates) {\n            // For each netuid that has a claimable rate, we need to check RootClaimed\n            for (const netuid of claimableRates.keys()) {\n              addressHotkeyNetuidPairs.push([address, stake.hotkey, netuid])\n            }\n          }\n        }\n      }\n    }\n\n    const [rootClaimedAmounts, convictionLocks] = await Promise.all([\n      addressHotkeyNetuidPairs.length && miniMetadata.data\n        ? fetchRootClaimedAmounts(connector, networkId, miniMetadata.data, addressHotkeyNetuidPairs)\n        : Promise.resolve(new Map<string, Map<string, Map<number, bigint>>>()),\n      miniMetadata.data\n        ? fetchConvictionLocks(connector, networkId, miniMetadata.data, addresses)\n        : Promise.resolve([]),\n    ])\n\n    // Upserts a balance into the accumulator, merging stake values if the balance already exists.\n    // Eg: Acc X has root staked with validator Y, but also staked on sn 45 with the same validator Y.\n    // We merge the pending root claim of sn 45 and the sn 45 stake in the same balance.\n    const upsertBalance = (\n      acc: Record<string, SubDTaoBalance>,\n      address: string,\n      tokenId: string,\n      balance: SubDTaoBalance\n    ): void => {\n      const key = `${address}:${tokenId}`\n      const recordedBalance = acc[key]\n      if (recordedBalance) {\n        acc[key] = {\n          ...recordedBalance,\n          stake: recordedBalance.stake + balance.stake,\n          // If the new balance has pendingRootClaim, use it (it's calculated from current state)\n          ...(balance.pendingRootClaim !== undefined && {\n            pendingRootClaim: balance.pendingRootClaim,\n          }),\n          ...(balance.convictionLock !== undefined && {\n            convictionLock: balance.convictionLock,\n          }),\n        }\n      } else {\n        acc[key] = balance\n      }\n    }\n\n    // one shared slicer across all loops below: the nested stakes×hotkeys×netuids work is\n    // time-sliced so it yields the thread on budget, and aborts when the poll unsubscribes\n    const slicer = createTimeSlicer({ signal, label: `dtao fetchBalances ${networkId}` })\n\n    const balancesRaw: Record<string, SubDTaoBalance> = {}\n    for (const [address, stakes] of stakeInfos) {\n      await forEachWithYield(\n        stakes,\n        (stake) => {\n          // Regular stake cases\n          const balance: SubDTaoBalance = {\n            address,\n            tokenId: subDTaoTokenId(networkId, stake.netuid, stake.hotkey),\n            baseTokenId: subDTaoTokenId(networkId, stake.netuid),\n            stake: stake.stake,\n            hotkey: stake.hotkey,\n            netuid: stake.netuid,\n          }\n\n          upsertBalance(balancesRaw, address, balance.tokenId, balance)\n\n          // Root stake cases, we need to calculate the pending root claim and add to the balances\n          if (stake.netuid === ROOT_NETUID) {\n            const claimableRates = rootClaimableRatesByHotkey.get(stake.hotkey) ?? new Map()\n            const alreadyClaimedMap =\n              rootClaimedAmounts.get(address)?.get(stake.hotkey) ?? new Map<number, bigint>()\n\n            const pendingRootClaimBalances = calculatePendingRootClaimable({\n              stake: stake.stake,\n              hotkey: stake.hotkey,\n              address,\n              networkId,\n              validatorRootClaimableRate: claimableRates,\n              alreadyClaimedByNetuid: alreadyClaimedMap,\n            })\n            pendingRootClaimBalances.forEach((balance) => {\n              upsertBalance(balancesRaw, address, balance.tokenId, balance)\n            })\n          }\n        },\n        { slicer }\n      )\n    }\n\n    await forEachWithYield(\n      convictionLocks,\n      ({ address, netuid, lock }) => {\n        // A conviction lock constrains the coldkey's TOTAL alpha on the subnet (across all of its\n        // hotkeys), not a specific staking position: report it on the subnet's base token (no hotkey).\n        // It surfaces in the portfolio's locked column but does NOT reduce available/transferable\n        // (the locked stake remains transferable via transfer_stake): staking/unstake flows cap\n        // per-position amounts with the subnet-wide available-to-unstake amount instead.\n        const balance: SubDTaoBalance = {\n          address,\n          tokenId: subDTaoTokenId(networkId, netuid),\n          baseTokenId: subDTaoTokenId(networkId, netuid),\n          stake: 0n,\n          hotkey: lock.hotkey,\n          netuid,\n          convictionLock: lock,\n        }\n\n        upsertBalance(balancesRaw, address, balance.tokenId, balance)\n      },\n      { slicer }\n    )\n\n    const balances = Object.values(balancesRaw)\n\n    const tokensById = keyBy(\n      tokensWithAddresses.map(([token]) => token),\n      (t) => t.id\n    )\n    const dynamicTokens: SubDTaoToken[] = []\n    const requestedTokenIds = new Set(balanceDefs.map((def) => def.token.id))\n\n    // identify tokens that were not requested but have balances\n    // BalanceProvider will be register them in ChaindataProvider at runtime, so they will be requested on next call\n    await forEachWithYield(\n      balances,\n      (bal) => {\n        // base token balances (eg conviction locks) use the already-registered template token\n        if (bal.tokenId === bal.baseTokenId) return\n        if (!requestedTokenIds.has(bal.tokenId)) {\n          const baseToken = tokensById[bal.baseTokenId] as SubDTaoToken | undefined\n          // define a token specific to this staking hotkey\n          if (baseToken) {\n            const cleanToken = getCleanToken(baseToken) as SubDTaoToken\n            const newToken = TokenSchema.parse({\n              ...cleanToken,\n              id: bal.tokenId,\n              hotkey: bal.hotkey,\n            }) as SubDTaoToken\n            dynamicTokens.push(newToken)\n          }\n        }\n      },\n      { slicer }\n    )\n\n    const success: IBalance[] = (\n      await mapWithYield(\n        balanceDefs,\n        (def): IBalance | null => {\n          // balancesRaw is keyed `${address}:${tokenId}` — direct lookup instead of O(n) find\n          const stake = balancesRaw[`${def.address}:${def.token.id}`]\n\n          // do NOT fabricate zero balances for defs with no on-chain record: with the\n          // full token list (all subnets × hotkeys × addresses) that meant building —\n          // and running change-detection over — thousands of objects on every 6s poll\n          // for downstream to discard. Absent balances are handled by the provider's\n          // storage update (expected-but-missing ids are deleted), so a position\n          // dropping to zero still disappears from the portfolio.\n          if (!stake) return null\n\n          const stakeAmount = BigInt(stake.stake?.toString() ?? \"0\")\n          const pendingRootClaimAmount = BigInt(stake.pendingRootClaim?.toString() ?? \"0\")\n          const convictionLockAmount = BigInt(stake.convictionLock?.amount?.toString() ?? \"0\")\n          const convictionLockConviction = BigInt(stake.convictionLock?.convictionRaw ?? \"0\")\n          const hasZeroStake = stakeAmount === 0n\n          const hasPendingRootClaim = pendingRootClaimAmount > 0n\n\n          const balanceValue: AmountWithLabel<string> = {\n            type: \"free\",\n            label: stake.netuid === 0 ? \"Root Staking\" : `Subnet Staking`,\n            amount: stakeAmount.toString(),\n          }\n\n          const pendingRootClaimValue: AmountWithLabel<string> = {\n            type: \"locked\",\n            label: \"Pending root claim\",\n            amount: pendingRootClaimAmount.toString(),\n            // The pending claim is not part of the stake (free amount): on-chain it only becomes\n            // stake once claimed (root_claim_on_subnet). Since it was never included in `free`,\n            // it must not be subtracted from it either: flag it so it does not reduce the staked\n            // position's transferable amount.\n            includeInTransferable: true,\n          }\n\n          const values: Array<AmountWithLabel<string>> = [balanceValue, pendingRootClaimValue]\n          // also surface zero-mass locks with residual conviction (\"ghost\" locks): the chain pins\n          // future lock_stake calls to their hotkey, so the lock wizard must know they exist\n          if (\n            stake.convictionLock &&\n            (convictionLockAmount > 0n || convictionLockConviction > 0n)\n          ) {\n            const convictionLockMeta: SubDTaoBalanceMeta = {\n              convictionLock: {\n                type: \"conviction-lock\",\n                hotkey: stake.convictionLock.hotkey,\n                lockType: stake.convictionLock.lockType,\n              },\n            }\n\n            values.push({\n              type: \"locked\",\n              label: getConvictionLockLabel(stake.convictionLock.lockType),\n              amount: convictionLockAmount.toString(),\n              meta: convictionLockMeta,\n            })\n          }\n\n          // If stake is 0n but there's a pendingRootClaim, add it as an extra amount\n          // with includeInTotal: true so it counts toward the total balance.\n          // This ensures the balance isn't filtered out when stake is 0n.\n          // The total.planck calculation is: free + reserved + extra (with includeInTotal: true)\n          // So by adding pendingRootClaim as extra, it will be included in total.planck.\n          if (hasZeroStake && hasPendingRootClaim) {\n            values.push({\n              type: \"extra\",\n              label: \"Pending root claim\",\n              amount: pendingRootClaimAmount.toString(),\n              includeInTotal: true,\n            })\n          }\n\n          return {\n            address: def.address,\n            networkId,\n            tokenId: def.token.id,\n            source: MODULE_TYPE,\n            status: \"live\",\n            values,\n          }\n        },\n        { slicer }\n      )\n    ).filter(isNotNil)\n\n    return {\n      success,\n      errors: [],\n      dynamicTokens,\n    }\n  } catch (err) {\n    // cancellation (poll unsubscribed mid-decode) is not a fetch failure\n    if (isAbortError(err)) throw err\n\n    log.warn(\"Failed to fetch balances for substrate-dtao\", { err })\n\n    const errors = balanceDefs.map((def) => ({\n      tokenId: def.token.id,\n      address: def.address,\n      error: new Error(`Failed to fetch balance for ${def.address} on ${networkId}`),\n    }))\n\n    return {\n      success: [],\n      errors,\n    }\n  }\n}\n\nconst buildStorageCoder = (metadataRpc: `0x${string}`, pallet: string, entry: string) => {\n  const { builder } = parseMetadataRpcCached(metadataRpc)\n  return builder.buildStorage(pallet, entry)\n}\n\nconst buildRootClaimableStorageCoder = async (\n  _connector: IChainConnectorDot,\n  networkId: string,\n  metadataRpc: `0x${string}` | null\n): Promise<ReturnType<ReturnType<typeof parseMetadataRpc>[\"builder\"][\"buildStorage\"]> | null> => {\n  let storageCoder: ReturnType<typeof buildStorageCoder> | null = null\n\n  if (metadataRpc) {\n    try {\n      storageCoder = buildStorageCoder(metadataRpc, \"SubtensorModule\", \"RootClaimable\")\n    } catch (cause) {\n      log.warn(\n        `Failed to build storage coder for SubtensorModule.RootClaimable using provided metadata on ${networkId}`,\n        { cause }\n      )\n    }\n  }\n\n  return storageCoder\n}\n\nconst buildRootClaimedStorageCoder = async (\n  networkId: string,\n  metadataRpc: `0x${string}` | null\n): Promise<ReturnType<ReturnType<typeof parseMetadataRpc>[\"builder\"][\"buildStorage\"]> | null> => {\n  let storageCoder: ReturnType<typeof buildStorageCoder> | null = null\n\n  if (metadataRpc) {\n    try {\n      storageCoder = buildStorageCoder(metadataRpc, \"SubtensorModule\", \"RootClaimed\")\n    } catch (cause) {\n      log.warn(\n        `Failed to build storage coder for SubtensorModule.RootClaimed using provided metadata on ${networkId}`,\n        { cause }\n      )\n    }\n  }\n\n  return storageCoder\n}\n\nconst buildRootClaimableQueries = (\n  networkId: string,\n  hotkeys: string[],\n  storageCoder: ReturnType<ReturnType<typeof parseMetadataRpc>[\"builder\"][\"buildStorage\"]>\n): Array<RpcQueryPack<[string, Map<number, bigint>]>> => {\n  return hotkeys.map((hotkey) => {\n    let stateKey: MaybeStateKey\n    try {\n      stateKey = storageCoder.keys.enc(hotkey) as MaybeStateKey\n    } catch (cause) {\n      // an unencodable key (metadata drift) would make the hotkey's RootClaimable read as an\n      // empty map, erasing its claim-only balances — fail the poll (stale) instead\n      log.warn(`Failed to encode storage key for hotkey ${hotkey} on ${networkId}`, { cause })\n      throw cause\n    }\n\n    const decodeResult = (changes: MaybeStateKey[]): [string, Map<number, bigint>] => {\n      const hexValue = changes[0]\n      if (!hexValue) {\n        return [hotkey, new Map<number, bigint>()]\n      }\n\n      const decoded = decodeScale<[number, bigint][] | null>(\n        storageCoder,\n        hexValue,\n        `Failed to decode RootClaimable for hotkey ${hotkey} on ${networkId}`\n      )\n      // a present-but-undecodable value is a bad response, not an absent entry: an empty\n      // map here would erase the hotkey's claim-only balances for this poll\n      if (decoded === null)\n        throw new Error(`Failed to decode RootClaimable for hotkey ${hotkey} on ${networkId}`)\n      return [hotkey, new Map(decoded)]\n    }\n\n    return {\n      stateKeys: [stateKey],\n      decodeResult,\n    }\n  })\n}\n\nconst fetchRootClaimableRates = async (\n  connector: IChainConnectorDot,\n  networkId: string,\n  metadataRpc: `0x${string}`,\n  hotkeys: string[]\n): Promise<Map<string, Map<number, bigint>>> => {\n  if (!hotkeys.length) return new Map<string, Map<number, bigint>>()\n\n  const storageCoder = await buildRootClaimableStorageCoder(connector, networkId, metadataRpc)\n  if (!storageCoder) {\n    // Fallback: return empty map for all hotkeys\n    return new Map(hotkeys.map((hotkey) => [hotkey, new Map<number, bigint>()]))\n  }\n\n  const queries = buildRootClaimableQueries(networkId, hotkeys, storageCoder)\n\n  try {\n    const results = await fetchRpcQueryPack(connector, networkId, queries)\n    return new Map(results)\n  } catch (cause) {\n    // empty rates would make claim-only balances (zero direct stake) read as non-existent\n    // for this poll — the provider would delete them and they'd flap back in on the next\n    // one. Transient fetch failures must fail the poll (balances go stale) instead\n    log.warn(`Failed to fetch RootClaimable for hotkeys on ${networkId}`, { cause })\n    throw cause\n  }\n}\n\nconst buildRootClaimedQueries = (\n  networkId: string,\n  addressHotkeyNetuidPairs: Array<[address: string, hotkey: string, netuid: number]>,\n  storageCoder: ReturnType<ReturnType<typeof parseMetadataRpc>[\"builder\"][\"buildStorage\"]>\n): Array<RpcQueryPack<[string, string, number, bigint]>> => {\n  return addressHotkeyNetuidPairs.map(([address, hotkey, netuid]) => {\n    let stateKey: MaybeStateKey\n    try {\n      // RootClaimed storage takes params: [netuid, hotkey, coldkey_ss58]\n      stateKey = storageCoder.keys.enc(netuid, hotkey, address) as MaybeStateKey\n    } catch (cause) {\n      // an unencodable key (metadata drift) would read as claimed=0, overstating the pending\n      // claim — fail the poll (stale) instead\n      log.warn(\n        `Failed to encode storage key for RootClaimed (netuid=${netuid}, hotkey=${hotkey}, address=${address}) on ${networkId}`,\n        { cause }\n      )\n      throw cause\n    }\n\n    const decodeResult = (changes: MaybeStateKey[]): [string, string, number, bigint] => {\n      const hexValue = changes[0]\n      if (!hexValue) {\n        return [address, hotkey, netuid, 0n]\n      }\n\n      const decoded = decodeScale<bigint | null>(\n        storageCoder,\n        hexValue,\n        `Failed to decode RootClaimed for (netuid=${netuid}, hotkey=${hotkey}, address=${address}) on ${networkId}`\n      )\n      // present-but-undecodable: claimed=0 would overstate the pending claim — fail the poll\n      if (decoded === null)\n        throw new Error(\n          `Failed to decode RootClaimed for (netuid=${netuid}, hotkey=${hotkey}, address=${address}) on ${networkId}`\n        )\n      return [address, hotkey, netuid, decoded]\n    }\n\n    return {\n      stateKeys: [stateKey],\n      decodeResult,\n    }\n  })\n}\n\nconst fetchRootClaimedAmounts = async (\n  connector: IChainConnectorDot,\n  networkId: string,\n  metadataRpc: `0x${string}`,\n  addressHotkeyNetuidPairs: Array<[address: string, hotkey: string, netuid: number]>\n): Promise<Map<string, Map<string, Map<number, bigint>>>> => {\n  if (!addressHotkeyNetuidPairs.length) {\n    return new Map<string, Map<string, Map<number, bigint>>>()\n  }\n\n  const storageCoder = await buildRootClaimedStorageCoder(networkId, metadataRpc)\n  if (!storageCoder) {\n    // Fallback: return empty map for all pairs\n    const result = new Map<string, Map<string, Map<number, bigint>>>()\n    for (const [address, hotkey, netuid] of addressHotkeyNetuidPairs) {\n      if (!result.has(address)) result.set(address, new Map())\n      const addressMap = result.get(address)!\n      if (!addressMap.has(hotkey)) addressMap.set(hotkey, new Map())\n      addressMap.get(hotkey)!.set(netuid, 0n)\n    }\n    return result\n  }\n\n  const queries = buildRootClaimedQueries(networkId, addressHotkeyNetuidPairs, storageCoder)\n\n  try {\n    const results = await fetchRpcQueryPack(connector, networkId, queries)\n    // Build a nested map: address -> hotkey -> netuid -> claimed amount\n    const result = new Map<string, Map<string, Map<number, bigint>>>()\n    for (const [address, hotkey, netuid, claimed] of results) {\n      if (!result.has(address)) result.set(address, new Map())\n      const addressMap = result.get(address)!\n      if (!addressMap.has(hotkey)) addressMap.set(hotkey, new Map())\n      addressMap.get(hotkey)!.set(netuid, claimed)\n    }\n    return result\n  } catch (cause) {\n    // claimed=0 fallback overstates every pending root claim for this poll (claimable\n    // minus claimed) — transient fetch failures must fail the poll, not fabricate values\n    log.warn(`Failed to fetch RootClaimed for address-hotkey-netuid pairs on ${networkId}`, {\n      cause,\n    })\n    throw cause\n  }\n}\n","import type { bittensor } from \"@polkadot-api/descriptors\"\nimport { Binary } from \"@polkadot-api/substrate-bindings\"\nimport type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport {\n  type AnyMiniMetadata,\n  type DotNetworkId,\n  type SubDTaoToken,\n  SubDTaoTokenSchema,\n  subDTaoTokenId,\n} from \"@talismn/chaindata-provider\"\nimport { getStorageKeyPrefix } from \"@talismn/scale\"\nimport { isNotNil } from \"@talismn/util\"\nimport { fromPairs } from \"lodash-es\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { fetchRuntimeCallResult, type QueryStorageResult } from \"../shared\"\nimport { parseMetadataRpcCached } from \"../shared/parseMetadataRpcCached\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\n\ntype GetDynamicInfosResult =\n  (typeof bittensor)[\"descriptors\"][\"apis\"][\"SubnetInfoRuntimeApi\"][\"get_all_dynamic_info\"][1]\n\n// hardcoded because we dont have access to native tokens from the balance module\nconst NATIVE_TOKEN_SYMBOLS: Record<string, string> = {\n  \"bittensor\": \"TAO\",\n  \"bittensor-testnet\": \"testTAO\",\n}\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  connector,\n  tokens,\n  miniMetadata,\n}) => {\n  const anyMiniMetadata = miniMetadata as AnyMiniMetadata\n  if (!anyMiniMetadata?.data) return []\n\n  const [transferableTokensMap, dynamicInfos] = await Promise.all([\n    fetchTransferableTokensMap(connector, anyMiniMetadata.data, networkId),\n    fetchRuntimeCallResult<GetDynamicInfosResult>(\n      connector,\n      networkId,\n      anyMiniMetadata.data,\n      \"SubnetInfoRuntimeApi\",\n      \"get_all_dynamic_info\",\n      []\n    ),\n  ])\n\n  return dynamicInfos\n    .filter(isNotNil)\n    .map((info): SubDTaoToken => {\n      const config = tokens.find((t) => t.netuid === info.netuid)\n\n      let symbol = new TextDecoder().decode(Uint8Array.from(info.token_symbol))\n      const subnetName =\n        (info.subnet_identity?.subnet_name\n          ? Binary.toText(info.subnet_identity.subnet_name)\n          : undefined) ?? (info.netuid === 0 ? \"Root\" : `Subnet ${info.netuid}`)\n      const name = `SN${info.netuid} | ${subnetName} ${symbol}`\n\n      // for root we want same symbol as native so they can be grouped together in portfolio\n      if (info.netuid === 0 && NATIVE_TOKEN_SYMBOLS[networkId])\n        symbol = NATIVE_TOKEN_SYMBOLS[networkId]\n\n      // if not stage in storage, consider transferable\n      const isTransferable = transferableTokensMap[info.netuid] ?? true\n\n      const token: SubDTaoToken = {\n        id: subDTaoTokenId(networkId, info.netuid),\n        type: MODULE_TYPE,\n        platform: PLATFORM,\n        networkId,\n        netuid: info.netuid,\n        isDefault: true,\n        symbol,\n        decimals: 9,\n        name,\n        subnetName,\n        isTransferable,\n      }\n\n      return Object.assign({}, token, config)\n    })\n\n    .filter((t) => {\n      const parsed = SubDTaoTokenSchema.safeParse(t)\n      return parsed.success\n    })\n}\n\nconst fetchTransferableTokensMap = async (\n  connector: IChainConnectorDot,\n  metadata: `0x${string}`,\n  networkId: DotNetworkId\n) => {\n  const { builder } = parseMetadataRpcCached(metadata)\n  const transferToggleCodec = builder.buildStorage(\"SubtensorModule\", \"TransferToggle\")\n\n  const transferToggleKeys = await connector.send<`0x${string}`[]>(networkId, \"state_getKeys\", [\n    getStorageKeyPrefix(\"SubtensorModule\", \"TransferToggle\"),\n  ])\n\n  const transferToggleResults = await connector.send<QueryStorageResult>(\n    networkId,\n    \"state_queryStorageAt\",\n    [transferToggleKeys]\n  )\n\n  const transferToggleEntries = transferToggleResults.length ? transferToggleResults[0].changes : []\n\n  return fromPairs(\n    transferToggleEntries.map(([key, value]) => {\n      const [netuid] = transferToggleCodec.keys.dec(key) as [number]\n      const isTransferable = transferToggleCodec.value.dec(value) as boolean\n      return [netuid, isTransferable]\n    })\n  )\n}\n","import { type AnyMiniMetadata, MINIMETADATA_VERSION } from \"@talismn/chaindata-provider\"\nimport { compactMetadata, encodeMetadata, parseMetadataRpc } from \"@talismn/scale\"\n\nimport { deriveMiniMetadataId } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getConstantValue } from \"../shared\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = ({\n  networkId,\n  specVersion,\n  metadataRpc,\n}) => {\n  const source = MODULE_TYPE\n  const chainId = networkId\n\n  const systemVersion = getConstantValue<{ spec_version: number }>(metadataRpc, \"System\", \"Version\")\n  if (specVersion !== systemVersion.spec_version)\n    throw new Error(\n      `specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`\n    )\n\n  const id = deriveMiniMetadataId({ source, chainId, specVersion })\n\n  const { unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  if (unifiedMetadata.version < 14)\n    throw new Error(\n      `Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`\n    )\n\n  return {\n    id,\n    source,\n    chainId,\n    specVersion,\n    version: MINIMETADATA_VERSION,\n    data: getData(metadataRpc),\n    extra: null,\n  } as AnyMiniMetadata\n}\n\nconst getData = (metadataRpc: `0x${string}`): `0x${string}` | null => {\n  const { metadata, unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  const isBittensor = unifiedMetadata.pallets.some(({ name }) => name === \"SubtensorModule\")\n  if (!isBittensor) return null\n\n  compactMetadata(\n    metadata,\n    [\n      {\n        pallet: \"SubtensorModule\",\n        items: [\"TransferToggle\", \"RootClaimable\", \"RootClaimed\", \"Lock\", \"DecayingLock\"],\n      },\n    ],\n    [\n      {\n        runtimeApi: \"StakeInfoRuntimeApi\",\n        methods: [\"get_stake_info_for_coldkeys\", \"get_coldkey_lock\"],\n      },\n      {\n        runtimeApi: \"SubnetInfoRuntimeApi\",\n        methods: [\"get_all_dynamic_info\"],\n      },\n    ]\n  )\n\n  return encodeMetadata(metadata)\n}\n","import { Binary } from \"@polkadot-api/substrate-bindings\"\nimport { mergeUint8 } from \"@polkadot-api/utils\"\nimport { isTokenOfType, parseSubDTaoTokenId } from \"@talismn/chaindata-provider\"\nimport { parseMetadataRpc } from \"@talismn/scale\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n  metadataRpc,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n  const { netuid: subnetId, hotkey } = parseSubDTaoTokenId(token.id)\n  if (!hotkey) throw new Error(`Missing hotkey`)\n\n  const { builder } = parseMetadataRpc(metadataRpc)\n  const { codec, location } = builder.buildCall(\"SubtensorModule\", \"transfer_stake\")\n\n  const args = codec.enc({\n    origin_netuid: subnetId,\n    hotkey,\n    destination_coldkey: to,\n    destination_netuid: subnetId,\n    alpha_amount: value,\n  })\n\n  const callData = mergeUint8([new Uint8Array(location), args])\n\n  return {\n    address: from,\n    method: Binary.toHex(callData) as `0x${string}`,\n  }\n}\n","import log from \"../../log\"\nimport type { AmountWithLabel, IBalance } from \"../../types/balancetypes\"\nimport type { BalanceEquivalence } from \"../shared/stabilizeBalances\"\nimport type { SubDTaoBalanceMeta } from \"./types\"\n\n/** root dividends accrue continuously; the pending-claim display is informational */\nconst CLAIM_DRIFT_TOLERANCE_BPS = 100n\n/**\n * subnet staking positions auto-compound: dividend injections land once per subnet tempo\n * (staggered across subnets, so with many positions SOME position bumps on nearly every\n * poll). Moves up to this size classify as drift (surfaced within the refresh interval);\n * anything larger (a real stake/unstake) emits immediately.\n */\nconst STAKE_DRIFT_TOLERANCE_BPS = 100n\n\n/**\n * dtao balances embed values that drift on (nearly) every block even when the user's\n * position is untouched: \"Pending root claim\" amounts accrue continuously, staking\n * positions auto-compound, and conviction locks decay.\n *\n * Without special handling, every 6s poll re-emits the full result set, which defeats\n * every distinctUntilChanged stage downstream and forces the whole pipeline\n * (aggregation, storage persistence, UI re-render) to run even though nothing\n * user-visible changed.\n *\n * This comparator classifies two emissions of the same balance (see BalanceEquivalence):\n * - \"equal\" when everything matches exactly except sub-tolerance movement of the\n *   drift-prone values above (relative to the previously EMITTED value, so movement\n *   accumulates and a sustained move still surfaces)\n * - \"drift\" when ONLY the drift-prone values moved, beyond tolerance. The stabilizer\n *   re-emits these at most once per refresh interval — important for fast-accruing\n *   values (a young pending claim can grow >1% per poll indefinitely, so a purely\n *   relative tolerance can never suppress it)\n * - \"changed\" for structural changes (stake, locks, status, value set) — emitted\n *   immediately\n */\n\nconst isWithinDriftTolerance = (previous: string, next: string, toleranceBps: bigint): boolean => {\n  if (previous === next) return true\n\n  let a: bigint\n  let b: bigint\n  try {\n    a = BigInt(previous)\n    b = BigInt(next)\n  } catch {\n    return false\n  }\n\n  // zero → non-zero (and vice versa) is always a real transition\n  if (a === 0n || b === 0n) return false\n\n  const diff = a > b ? a - b : b - a\n  const max = a > b ? a : b\n  return diff * 10_000n <= max * toleranceBps\n}\n\n/** the only labels whose amounts accrue per block (see fetchBalances) */\nconst PENDING_ROOT_CLAIM_LABEL = \"Pending root claim\"\n\ntype Classified = { equivalence: BalanceEquivalence; reason?: string }\n\nconst changed = (reason: string): Classified => ({ equivalence: \"changed\", reason })\n\n/** claims accrue and locks decay — their values may appear/disappear as amounts cross zero */\nconst isDriftProneValue = (value: AmountWithLabel<string>): boolean =>\n  value.label === PENDING_ROOT_CLAIM_LABEL ||\n  !!(value.meta as SubDTaoBalanceMeta | undefined)?.convictionLock\n\nconst classifyValue = (\n  previous: AmountWithLabel<string>,\n  next: AmountWithLabel<string>\n): Classified => {\n  // variant flags must match exactly (LockedAmount / ExtraAmount)\n  if (\n    (\"includeInTransferable\" in previous ? previous.includeInTransferable : undefined) !==\n      (\"includeInTransferable\" in next ? next.includeInTransferable : undefined) ||\n    (\"includeInTotal\" in previous ? previous.includeInTotal : undefined) !==\n      (\"includeInTotal\" in next ? next.includeInTotal : undefined)\n  )\n    return changed(\"variant flags\")\n\n  const previousMeta = previous.meta as SubDTaoBalanceMeta | undefined\n  const nextMeta = next.meta as SubDTaoBalanceMeta | undefined\n\n  // conviction-lock meta (hotkey, lockType) must match exactly\n  const previousLock = previousMeta?.convictionLock\n  const nextLock = nextMeta?.convictionLock\n  if (\n    previousLock?.type !== nextLock?.type ||\n    previousLock?.hotkey !== nextLock?.hotkey ||\n    previousLock?.lockType !== nextLock?.lockType\n  )\n    return changed(\"conviction lock meta\")\n\n  // amounts: every dtao amount kind moves continuously in its own way\n  let drift = false\n  if (previous.amount !== next.amount) {\n    if (previous.label === PENDING_ROOT_CLAIM_LABEL) {\n      // dividends accrue per block: sub-tolerance accrual is not worth surfacing at all,\n      // beyond-tolerance accrual is drift (bounded by the refresh interval)\n      if (!isWithinDriftTolerance(previous.amount, next.amount, CLAIM_DRIFT_TOLERANCE_BPS))\n        drift = true\n    } else if (previousLock) {\n      // decaying conviction locks shrink every block — always drift (a lock disappearing\n      // entirely removes its value and is treated as a drift-prone toggle instead)\n      drift = true\n    } else {\n      // stake: auto-compounding dividend injections are drift, real stake/unstake moves\n      // emit immediately\n      if (isWithinDriftTolerance(previous.amount, next.amount, STAKE_DRIFT_TOLERANCE_BPS))\n        drift = true\n      else return changed(`amount ${previous.amount}→${next.amount}`)\n    }\n  }\n\n  return { equivalence: drift ? \"drift\" : \"equal\" }\n}\n\nconst keyOf = (value: AmountWithLabel<string>) => `${value.type}|${value.label}`\n\nconst classifyBalance = (previous: IBalance, next: IBalance): Classified => {\n  if (previous.address !== next.address) return changed(\"address\")\n  if (previous.tokenId !== next.tokenId) return changed(\"tokenId\")\n  if (previous.networkId !== next.networkId) return changed(\"networkId\")\n  if (previous.source !== next.source) return changed(\"source\")\n  if (previous.status !== next.status) return changed(`status ${previous.status}→${next.status}`)\n\n  const previousValues = (\"values\" in previous ? previous.values : undefined) ?? []\n  const nextValues = (\"values\" in next ? next.values : undefined) ?? []\n\n  // match values by (type, label) key, NOT by index: value sets legitimately toggle —\n  // a pending claim or conviction lock value appears/disappears as its amount crosses\n  // zero. Toggles of drift-prone values classify as drift; anything else is structural.\n  const previousByKey = new Map(previousValues.map((value) => [keyOf(value), value]))\n  const nextByKey = new Map(nextValues.map((value) => [keyOf(value), value]))\n  if (previousByKey.size !== previousValues.length || nextByKey.size !== nextValues.length)\n    return changed(\"duplicate value keys\")\n\n  let drift = false\n\n  for (const [key, previousValue] of previousByKey) {\n    const nextValue = nextByKey.get(key)\n    if (!nextValue) {\n      if (!isDriftProneValue(previousValue)) return changed(`value removed: ${key}`)\n      drift = true\n      continue\n    }\n    const result = classifyValue(previousValue, nextValue)\n    if (result.equivalence === \"changed\") return changed(`${key}: ${result.reason}`)\n    if (result.equivalence === \"drift\") drift = true\n  }\n\n  for (const [key, nextValue] of nextByKey) {\n    if (previousByKey.has(key)) continue\n    if (!isDriftProneValue(nextValue)) return changed(`value added: ${key}`)\n    drift = true\n  }\n\n  return { equivalence: drift ? \"drift\" : \"equal\" }\n}\n\nexport const isEffectivelyEqualDTaoBalance = (\n  previous: IBalance,\n  next: IBalance\n): BalanceEquivalence => {\n  const result = classifyBalance(previous, next)\n\n  // \"changed\" forces an immediate full-pipeline emission — log WHY, so recurring\n  // emissions can be attributed to a specific field instead of guessed at\n  if (result.equivalence === \"changed\")\n    log.debug(`[dtao-classify] changed ${next.tokenId}: ${result.reason}`)\n\n  return result.equivalence\n}\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getBalanceDefs } from \"../shared\"\nimport { stabilizeModuleResults } from \"../shared/stabilizeBalances\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { isEffectivelyEqualDTaoBalance } from \"./isEffectivelyEqualDTaoBalance\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    // on hydration balances are fetched using a runtimeApi, which can't be subscribed to.\n    // => poll values for each block\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses: tokensWithAddresses,\n          connector,\n          miniMetadata,\n          signal: abortController.signal,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n      } catch (error) {\n        if (abortController.signal.aborted) return\n\n        // don't kill the subscription (balances would be stuck as stale until next resubscribe),\n        // emit balance errors so the provider can mark cached balances stale, then retry on next poll\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          miniMetadata,\n          addressesByToken: tokensWithAddresses,\n          error,\n        })\n        const fetchError = error instanceof Error ? error : new Error(String(error))\n        subscriber.next({\n          success: [],\n          errors: balanceDefs.map((def) => ({\n            tokenId: def.token.id,\n            address: def.address,\n            error: fetchError,\n          })),\n        })\n      }\n\n      if (!abortController.signal.aborted) setTimeout(poll, SUBSCRIPTION_INTERVAL)\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(\n    // reuse previous objects for balances whose only change is sub-tolerance drift of the\n    // AMM price / root-claim accrual — without this, those values move every block and\n    // the distinctUntilChanged below never suppresses a poll\n    stabilizeModuleResults(isEffectivelyEqualDTaoBalance),\n    distinctUntilChanged(isEqualModuleResults)\n  )\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SubDTaoBalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import type { bittensor } from \"@polkadot-api/descriptors\"\nimport { SubDTaoTokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SubDTaoTokenConfigSchema = z.strictObject({\n  netuid: SubDTaoTokenSchema.shape.netuid,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type SubDTaoTokenConfig = z.infer<typeof SubDTaoTokenConfigSchema>\n\nexport type SubDTaoBalanceMeta = {\n  convictionLock?: SubDTaoConvictionLockMeta\n}\n\nexport type SubDTaoConvictionLockType = \"decaying\" | \"perpetual\"\n\nexport type SubDTaoConvictionLockMeta = {\n  type: \"conviction-lock\"\n  hotkey: string\n  lockType: SubDTaoConvictionLockType\n}\n\nexport type SubDTaoBalance = {\n  address: string\n  tokenId: string\n  baseTokenId: string\n  stake: bigint\n  pendingRootClaim?: bigint\n  convictionLock?: SubDTaoConvictionLock\n  hotkey: string\n  netuid: number\n}\n\nexport type SubDTaoConvictionLock = {\n  amount: bigint\n  hotkey: string\n  lockType: SubDTaoConvictionLockType\n  convictionRaw: string\n}\n\nexport type GetStakeInfosResult =\n  (typeof bittensor)[\"descriptors\"][\"apis\"][\"StakeInfoRuntimeApi\"][\"get_stake_info_for_coldkeys\"][1]\n\n/**\n * `undefined` when the coldkey has no lock on the subnet; `null` is our own fetch-failure marker.\n * `conviction` is the raw U64F64 fixed-point value (shift right by 64 bits for the integer part),\n * despite decoding as a plain bigint.\n */\nexport type GetColdkeyLockResult =\n  | (typeof bittensor)[\"descriptors\"][\"apis\"][\"StakeInfoRuntimeApi\"][\"get_coldkey_lock\"][1]\n  | null\n","import { SubForeignAssetsTokenSchema } from \"@talismn/chaindata-provider\"\n\nexport type { SubForeignAssetsTokenConfig as TokenConfig } from \"./types\"\n\nexport const MODULE_TYPE = SubForeignAssetsTokenSchema.shape.type.value\nexport const PLATFORM = SubForeignAssetsTokenSchema.shape.platform.value\n","import type { AnyMiniMetadata } from \"@talismn/chaindata-provider\"\nimport { decodeScale, papiParse } from \"@talismn/scale\"\nimport { isNotNil } from \"@talismn/util\"\n\nimport log from \"../../log\"\nimport type { AmountWithLabel, IBalance } from \"../../types\"\nimport { buildNetworkStorageCoders } from \"../shared\"\nimport type { MaybeStateKey, RpcQueryPack } from \"../shared/rpcQueryPack\"\nimport type { BalanceDef } from \"../shared/types\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const buildQueries = (\n  networkId: string,\n  balanceDefs: BalanceDef<typeof MODULE_TYPE>[],\n  miniMetadata: AnyMiniMetadata\n): Array<RpcQueryPack<IBalance>> => {\n  const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {\n    storage: [\"ForeignAssets\", \"Account\"],\n  })\n\n  return balanceDefs\n    .map(({ token, address }): RpcQueryPack<IBalance> | null => {\n      const scaleCoder = networkStorageCoders?.storage\n\n      const getStateKey = (onChainId: string) => {\n        try {\n          return scaleCoder?.keys?.enc?.(papiParse(onChainId), address) as MaybeStateKey\n        } catch {\n          return null\n        }\n      }\n\n      const stateKey = getStateKey(token.onChainId)\n\n      if (!stateKey) {\n        log.warn(\n          `Invalid assetId / address in ${networkId} storage query ${token.onChainId} / ${address}`\n        )\n        return null\n      }\n\n      const decodeResult = (changes: MaybeStateKey[]) => {\n        /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n        type DecodedType = {\n          balance?: bigint\n          is_frozen?: boolean // most likely not used\n          reason?: { type?: \"Sufficient\" }\n          status?: { type?: \"Liquid\" } | { type?: \"Frozen\" }\n          extra?: undefined\n        }\n\n        const decoded = decodeScale<DecodedType>(\n          scaleCoder,\n          changes[0],\n          `Failed to decode substrate-assets balance on chain ${networkId}`\n        ) ?? {\n          balance: 0n,\n          is_frozen: false,\n          reason: { type: \"Sufficient\" },\n          status: { type: \"Liquid\" },\n          extra: undefined,\n        }\n\n        const isFrozen = decoded.is_frozen ?? decoded?.status?.type === \"Frozen\"\n        const amount = (decoded?.balance ?? 0n).toString()\n\n        // due to the following balance calculations, which are made in the `Balance` type:\n        //\n        // total balance        = (free balance) + (reserved balance)\n        // transferable balance = (free balance) - (frozen balance)\n        //\n        // when `isFrozen` is true we need to set **both** the `free` and `frozen` amounts\n        // of this balance to the value we received from the RPC.\n        //\n        // if we only set the `frozen` amount, then the `total` calculation will be incorrect!\n        const free = amount\n        const frozen = token.isFrozen || isFrozen ? amount : \"0\"\n\n        // include balance values even if zero, so that newly-zero values overwrite old values\n        const balanceValues: Array<AmountWithLabel<string>> = [\n          { type: \"free\", label: \"free\", amount: free.toString() },\n          { type: \"locked\", label: \"frozen\", amount: frozen.toString() },\n        ]\n\n        const balance: IBalance = {\n          source: \"substrate-assets\",\n          status: \"live\",\n          address,\n          networkId,\n          tokenId: token.id,\n          values: balanceValues,\n        }\n\n        return balance\n      }\n\n      return {\n        stateKeys: [stateKey],\n        decodeResult,\n      }\n    })\n    .filter(isNotNil)\n}\n","import log from \"../../log\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { fetchRpcQueryPack } from \"../shared/rpcQueryPack\"\nimport { getBalanceDefs } from \"../shared/types\"\nimport { buildQueries } from \"./buildQueries\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  if (!miniMetadata?.data) {\n    log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(\"Minimetadata is required for fetching balances\"),\n      })),\n    }\n  }\n  if (miniMetadata.source !== MODULE_TYPE) {\n    log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE}`),\n      })),\n    }\n  }\n  if (miniMetadata.chainId !== networkId) {\n    log.warn(\n      `Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE}. Expected chainId is ${networkId}`\n    )\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: Expected chainId is ${networkId}`),\n      })),\n    }\n  }\n\n  const queries = buildQueries(networkId, balanceDefs, miniMetadata)\n\n  const balances = await fetchRpcQueryPack(connector, networkId, queries)\n\n  return balanceDefs.reduce<FetchBalanceResults>(\n    (acc, def) => {\n      const balance = balances.find(\n        (b) => b?.address === def.address && b?.tokenId === def.token.id\n      )\n      if (balance) acc.success.push(balance)\n      //if no entry consider empty balance\n      else\n        acc.success.push({\n          address: def.address,\n          networkId,\n          tokenId: def.token.id,\n          source: MODULE_TYPE,\n          status: \"live\",\n          values: [\n            { type: \"free\", label: \"free\", amount: \"0\" },\n            { type: \"locked\", label: \"frozen\", amount: \"0\" },\n          ],\n        })\n      return acc\n    },\n    { success: [], errors: [] }\n  )\n}\n","import { Binary } from \"@polkadot-api/substrate-bindings\"\nimport {\n  type AnyMiniMetadata,\n  type SubForeignAssetsToken,\n  SubForeignAssetsTokenSchema,\n  subForeignAssetTokenId,\n} from \"@talismn/chaindata-provider\"\nimport { getStorageKeyPrefix, papiStringify } from \"@talismn/scale\"\nimport { assign, keyBy, keys } from \"lodash-es\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { QueryStorageResult } from \"../shared\"\nimport { parseMetadataRpcCached } from \"../shared/parseMetadataRpcCached\"\nimport { MODULE_TYPE, type TokenConfig } from \"./config\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  connector,\n  miniMetadata,\n}) => {\n  const anyMiniMetadata = miniMetadata as AnyMiniMetadata\n  if (!anyMiniMetadata?.data) return []\n\n  const { builder } = parseMetadataRpcCached(anyMiniMetadata.data)\n  const assetCodec = builder.buildStorage(\"ForeignAssets\", \"Asset\")\n  const metadataCodec = builder.buildStorage(\"ForeignAssets\", \"Metadata\")\n\n  const [allAssetStorageKeys, allMetadataStorageKeys] = await Promise.all([\n    connector.send<`0x${string}`[]>(networkId, \"state_getKeys\", [\n      getStorageKeyPrefix(\"ForeignAssets\", \"Asset\"),\n    ]),\n    connector.send<`0x${string}`[]>(networkId, \"state_getKeys\", [\n      getStorageKeyPrefix(\"ForeignAssets\", \"Metadata\"),\n    ]),\n  ])\n\n  const [assetStorageResults, metadataStorageResults] = await Promise.all([\n    connector.send<QueryStorageResult>(networkId, \"state_queryStorageAt\", [allAssetStorageKeys]),\n    connector.send<QueryStorageResult>(networkId, \"state_queryStorageAt\", [allMetadataStorageKeys]),\n  ])\n\n  // if there is at least one storage entry, the results will be an array with a single object\n  // some networks avec the pallet with no tokens in it, in which case the response will be an empty array\n  const assetStorageEntries: [key: `0x${string}`, value: `0x${string}`][] =\n    assetStorageResults[0]?.changes ?? []\n  const metadataStorageEntries: [key: `0x${string}`, value: `0x${string}`][] =\n    metadataStorageResults[0]?.changes ?? []\n\n  const assetByOnChainId = keyBy(\n    assetStorageEntries.map(([key, value]) => {\n      const [decodedKey] = assetCodec.keys.dec(key) as [unknown]\n      const onChainId = papiStringify(decodedKey)\n      const asset = assetCodec.value.dec(value) as {\n        is_sufficient: boolean\n        min_balance: bigint\n      }\n      return { onChainId, existentialDeposit: asset.min_balance, isSufficient: asset.is_sufficient }\n    }),\n    (a) => a.onChainId\n  )\n\n  const metadataByOnChainId = keyBy(\n    metadataStorageEntries.map(([key, value]) => {\n      const [decodedKey] = metadataCodec.keys.dec(key) as [unknown]\n      const onChainId = papiStringify(decodedKey)\n      const metadata = metadataCodec.value.dec(value) as {\n        decimals?: number\n        deposit?: bigint\n        is_frozen?: boolean\n        name?: Uint8Array\n        symbol?: Uint8Array\n      }\n      return {\n        onChainId,\n        decimals: metadata.decimals,\n        isFrozen: metadata.is_frozen,\n        name: metadata.name ? Binary.toText(metadata.name) : undefined,\n        symbol: metadata.symbol ? Binary.toText(metadata.symbol) : undefined,\n      }\n    }),\n    (a) => a.onChainId\n  )\n\n  const allTokens = keys(assetByOnChainId).map((onChainId) =>\n    assign({}, assetByOnChainId[onChainId], metadataByOnChainId[onChainId] ?? undefined)\n  )\n\n  const configTokenByOnChainId = keyBy(tokens, (t) => t.onChainId)\n\n  return (\n    allTokens\n      .map(\n        (asset): SubForeignAssetsToken => ({\n          id: subForeignAssetTokenId(networkId, asset.onChainId),\n          type: MODULE_TYPE,\n          platform: \"polkadot\",\n          networkId,\n          onChainId: String(asset.onChainId),\n          isSufficient: asset.isSufficient,\n          isFrozen: asset.isFrozen,\n          name: asset.name,\n          symbol: asset.symbol as string,\n          decimals: asset.decimals ?? 0,\n          existentialDeposit: String(asset.existentialDeposit),\n          isDefault: true,\n        })\n      )\n      // keep all tokens listed in the config + all tokens marked as sufficient\n      .filter((token) => {\n        const configToken = configTokenByOnChainId[token.onChainId]\n        return configToken || token.isSufficient\n      })\n      // apply config overrides\n      .map((token) => {\n        const configToken = configTokenByOnChainId[token.onChainId]\n        return configToken ? assign({}, token, configToken) : token\n      })\n      // validate results\n      .filter((t) => {\n        const parsed = SubForeignAssetsTokenSchema.safeParse(t)\n        // if (!parsed.success) log.warn(`Ignoring invalid token ${MODULE_TYPE}`, t)\n\n        return parsed.success\n      })\n  )\n}\n","import { type AnyMiniMetadata, MINIMETADATA_VERSION } from \"@talismn/chaindata-provider\"\nimport { compactMetadata, encodeMetadata, parseMetadataRpc } from \"@talismn/scale\"\n\nimport { deriveMiniMetadataId } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getConstantValue, hasStorageItems } from \"../shared\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = ({\n  networkId,\n  specVersion,\n  metadataRpc,\n}) => {\n  const source = MODULE_TYPE\n  const chainId = networkId\n\n  const systemVersion = getConstantValue<{ spec_version: number }>(metadataRpc, \"System\", \"Version\")\n  if (specVersion !== systemVersion.spec_version)\n    throw new Error(\n      `specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`\n    )\n\n  const id = deriveMiniMetadataId({ source, chainId, specVersion })\n\n  const { unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  if (unifiedMetadata.version < 14)\n    throw new Error(\n      `Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`\n    )\n\n  return {\n    id,\n    source,\n    chainId,\n    specVersion,\n    version: MINIMETADATA_VERSION,\n    data: getData(metadataRpc),\n    extra: null,\n  } as AnyMiniMetadata\n}\n\nconst getData = (metadataRpc: `0x${string}`): `0x${string}` | null => {\n  const { metadata, unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  // ensure the network has all the required bits\n  if (!hasStorageItems(unifiedMetadata, \"ForeignAssets\", [\"Account\", \"Asset\", \"Metadata\"]))\n    return null\n\n  compactMetadata(metadata, [{ pallet: \"ForeignAssets\", items: [\"Account\", \"Asset\", \"Metadata\"] }])\n\n  return encodeMetadata(metadata)\n}\n","import { Binary, type Codec, Enum } from \"@polkadot-api/substrate-bindings\"\nimport { mergeUint8 } from \"@polkadot-api/utils\"\nimport { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport { papiParse, parseMetadataRpc } from \"@talismn/scale\"\n\nimport type { BalanceTransferType, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n  type,\n  metadataRpc,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n  const { builder } = parseMetadataRpc(metadataRpc)\n  const method = getTransferMethod(type)\n  const { codec, location } = builder.buildCall(\"ForeignAssets\", method)\n  const args = getEncodedArgs(method, token.onChainId, to, value, codec)\n  const callData = mergeUint8([new Uint8Array(location), args])\n\n  return {\n    address: from,\n    method: Binary.toHex(callData) as `0x${string}`,\n  }\n}\n\nconst getTransferMethod = (type: BalanceTransferType) => {\n  switch (type) {\n    case \"keep-alive\":\n      return \"transfer_keep_alive\"\n    case \"all\":\n      return \"transfer_all\"\n    case \"allow-death\":\n      return \"transfer\"\n  }\n}\n\nconst getEncodedArgs = (\n  method: ReturnType<typeof getTransferMethod>,\n  onChainId: string,\n  to: string,\n  value: string,\n  argsCodec: Codec<unknown>\n): Uint8Array => {\n  try {\n    switch (method) {\n      case \"transfer_keep_alive\":\n      case \"transfer\":\n        return getTransferEncodedArgs(onChainId, to, value, argsCodec)\n      case \"transfer_all\":\n        return getTransferAllEncodedArgs(onChainId, to, argsCodec)\n    }\n  } catch {\n    throw new Error(\n      `Failed to encode arguments for method ${method}: ${onChainId}, ${to}, ${value}`\n    )\n  }\n}\n\nconst getEncodedValue = (codec: Codec<unknown>, possibleValue: Array<() => unknown>) => {\n  for (const getArgs of possibleValue) {\n    try {\n      return codec.enc(getArgs())\n    } catch {\n      // wrong inputs, ignore and try the next one\n    }\n  }\n\n  throw new Error(\"Failed to encode\")\n}\n\n// same inputs for both KeepAlive and allowDeath\nconst getTransferEncodedArgs = (\n  onChainId: string,\n  to: string,\n  value: string,\n  codec: Codec<unknown>\n) => {\n  return getEncodedValue(codec, [\n    () => ({\n      id: papiParse(onChainId), // for most networks\n      target: Enum(\"Id\", to),\n      amount: BigInt(value),\n    }),\n    () => ({\n      id: papiParse(onChainId), // for Neuroweb\n      target: to,\n      amount: BigInt(value),\n    }),\n  ])\n}\n\nconst getTransferAllEncodedArgs = (onChainId: string, to: string, codec: Codec<unknown>) => {\n  return getEncodedValue(codec, [\n    () => ({\n      id: papiParse(onChainId), // for most networks\n      dest: Enum(\"Id\", to),\n      keep_alive: false,\n    }),\n    () => ({\n      id: papiParse(onChainId), // for Neuroweb\n      dest: to,\n      keep_alive: false,\n    }),\n  ])\n}\n","import { yieldToEventLoop } from \"@talismn/util\"\nimport { defer, map, of, switchMap } from \"rxjs\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getBalanceDefs } from \"../shared\"\nimport { getRpcQueryPack$ } from \"../shared/rpcQueryPack\"\nimport { buildQueries } from \"./buildQueries\"\nimport type { MODULE_TYPE } from \"./config\"\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  return defer(async () => {\n    // on a scale-builder cache miss, query building parses/builds the chain metadata\n    // (expensive, indivisible) — give it its own macrotask so it doesn't stack with\n    // the current tick's other work\n    await yieldToEventLoop()\n    return buildQueries(networkId, balanceDefs, miniMetadata)\n  }).pipe(\n    switchMap((queries) => getRpcQueryPack$(connector, networkId, queries)),\n    map((balances) => ({\n      success: balances,\n      errors: [],\n    }))\n  )\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SubForeignAssetsBalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { SubForeignAssetsTokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SubForeignAssetsTokenConfigSchema = z.strictObject({\n  onChainId: SubForeignAssetsTokenSchema.shape.onChainId,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type SubForeignAssetsTokenConfig = z.infer<typeof SubForeignAssetsTokenConfigSchema>\n","import { SubHydrationTokenSchema } from \"@talismn/chaindata-provider\"\n\nexport type { SubHydrationTokenConfig as TokenConfig } from \"./types\"\n\nexport const MODULE_TYPE = SubHydrationTokenSchema.shape.type.value\nexport const PLATFORM = SubHydrationTokenSchema.shape.platform.value\n","import { keyBy, uniq } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { IBalance } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { fetchRuntimeCallResult } from \"../shared\"\nimport { getBalanceDefs } from \"../shared/types\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  if (!miniMetadata?.data) {\n    log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`, {\n      tokensWithAddresses,\n    })\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(\"Minimetadata is required for fetching balances\"),\n      })),\n    }\n  }\n  if (miniMetadata.source !== MODULE_TYPE) {\n    log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE}`),\n      })),\n    }\n  }\n  if (miniMetadata.chainId !== networkId) {\n    log.warn(\n      `Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE}. Expected chainId is ${networkId}`\n    )\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: Expected chainId is ${networkId}`),\n      })),\n    }\n  }\n\n  const addresses = uniq(balanceDefs.map((def) => def.address))\n\n  try {\n    const res = await Promise.all(\n      addresses.map((address) =>\n        fetchRuntimeCallResult<\n          [onChainId: number, balance: { free: bigint; reserved: bigint; frozen: bigint }][]\n        >(connector, networkId, miniMetadata.data!, \"CurrenciesApi\", \"accounts\", [address])\n      )\n    )\n\n    const fetchedBalances = addresses.flatMap((address, index) => {\n      return res[index]\n        .map(([onChainId, balance]) => ({\n          address,\n          onChainId,\n          free: balance.free.toString(),\n          reserved: balance.reserved.toString(),\n          frozen: balance.frozen.toString(),\n        }))\n        .filter((b) => b.onChainId !== undefined)\n    })\n\n    const balancesByKey = keyBy(fetchedBalances, (b) => `${b.address}:${b.onChainId}`)\n\n    const success = tokensWithAddresses.reduce((acc, [token, addresses]) => {\n      if (token.type === MODULE_TYPE)\n        for (const address of addresses) {\n          const rawBalance = balancesByKey[`${address}:${token.onChainId}`]\n\n          // the endpoint only returns entries for which the address has a non-zero\n          // balance. Do NOT fabricate zero-balance objects for the rest: with the full\n          // token list that meant building (and fingerprinting) tokens×addresses\n          // objects (1000+) on every 6s poll just for downstream to discard them — a\n          // recurring JS-thread stall. Absent balances are already handled: the\n          // provider's storage update deletes ids expected-but-missing from the result\n          // set, so a position dropping to zero still disappears from the portfolio.\n          if (!rawBalance) continue\n\n          const balance: IBalance = {\n            address,\n            networkId,\n            tokenId: token.id,\n            source: MODULE_TYPE,\n            status: \"live\",\n            values: [\n              {\n                type: \"free\",\n                label: \"free\",\n                amount: rawBalance.free.toString(),\n              },\n              {\n                type: \"reserved\",\n                label: \"reserved\",\n                amount: rawBalance.reserved.toString(),\n              },\n              {\n                type: \"locked\",\n                label: \"frozen\",\n                amount: rawBalance.frozen.toString(),\n              },\n            ],\n          }\n\n          acc.push(balance)\n        }\n\n      return acc\n    }, [] as IBalance[])\n\n    return {\n      success,\n      errors: [],\n    }\n  } catch (err) {\n    log.warn(\"Failed to fetch balances for substrate-hydration\", err)\n\n    const errors = balanceDefs.map((def) => ({\n      tokenId: def.token.id,\n      address: def.address,\n      error: new Error(`Failed to fetch balance for ${def.address} on ${networkId}`),\n    }))\n\n    return {\n      success: [],\n      errors,\n    }\n  }\n}\n","import { Binary } from \"@polkadot-api/substrate-bindings\"\nimport {\n  type AnyMiniMetadata,\n  type SubHydrationToken,\n  SubHydrationTokenSchema,\n  subHydrationTokenId,\n} from \"@talismn/chaindata-provider\"\nimport { getStorageKeyPrefix } from \"@talismn/scale\"\nimport { assign, keyBy } from \"lodash-es\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { QueryStorageResult } from \"../shared\"\nimport { parseMetadataRpcCached } from \"../shared/parseMetadataRpcCached\"\nimport { MODULE_TYPE, type TokenConfig } from \"./config\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  connector,\n  miniMetadata,\n}) => {\n  const anyMiniMetadata = miniMetadata as AnyMiniMetadata\n  if (!anyMiniMetadata?.data) return []\n\n  const { builder } = parseMetadataRpcCached(anyMiniMetadata.data)\n  const assetsCodec = builder.buildStorage(\"AssetRegistry\", \"Assets\")\n\n  const allAssetStorageKeys = await connector.send<`0x${string}`[]>(networkId, \"state_getKeys\", [\n    getStorageKeyPrefix(\"AssetRegistry\", \"Assets\"),\n  ])\n\n  const assetStorageResults = await connector.send<QueryStorageResult>(\n    networkId,\n    \"state_queryStorageAt\",\n    [allAssetStorageKeys]\n  )\n\n  const assetStorageEntries = assetStorageResults.length ? assetStorageResults[0].changes : []\n\n  const configTokenByAssetId = keyBy(tokens, (t) => t.onChainId)\n\n  return (\n    assetStorageEntries\n      .map(([key, value]) => {\n        // parse results\n        const [onChainId] = assetsCodec.keys.dec(key) as [number]\n        const asset = assetsCodec.value.dec(value) as {\n          name: Uint8Array | undefined\n          symbol: Uint8Array | undefined\n          decimals: number | undefined\n          is_sufficient: boolean\n          asset_type: { type: string }\n          existential_deposit: bigint\n        }\n\n        return {\n          onChainId,\n          assetType: asset.asset_type.type,\n          isSufficient: asset.is_sufficient,\n          name: asset.name ? Binary.toText(asset.name) : undefined,\n          symbol: asset.symbol ? Binary.toText(asset.symbol) : undefined,\n          decimals: asset.decimals,\n          existentialDeposit: asset.existential_deposit.toString(),\n        }\n      })\n      // convert asset to a SubHydrationToken\n      .map(\n        (asset): SubHydrationToken => ({\n          id: subHydrationTokenId(networkId, asset.onChainId),\n          type: MODULE_TYPE,\n          platform: \"polkadot\",\n          networkId,\n          onChainId: asset.onChainId,\n          assetType: asset.assetType as SubHydrationToken[\"assetType\"], // Erc20 or Token,\n          isSufficient: asset.isSufficient,\n          name: asset.name,\n          symbol: asset.symbol as string,\n          decimals: asset.decimals ?? 0,\n          existentialDeposit: asset.existentialDeposit,\n          isDefault: true,\n        })\n      )\n      // keep all tokens listed in the config + all tokens marked as sufficient\n      .filter((token) => {\n        const configToken = configTokenByAssetId[token.onChainId]\n        return configToken || token.isSufficient\n      })\n      // apply config overrides\n      .map((token) => {\n        const configToken = configTokenByAssetId[token.onChainId]\n        return configToken ? assign({}, token, configToken) : token\n      })\n      // validate results\n      .filter((t) => {\n        const parsed = SubHydrationTokenSchema.safeParse(t)\n        // if (!parsed.success) log.warn(`Ignoring invalid token ${MODULE_TYPE}`, t)\n\n        return parsed.success\n      })\n  )\n}\n","import { type AnyMiniMetadata, MINIMETADATA_VERSION } from \"@talismn/chaindata-provider\"\nimport { compactMetadata, encodeMetadata, parseMetadataRpc } from \"@talismn/scale\"\n\nimport { deriveMiniMetadataId } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getConstantValue, hasRuntimeApi, hasStorageItem } from \"../shared\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = ({\n  networkId,\n  specVersion,\n  metadataRpc,\n}) => {\n  const source = MODULE_TYPE\n  const chainId = networkId\n\n  const systemVersion = getConstantValue<{ spec_version: number }>(metadataRpc, \"System\", \"Version\")\n  if (specVersion !== systemVersion.spec_version)\n    throw new Error(\n      `specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`\n    )\n\n  const id = deriveMiniMetadataId({ source, chainId, specVersion })\n\n  const { unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  if (unifiedMetadata.version < 14)\n    throw new Error(\n      `Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`\n    )\n\n  return {\n    id,\n    source,\n    chainId,\n    specVersion,\n    version: MINIMETADATA_VERSION,\n    data: getData(metadataRpc),\n    extra: null,\n  } as AnyMiniMetadata\n}\n\nconst getData = (metadataRpc: `0x${string}`): `0x${string}` | null => {\n  const { metadata, unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  // ensure the network has all the required bits\n  if (\n    !hasStorageItem(unifiedMetadata, \"AssetRegistry\", \"Assets\") ||\n    !hasStorageItem(unifiedMetadata, \"Tokens\", \"Accounts\") ||\n    !hasRuntimeApi(unifiedMetadata, \"CurrenciesApi\", \"accounts\")\n  )\n    return null\n\n  compactMetadata(\n    metadata,\n    [\n      { pallet: \"AssetRegistry\", items: [\"Assets\"] }, // token specs\n      { pallet: \"Tokens\", items: [\"Accounts\"] }, // balances for tokens\n    ],\n    [\n      {\n        runtimeApi: \"CurrenciesApi\",\n        methods: [\"accounts\"],\n      },\n    ]\n  )\n\n  return encodeMetadata(metadata)\n}\n","import { Binary } from \"@polkadot-api/substrate-bindings\"\nimport { mergeUint8 } from \"@polkadot-api/utils\"\nimport { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport { parseMetadataRpc } from \"@talismn/scale\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n  metadataRpc,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n  // there is only one transfer method, no existential deposit handling.\n  // => leave this to the frontend and dry runs\n  const { builder } = parseMetadataRpc(metadataRpc)\n  const { codec, location } = builder.buildCall(\"Currencies\", \"transfer\")\n  const args = {\n    dest: to,\n    currency_id: token.onChainId,\n    amount: BigInt(value),\n  }\n\n  const callData = mergeUint8([new Uint8Array(location), codec.enc(args)])\n  return {\n    address: from,\n    method: Binary.toHex(callData) as `0x${string}`,\n  }\n}\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    // on hydration balances are fetched using a runtimeApi, which can't be subscribed to.\n    // => poll values for each block\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses: tokensWithAddresses,\n          connector,\n          miniMetadata,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n\n        setTimeout(poll, SUBSCRIPTION_INTERVAL)\n      } catch (error) {\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          miniMetadata,\n          addressesByToken: tokensWithAddresses,\n          error,\n        })\n        subscriber.error(error)\n      }\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(distinctUntilChanged(isEqualModuleResults))\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SubHydrationBalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { SubHydrationTokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SubHydrationTokenConfigSchema = z.strictObject({\n  onChainId: SubHydrationTokenSchema.shape.onChainId,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type SubHydrationTokenConfig = z.infer<typeof SubHydrationTokenConfigSchema>\n","import { SubNativeTokenSchema } from \"@talismn/chaindata-provider\"\n\nexport type {\n  SubNativeMiniMetadataExtra as MiniMetadataExtra,\n  SubNativeModuleConfig as ModuleConfig,\n  SubNativeTokenConfig as TokenConfig,\n} from \"./types\"\n\nexport const MODULE_TYPE = SubNativeTokenSchema.shape.type.value\nexport const PLATFORM = SubNativeTokenSchema.shape.platform.value\n","import upperFirst from \"lodash-es/upperFirst\"\n\nimport type { Balance, BalanceFormatter, LockedAmount } from \"../../../types\"\n\nexport type BalanceLockType =\n  | \"reserved\"\n  | \"democracy\"\n  | \"crowdloan\"\n  | \"staking\"\n  | \"nompools-staking\"\n  | \"nompools-unbonding\"\n  | \"subtensor-staking\"\n  | \"vesting\"\n  | \"dapp-staking\"\n  | `other-${string}`\n  | \"other\"\n\nconst getOtherType: (input: string) => `other-${string}` = (input) =>\n  `other-${input}` as `other-${string}`\n\n/**\n * For converting the value of `lock?.id?.toUtf8?.()` which is retrieved from\n * the Balances.Locks storage key into a useful classification for our UI\n */\nexport const getLockedType = (input?: string): BalanceLockType => {\n  if (typeof input !== \"string\") return getOtherType(\"unknown\")\n\n  if (input.includes(\"vesting\")) return \"vesting\"\n  if (input.includes(\"calamvst\")) return \"vesting\" // vesting on manta network\n  if (input.includes(\"ormlvest\")) return \"vesting\" // vesting ORML tokens\n  if (input.includes(\"pyconvot\")) return \"democracy\"\n  if (input.includes(\"democrac\")) return \"democracy\"\n  if (input.includes(\"democracy\")) return \"democracy\"\n  if (input.includes(\"phrelect\")) return \"democracy\" // specific to council\n  if (input.includes(\"staking\")) return \"staking\"\n  if (input.includes(\"stkngdel\")) return \"staking\" // staking delegator\n  if (input.includes(\"stkngcol\")) return \"staking\" // staking collator\n  if (input.includes(\"kiltpstk\")) return \"staking\" // Kilt specific staking\n  if (input.includes(\"dapstake\")) return \"dapp-staking\" // Astar specific\n  if (input.includes(\"appstake\")) return \"dapp-staking\" // Quartz (unique) specific\n  if (input.includes(\"dappstaking\")) return \"dapp-staking\"\n\n  // Joystream specifics https://github.com/Joystream/pioneer/blob/dev/packages/ui/src/accounts/model/lockTypes.ts\n  if (input.includes(\"voting\")) return \"democracy\"\n  if (input.includes(\"candidac\")) return \"democracy\" // Council Candidate\n  if (input.includes(\"councilo\")) return \"democracy\" // Councilor\n  if (input.includes(\"proposal\")) return \"democracy\"\n  if (input.includes(\"boundsta\")) return \"staking\" // Bound Staking Account\n  if (input.includes(\"invitemb\")) return getOtherType(input) // Invite member\n  if (input.includes(\"bounty\")) return getOtherType(input)\n  if (input.startsWith(\"wg-\")) return getOtherType(input)\n\n  // ignore technical or undocumented lock types\n  if (input.includes(\"pdexlock\")) return getOtherType(input)\n  if (input.includes(\"phala/sp\")) return getOtherType(input)\n  if (input.includes(\"aca/earn\")) return getOtherType(input)\n  if (input.includes(\"stk_stks\")) return getOtherType(input)\n\n  // biome-ignore lint/suspicious/noConsole: legacy\n  console.warn(`unknown locked type: ${input}`)\n  return getOtherType(input)\n}\n\nconst baseLockLabels = [\"fees\", \"misc\"]\nconst isBaseLock = (lock: Pick<LockedAmount<string>, \"label\">) =>\n  baseLockLabels.includes(lock.label)\nconst isNonBaseLock = (lock: Pick<LockedAmount<string>, \"label\">) => !isBaseLock(lock)\nexport const filterBaseLocks = (\n  locks: Array<Omit<LockedAmount<string>, \"amount\"> & { amount: BalanceFormatter }>\n) => {\n  const hasNonBaseLocks = locks.some(isNonBaseLock)\n  if (!hasNonBaseLocks) return locks\n\n  return locks.filter(isNonBaseLock)\n}\n\n// TODO: Make these titles translatable\nexport const getLockTitle = (\n  lock: Pick<LockedAmount<string>, \"label\" | \"meta\">,\n  // biome-ignore lint/correctness/noUnusedFunctionParameters: legacy\n  { balance }: { balance?: Balance } = {}\n) => {\n  if (!lock.label) return lock.label\n\n  if (lock.label === \"democracy\") return \"Governance\"\n  if (lock.label === \"crowdloan\") return \"Crowdloan\"\n  if (lock.label === \"nompools-staking\") return \"Pooled Staking\"\n  if (lock.label === \"nompools-unbonding\") return \"Pooled Staking\"\n  if (lock.label === \"subtensor-staking\") return \"Root Staking\"\n  if (lock.label === \"dapp-staking\") return \"DApp Staking\"\n  if (lock.label === \"fees\") return \"Locked (Fees)\"\n  if (lock.label === \"misc\") return \"Locked\"\n  if (lock.label.startsWith(\"other\")) return \"Locked\"\n\n  return upperFirst(lock.label)\n}\n","import { Binary, type Enum } from \"@polkadot-api/substrate-bindings\"\nimport { decodeScale, type ScaleStorageCoder } from \"@talismn/scale\"\nimport { isNotNil } from \"@talismn/util\"\n\nimport type { AmountWithLabel, IBalance, MiniMetadata } from \"../../../types\"\nimport { type BalanceDef, buildNetworkStorageCoders } from \"../../shared\"\nimport type { MaybeStateKey, RpcQueryPack } from \"../../shared/rpcQueryPack\"\nimport type { MiniMetadataExtra } from \"../config\"\nimport { getLockedType } from \"../util/lockTypes\"\n\nexport type NomPoolMemberInfo = {\n  points: string\n  poolId: string\n  unbondingEras: Array<{ era: string; amount: string }>\n}\n\nexport type BaseBalance = { balance: IBalance; nomPoolMemberInfo: NomPoolMemberInfo | null }\n\nexport const buildBaseQueries = (\n  networkId: string,\n  balanceDefs: BalanceDef<\"substrate-native\">[],\n  miniMetadata: MiniMetadata<MiniMetadataExtra>\n): Array<RpcQueryPack<BaseBalance>> => {\n  const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {\n    account: [\"System\", \"Account\"],\n    stakingLedger: [\"Staking\", \"Ledger\"],\n    reserves: [\"Balances\", \"Reserves\"], // unused ??\n    holds: [\"Balances\", \"Holds\"],\n    locks: [\"Balances\", \"Locks\"],\n    freezes: [\"Balances\", \"Freezes\"],\n    poolMembers: [\"NominationPools\", \"PoolMembers\"],\n  })\n\n  if (!networkStorageCoders)\n    throw new Error(`No network storage coders found for networkId: ${networkId}`)\n\n  return balanceDefs\n    .map(({ token, address }): RpcQueryPack<BaseBalance> | null => {\n      const getStateKeys = () => {\n        try {\n          const accountStateKey = networkStorageCoders.account\n            ? (networkStorageCoders.account.keys.enc(address) as `0x${string}`)\n            : null\n\n          const locksStateKey = networkStorageCoders.locks\n            ? (networkStorageCoders.locks.keys.enc(address) as `0x${string}`)\n            : null\n\n          const freezesStateKey = networkStorageCoders.freezes\n            ? (networkStorageCoders.freezes.keys.enc(address) as `0x${string}`)\n            : null\n\n          const holdsStateKey = networkStorageCoders.holds\n            ? (networkStorageCoders.holds.keys.enc(address) as `0x${string}`)\n            : null\n\n          const stakingLedgerStateKey = networkStorageCoders.stakingLedger\n            ? (networkStorageCoders.stakingLedger.keys.enc(address) as `0x${string}`)\n            : null\n\n          const poolMemberStateKey = networkStorageCoders.poolMembers\n            ? (networkStorageCoders.poolMembers.keys.enc(address) as `0x${string}`)\n            : null\n\n          return [\n            accountStateKey,\n            locksStateKey,\n            freezesStateKey,\n            holdsStateKey,\n            stakingLedgerStateKey,\n            poolMemberStateKey,\n          ]\n        } catch {\n          // most likely invalid address\n          return []\n        }\n      }\n\n      return {\n        stateKeys: getStateKeys(),\n        decodeResult: (changes: MaybeStateKey[]) => {\n          const balance: IBalance = {\n            source: \"substrate-native\",\n            status: \"live\",\n            address,\n            networkId,\n            tokenId: token.id,\n            values: [],\n            useLegacyTransferableCalculation: miniMetadata.extra.useLegacyTransferableCalculation,\n          }\n\n          let nomPoolMemberInfo: NomPoolMemberInfo | null = null\n\n          const [\n            accountChange,\n            lockChange,\n            freezesChange,\n            holdsChange,\n            stakingLedgerChange,\n            nomPoolMemberChange,\n          ] = changes\n\n          if (networkStorageCoders.account) {\n            // for account balance we decode even empty values\n            const baseValues = decodeBaseResult(\n              networkStorageCoders.account,\n              accountChange,\n              networkId\n            )\n            balance.values.push(...baseValues)\n          }\n\n          if (networkStorageCoders.locks && lockChange) {\n            const lockValues = decodeLocksResult(networkStorageCoders.locks, lockChange, networkId)\n            balance.values.push(...lockValues)\n          }\n\n          if (networkStorageCoders.freezes && freezesChange) {\n            const freezesValues = decodeFreezesResult(\n              networkStorageCoders.freezes,\n              freezesChange,\n              networkId\n            )\n            balance.values.push(...freezesValues)\n          }\n\n          if (networkStorageCoders.holds && holdsChange) {\n            const holdsValues = decodeHoldsResult(\n              networkStorageCoders.holds,\n              holdsChange,\n              networkId\n            )\n            balance.values.push(...holdsValues)\n          }\n\n          if (networkStorageCoders.stakingLedger && stakingLedgerChange) {\n            const stakingLedgerValues = decodeStakingLedgerResult(\n              networkStorageCoders.stakingLedger,\n              stakingLedgerChange,\n              networkId\n            )\n            balance.values.push(...stakingLedgerValues)\n          }\n\n          if (networkStorageCoders.poolMembers && nomPoolMemberChange) {\n            const nomPoolMemberValue = decodePoolMemberResult(\n              networkStorageCoders.poolMembers,\n              nomPoolMemberChange,\n              networkId\n            )\n\n            if (nomPoolMemberValue) nomPoolMemberInfo = nomPoolMemberValue\n          }\n\n          return { balance, nomPoolMemberInfo }\n        },\n      }\n    })\n    .filter(isNotNil)\n}\n\nconst decodeBaseResult = (\n  coder: ScaleStorageCoder,\n  value: string | null,\n  networkId: string\n): Array<AmountWithLabel<string>> => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = {\n    data?: {\n      flags?: bigint\n      free?: bigint\n      frozen?: bigint\n      reserved?: bigint\n\n      // deprecated fields (they only show up on old chains)\n      feeFrozen?: bigint\n      miscFrozen?: bigint\n    }\n  }\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode base native balance on chain ${networkId}`\n  )\n\n  const free = (decoded?.data?.free ?? 0n).toString()\n  const reserved = (decoded?.data?.reserved ?? 0n).toString()\n  const miscLock = (\n    (decoded?.data?.miscFrozen ?? 0n) +\n    // new chains don't split their `frozen` amount into `feeFrozen` and `miscFrozen`.\n    // for these chains, we'll use the `frozen` amount as `miscFrozen`.\n    ((decoded?.data as DecodedType[\"data\"])?.frozen ?? 0n)\n  ).toString()\n  const feesLock = (decoded?.data?.feeFrozen ?? 0n).toString()\n\n  // even if these values are 0, we still need to add them to the balanceJson.values array\n  // so that the balance pool can handle newly zeroed balances\n  // const existingValues = Object.fromEntries(\n  //   balanceJson.values.map((v) => [getValueId(v), v]),\n  // )\n  const newValues: AmountWithLabel<string>[] = [\n    { type: \"free\", label: \"free\", amount: free.toString() },\n    { type: \"reserved\", label: \"reserved\", amount: reserved.toString() },\n    { type: \"locked\", label: \"misc\", amount: miscLock.toString() },\n    { type: \"locked\", label: \"fees\", amount: feesLock.toString() },\n  ]\n\n  return newValues\n}\n\nconst decodeLocksResult = (\n  coder: ScaleStorageCoder,\n  value: string | null,\n  networkId: string\n): Array<AmountWithLabel<string>> => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = Array<{\n    id?: `0x${string}`\n    amount?: bigint\n  }>\n\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode lock on chain ${networkId}`\n  )\n\n  const locksQueryLocks: Array<AmountWithLabel<string>> =\n    decoded?.map?.((lock) => {\n      // lock id is a fixed-size `[u8; 8]` (LockIdentifier), decoded as a hex string by\n      // polkadot-api v2 — convert back to its ASCII text form (e.g. \"staking \").\n      const id = lock?.id ? Binary.toText(Binary.fromHex(lock.id)) : undefined\n      return {\n        type: \"locked\" as const,\n        source: \"substrate-native-locks\",\n        label: getLockedType(id),\n        meta: { id },\n        amount: (lock?.amount ?? 0n).toString(),\n      }\n    }) ?? []\n\n  return locksQueryLocks\n}\n\nconst decodeFreezesResult = (\n  coder: ScaleStorageCoder,\n  value: `0x${string}` | null,\n  networkId: string\n): Array<AmountWithLabel<string>> => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = Array<{\n    id?: { type?: string }\n    amount?: bigint\n  }>\n\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode freeze on chain ${networkId}`\n  )\n\n  const freezesValues: Array<AmountWithLabel<string>> =\n    decoded?.map?.((lock) => ({\n      type: \"locked\",\n      source: \"substrate-native-freezes\",\n      label: getLockedType(lock?.id?.type?.toLowerCase?.()),\n      amount: lock?.amount?.toString?.() ?? \"0\",\n    })) ?? []\n\n  return freezesValues\n}\n\nconst decodeHoldsResult = (\n  coder: ScaleStorageCoder,\n  value: `0x${string}` | null,\n  networkId: string\n): Array<AmountWithLabel<string>> => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = Array<{\n    id?: Enum<{ DelegatedStaking: Enum<{ StakingDelegation: undefined }> }>\n    amount?: bigint\n  }>\n\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode holds on chain ${networkId}`\n  )\n\n  // at this time we re only interested in DelegatedStaking holds, to determine if nom pool staked amount is included in reserved or not\n  const holdsValues: Array<AmountWithLabel<string>> =\n    decoded\n      ?.filter((hold) => hold.id?.type)\n      .map((hold) => ({\n        type: \"locked\",\n        source: \"substrate-native-holds\",\n        label: hold.id!.type,\n        // anount needs to be 0 or a row could appear in the UI, this entry is just for information\n        amount: \"0\",\n        meta: { amount: (hold?.amount ?? 0n).toString() },\n      })) ?? []\n\n  return holdsValues\n}\n\nconst decodeStakingLedgerResult = (\n  coder: ScaleStorageCoder,\n  value: `0x${string}` | null,\n  networkId: string\n): Array<AmountWithLabel<string>> => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = {\n    active: bigint\n    legacy_claimed_rewards: number[]\n    stash: string\n    total: bigint\n    unlocking: Array<{\n      era: number\n      value: bigint\n    }>\n  } | null\n\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode unbonding query on chain ${networkId}`\n  )\n\n  const totalUnlocking =\n    decoded?.unlocking?.reduce?.((acc, unlocking) => acc + unlocking.value, 0n) ?? 0n\n\n  const stakingLedgerResults: Array<AmountWithLabel<string>> =\n    totalUnlocking <= 0n\n      ? []\n      : [\n          {\n            type: \"locked\",\n            source: \"substrate-native-unbonding\",\n            label: \"Unbonding\",\n            amount: totalUnlocking.toString(),\n          },\n        ]\n\n  return stakingLedgerResults\n}\n\nconst decodePoolMemberResult = (\n  coder: ScaleStorageCoder,\n  value: `0x${string}` | null,\n  networkId: string\n): NomPoolMemberInfo | null => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = {\n    pool_id: number\n    points: bigint\n    last_recorded_reward_counter?: bigint\n    /** Array of `[Era, Amount]` */\n    unbonding_eras: Array<[number, bigint] | undefined>\n  }\n\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode poolMembers on chain ${networkId}`\n  )\n\n  if (!decoded) return null\n\n  const poolId: string = decoded.pool_id.toString()\n  const points: string = decoded.points.toString()\n  const unbondingEras: Array<{ era: string; amount: string }> = Array.from(\n    decoded.unbonding_eras ?? []\n  ).flatMap((entry) => {\n    if (entry === undefined) return []\n    const [key, value] = Array.from(entry)\n\n    const era = key.toString()\n    const amount = value.toString()\n    if (typeof era !== \"string\" || typeof amount !== \"string\") return []\n\n    return { era, amount }\n  })\n\n  return { poolId, points, unbondingEras }\n}\n","import { AccountId, type SS58String } from \"@polkadot-api/substrate-bindings\"\nimport { mergeUint8 } from \"@polkadot-api/utils\"\nimport { u32 } from \"scale-ts\"\n\n/**\n * Each nominationPool in the nominationPools pallet has access to some accountIds which have no\n * associated private key. Instead, they are derived from this function.\n */\nconst nompoolAccountId = (palletId: string, poolId: string | number, index: number): SS58String => {\n  const utf8Encoder = new TextEncoder()\n  const encModPrefix = utf8Encoder.encode(\"modl\")\n  const encPalletId = utf8Encoder.encode(palletId)\n\n  const encIndex = new Uint8Array([index])\n  const encPoolId = u32.enc(typeof poolId === \"string\" ? parseInt(poolId, 10) : poolId)\n\n  const length = encModPrefix.length + encPalletId.length + encIndex.length + encPoolId.length\n  const remainingBytes = 32 - length\n  const encEmptyH256 = new Uint8Array(remainingBytes)\n\n  const bytes = mergeUint8([encModPrefix, encPalletId, encIndex, encPoolId, encEmptyH256])\n\n  return AccountId().dec(bytes)\n}\n/** The stash account for the nomination pool */\nexport const nompoolStashAccountId = (palletId: string, poolId: string | number) =>\n  nompoolAccountId(palletId, poolId, 0)\n/** The rewards account for the nomination pool */\nconst _nompoolRewardAccountId = (palletId: string, poolId: string | number) =>\n  nompoolAccountId(palletId, poolId, 1)\n","import { Binary } from \"@polkadot-api/substrate-bindings\"\nimport { decodeScale, type ScaleStorageCoder } from \"@talismn/scale\"\n\nimport type { IBalance, MiniMetadata } from \"../../../types\"\nimport { buildNetworkStorageCoders } from \"../../shared\"\nimport type { RpcQueryPack } from \"../../shared/rpcQueryPack\"\nimport type { MiniMetadataExtra } from \"../config\"\nimport { nompoolStashAccountId } from \"../util/nompoolAccountId\"\nimport type { BaseBalance, NomPoolMemberInfo } from \"./buildBaseQueries\"\n\nexport const buildNomPoolQueries = (\n  networkId: string,\n  partialBalances: BaseBalance[],\n  miniMetadata: MiniMetadata<MiniMetadataExtra>\n): Array<RpcQueryPack<IBalance>> => {\n  const networkStorageCoders = getNomPoolCoders(networkId, miniMetadata)\n\n  if (!networkStorageCoders)\n    throw new Error(`No network storage coders found for networkId: ${networkId}`)\n\n  return partialBalances.map(({ balance, nomPoolMemberInfo }) => {\n    const stateKeys = getNomPoolStateKeys(\n      networkStorageCoders,\n      nomPoolMemberInfo,\n      miniMetadata.extra\n    )\n\n    return {\n      stateKeys,\n      decodeResult: (changes: (`0x${string}` | null)[]) => {\n        if (!nomPoolMemberInfo || !stateKeys.length || changes.includes(null)) return balance\n\n        const accountPoints = nomPoolMemberInfo?.points ?? \"0\"\n\n        const { poolPoints = \"0\" } = decodePoolPoints(\n          networkStorageCoders.bondedPools!,\n          changes[0]!,\n          networkId\n        )\n        const { poolTotalActiveStake = \"0\" } = decodePoolStake(\n          networkStorageCoders.ledger!,\n          changes[1]!,\n          networkId\n        )\n        const { metadata = \"0\" } = decodePoolMeta(\n          networkStorageCoders.metadata!,\n          changes[2]!,\n          networkId\n        )\n\n        const amount =\n          accountPoints === \"0\" || poolPoints === \"0\" || poolTotalActiveStake === \"0\"\n            ? 0n\n            : (BigInt(poolTotalActiveStake) * BigInt(accountPoints)) / BigInt(poolPoints)\n\n        const unbondingAmount = nomPoolMemberInfo.unbondingEras.reduce(\n          (total, { amount }) => total + BigInt(amount ?? \"0\"),\n          0n\n        )\n\n        return {\n          ...balance,\n          values: [\n            ...(balance.values?.filter(({ source }) => source !== \"nompools-staking\") ?? []),\n            {\n              source: \"nompools-staking\",\n              type: \"nompool\",\n              label: \"nompools-staking\",\n              amount: amount.toString(),\n              meta: { type: \"nompool\", poolId: nomPoolMemberInfo.poolId, description: metadata },\n            },\n            {\n              source: \"nompools-staking\",\n              type: \"nompool\",\n              label: \"nompools-unbonding\",\n              amount: unbondingAmount.toString(),\n              meta: {\n                poolId: nomPoolMemberInfo.poolId,\n                description: metadata ?? `Pool ${nomPoolMemberInfo.poolId}`,\n                unbonding: true,\n              },\n            },\n          ],\n        }\n      },\n    }\n  })\n}\n\nconst getNomPoolCoders = (networkId: string, miniMetadata: MiniMetadata<MiniMetadataExtra>) => {\n  return buildNetworkStorageCoders(networkId, miniMetadata, {\n    poolMembers: [\"NominationPools\", \"PoolMembers\"],\n    bondedPools: [\"NominationPools\", \"BondedPools\"],\n    ledger: [\"Staking\", \"Ledger\"],\n    metadata: [\"NominationPools\", \"Metadata\"],\n  })\n}\n\nconst decodePoolPoints = (coder: ScaleStorageCoder, value: string, networkId: string) => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = {\n    commission?: unknown\n    member_counter?: number\n    points: bigint\n    roles?: unknown\n    state?: unknown\n  }\n\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode bondedPools on chain ${networkId}`\n  )\n\n  return { poolPoints: decoded?.points.toString() }\n}\n\nconst decodePoolStake = (coder: ScaleStorageCoder, value: string, networkId: string) => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = {\n    active: bigint\n    legacy_claimed_rewards?: number[]\n    stash?: string\n    total?: bigint\n    unlocking?: Array<{ value?: bigint; era?: number }>\n  }\n\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode ledger on chain ${networkId}`\n  )\n\n  return { poolTotalActiveStake: decoded?.active.toString() }\n}\n\nconst decodePoolMeta = (coder: ScaleStorageCoder, value: string, networkId: string) => {\n  /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n  type DecodedType = Uint8Array\n\n  const decoded = decodeScale<DecodedType>(\n    coder,\n    value,\n    `Failed to decode metadata on chain ${networkId}`\n  )\n\n  const metadata = decoded ? Binary.toText(decoded) : undefined\n\n  return { metadata }\n}\n\nconst getNomPoolStateKeys = (\n  coders: ReturnType<typeof getNomPoolCoders>,\n  nomPoolMemberInfo: NomPoolMemberInfo | null,\n  extra: MiniMetadataExtra\n): `0x${string}`[] => {\n  if (\n    !nomPoolMemberInfo ||\n    !extra.nominationPoolsPalletId ||\n    !coders?.bondedPools ||\n    !coders.ledger ||\n    !coders.metadata\n  )\n    return []\n\n  try {\n    const poolId = nomPoolMemberInfo.poolId\n    const stashAddress = nompoolStashAccountId(extra.nominationPoolsPalletId, poolId)\n\n    const poolPointsStateKey = coders.bondedPools.keys.enc(poolId) as `0x${string}`\n    const poolStakeStateKey = coders.ledger.keys.enc(stashAddress) as `0x${string}`\n    const poolMetaStateKey = coders.metadata.keys.enc(poolId) as `0x${string}`\n\n    return [poolPointsStateKey, poolStakeStateKey, poolMetaStateKey]\n  } catch {\n    return []\n  }\n}\n","import log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { fetchRpcQueryPack } from \"../shared/rpcQueryPack\"\nimport { getBalanceDefs } from \"../shared/types\"\nimport { type MiniMetadataExtra, MODULE_TYPE, type ModuleConfig, type TokenConfig } from \"./config\"\nimport { buildBaseQueries } from \"./queries/buildBaseQueries\"\nimport { buildNomPoolQueries } from \"./queries/buildNomPoolQueries\"\n\nexport const fetchBalances: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n>[\"fetchBalances\"] = async ({ networkId, tokensWithAddresses, connector, miniMetadata }) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  if (!miniMetadata?.data) {\n    log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(\"Minimetadata is required for fetching balances\"),\n      })),\n    }\n  }\n  if (miniMetadata.source !== MODULE_TYPE) {\n    log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE}`),\n      })),\n    }\n  }\n  if (miniMetadata.chainId !== networkId) {\n    log.warn(\n      `Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE}. Expected chainId is ${networkId}`\n    )\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: Expected chainId is ${networkId}`),\n      })),\n    }\n  }\n\n  const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata)\n  const partialBalances = await fetchRpcQueryPack(connector, networkId, baseQueries)\n\n  // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool\n  const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata)\n  const balances = await fetchRpcQueryPack(connector, networkId, nomPoolQueries)\n\n  return { success: balances, errors: [] }\n}\n","import type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport {\n  type SubNativeToken,\n  SubNativeTokenSchema,\n  subNativeTokenId,\n} from \"@talismn/chaindata-provider\"\nimport { assign } from \"lodash-es\"\nimport z from \"zod/v4\"\n\nimport log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { MiniMetadataExtra, MODULE_TYPE, ModuleConfig, TokenConfig } from \"./config\"\n\nexport const fetchTokens: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n>[\"fetchTokens\"] = async ({ networkId, tokens, connector, miniMetadata }) => {\n  if (miniMetadata.extra.disable) return []\n\n  const { tokenSymbol: symbol, tokenDecimals: decimals } = await getChainProperties(\n    connector,\n    networkId\n  )\n\n  if (!miniMetadata.extra.existentialDeposit)\n    log.warn(`Substrate native module: existentialDeposit is undefined for ${networkId}, using 0`)\n\n  const tokenConfig: TokenConfig | undefined = tokens[0]\n\n  const nativeToken: SubNativeToken = {\n    id: subNativeTokenId(networkId),\n    type: \"substrate-native\",\n    platform: \"polkadot\",\n    networkId,\n    isDefault: true,\n    symbol: symbol,\n    name: symbol,\n    decimals: decimals,\n    existentialDeposit: miniMetadata.extra.existentialDeposit ?? \"0\",\n  }\n\n  const token = assign(nativeToken, tokenConfig)\n\n  const parsed = SubNativeTokenSchema.safeParse(token)\n  if (!parsed.success) {\n    // log.warn(`Ignoring invalid token ${MODULE_TYPE}`, token, parsed.error)\n    return []\n  }\n\n  return [parsed.data]\n}\n\n// some nodes (e.g. the reset Paseo relay) serialize numbers as strings in system_properties\n// (tokenDecimals: \"10\"), so coerce rather than require a JSON number.\nconst DotNetworkPropertiesSimple = z.object({\n  tokenDecimals: z.coerce.number().optional().default(0),\n  tokenSymbol: z.string().optional().default(\"Unit\"),\n})\n\nconst DotNetworkPropertiesArray = z.object({\n  tokenDecimals: z.array(z.coerce.number()).nonempty(),\n  tokenSymbol: z.array(z.string()).nonempty(),\n})\n\nconst DotNetworkPropertiesSchema = z\n  .union([DotNetworkPropertiesSimple, DotNetworkPropertiesArray])\n  .transform((val) => ({\n    tokenDecimals: Array.isArray(val.tokenDecimals) ? val.tokenDecimals[0] : val.tokenDecimals,\n    tokenSymbol: Array.isArray(val.tokenSymbol) ? val.tokenSymbol[0] : val.tokenSymbol,\n  }))\n\nconst getChainProperties = async (connector: IChainConnectorDot, networkId: string) => {\n  const properties = await connector.send(networkId, \"system_properties\", [], true)\n  return DotNetworkPropertiesSchema.parse(properties)\n}\n","import { Binary } from \"@polkadot-api/substrate-bindings\"\nimport { MINIMETADATA_VERSION } from \"@talismn/chaindata-provider\"\nimport { compactMetadata, encodeMetadata, parseMetadataRpc } from \"@talismn/scale\"\n\nimport { deriveMiniMetadataId } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getConstantValue, tryGetConstantValue } from \"../shared\"\nimport { type MiniMetadataExtra, MODULE_TYPE, type ModuleConfig, type TokenConfig } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n>[\"getMiniMetadata\"] = ({ networkId, specVersion, metadataRpc, config }) => {\n  const source = MODULE_TYPE\n  const chainId = networkId\n\n  const systemVersion = getConstantValue<{ spec_version: number }>(metadataRpc, \"System\", \"Version\")\n  if (specVersion !== systemVersion.spec_version)\n    throw new Error(\n      `specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`\n    )\n\n  const id = deriveMiniMetadataId({ source, chainId, specVersion })\n\n  const { metadata, unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  if (unifiedMetadata.version < 14)\n    throw new Error(\n      `Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`\n    )\n\n  if (config?.disable)\n    return {\n      id,\n      source,\n      chainId,\n      specVersion,\n      version: MINIMETADATA_VERSION,\n      data: null,\n      extra: { disable: true },\n    }\n\n  const existentialDeposit = tryGetConstantValue<bigint>(\n    metadataRpc,\n    \"Balances\",\n    \"ExistentialDeposit\"\n  )?.toString()\n  // NominationPools.PalletId is a fixed-size `[u8; 8]`, which polkadot-api v2 decodes to a hex\n  // string. Convert it back to its ASCII text form (e.g. \"py/nopls\"), which nompoolAccountId\n  // re-encodes as utf-8 to derive pool account ids.\n  const nominationPoolsPalletIdHex = tryGetConstantValue<`0x${string}`>(\n    metadataRpc,\n    \"NominationPools\",\n    \"PalletId\"\n  )\n  const nominationPoolsPalletId = nominationPoolsPalletIdHex\n    ? Binary.toText(Binary.fromHex(nominationPoolsPalletIdHex))\n    : undefined\n\n  const hasFreezesItem = Boolean(\n    unifiedMetadata.pallets\n      .find(({ name }) => name === \"Balances\")\n      ?.storage?.items.find(({ name }) => name === \"Freezes\")\n  )\n  const useLegacyTransferableCalculation = !hasFreezesItem\n\n  compactMetadata(metadata, [\n    { pallet: \"System\", constants: [\"Version\", \"SS58Prefix\"], items: [\"Account\"] },\n    { pallet: \"Balances\", items: [\"Reserves\", \"Holds\", \"Locks\", \"Freezes\"] },\n    { pallet: \"NominationPools\", items: [\"PoolMembers\", \"BondedPools\", \"Metadata\"] },\n    { pallet: \"Staking\", items: [\"Ledger\"] },\n  ])\n\n  return {\n    id,\n    source,\n    chainId,\n    specVersion,\n    version: MINIMETADATA_VERSION,\n    data: encodeMetadata(metadata),\n    extra: {\n      useLegacyTransferableCalculation,\n      existentialDeposit,\n      nominationPoolsPalletId,\n    },\n  }\n}\n","import { Binary, Enum } from \"@polkadot-api/substrate-bindings\"\nimport { mergeUint8 } from \"@polkadot-api/utils\"\nimport { isTokenOfType } from \"@talismn/chaindata-provider\"\nimport {\n  type Codec,\n  type MetadataLookup,\n  parseMetadataRpc,\n  type UnifiedMetadata,\n} from \"@talismn/scale\"\n\nimport type { BalanceTransferType, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] = ({\n  from,\n  to,\n  value,\n  token,\n  type,\n  metadataRpc,\n}) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n  const { unifiedMetadata, lookupFn, builder } = parseMetadataRpc(metadataRpc)\n  const method = getTransferMethod(type, unifiedMetadata, lookupFn)\n\n  const { codec, location } = builder.buildCall(\"Balances\", method)\n  const args = getEncodedArgs(method, to, value, codec)\n  const callData = mergeUint8([new Uint8Array(location), args])\n\n  return {\n    address: from,\n    method: Binary.toHex(callData) as `0x${string}`,\n  }\n}\n\nconst getTransferMethod = (\n  type: BalanceTransferType,\n  unifiedMetadata: UnifiedMetadata,\n  lookupFn: MetadataLookup\n) => {\n  switch (type) {\n    case \"keep-alive\":\n      return \"transfer_keep_alive\"\n    case \"all\":\n      return \"transfer_all\"\n    case \"allow-death\": {\n      const callType = unifiedMetadata.pallets.find((pallet) => pallet.name === \"Balances\")?.calls\n        ?.type\n\n      if (callType) {\n        const palletCalls = lookupFn(callType)\n        if (palletCalls.type === \"enum\" && palletCalls.value.transfer_allow_death)\n          return \"transfer_allow_death\"\n      }\n\n      // legacy fallback\n      return \"transfer\"\n    }\n  }\n}\n\nconst getEncodedArgs = (\n  method: ReturnType<typeof getTransferMethod>,\n  to: string,\n  value: string,\n  argsCodec: Codec<unknown>\n): Uint8Array => {\n  try {\n    switch (method) {\n      case \"transfer_allow_death\":\n      case \"transfer_keep_alive\":\n      case \"transfer\":\n        return getTransferEncodedArgs(to, value, argsCodec)\n      case \"transfer_all\":\n        return getTransferAllEncodedArgs(to, argsCodec)\n    }\n  } catch {\n    throw new Error(`Failed to encode arguments for method ${method}, ${to}, ${value}`)\n  }\n}\n\nconst getEncodedValue = (codec: Codec<unknown>, possibleValue: Array<() => unknown>) => {\n  for (const getArgs of possibleValue) {\n    try {\n      return codec.enc(getArgs())\n    } catch {\n      // wrong inputs, ignore and try the next one\n    }\n  }\n\n  throw new Error(\"Failed to encode\")\n}\n\n// same inputs for both KeepAlive and allowDeath\nconst getTransferEncodedArgs = (to: string, value: string, codec: Codec<unknown>) => {\n  return getEncodedValue(codec, [\n    () => ({\n      dest: Enum(\"Id\", to),\n      value: BigInt(value),\n    }),\n    () => ({\n      dest: to, // ex: native MYTH on Mythos\n      value: BigInt(value),\n    }),\n  ])\n}\n\nconst getTransferAllEncodedArgs = (to: string, codec: Codec<unknown>) => {\n  return getEncodedValue(codec, [\n    () => ({\n      dest: Enum(\"Id\", to),\n      keep_alive: false,\n    }),\n    () => ({\n      dest: to,\n      keep_alive: false,\n    }),\n  ])\n}\n","import { yieldToEventLoop } from \"@talismn/util\"\nimport { defer, map, of, switchMap } from \"rxjs\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getBalanceDefs } from \"../shared\"\nimport { getRpcQueryPack$ } from \"../shared/rpcQueryPack\"\nimport type { MiniMetadataExtra, MODULE_TYPE, ModuleConfig, TokenConfig } from \"./config\"\nimport { buildBaseQueries } from \"./queries/buildBaseQueries\"\nimport { buildNomPoolQueries } from \"./queries/buildNomPoolQueries\"\n\nexport const subscribeBalances: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n>[\"subscribeBalances\"] = ({ networkId, tokensWithAddresses, connector, miniMetadata }) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  // could be use as shared observable key if we decide to cache the sub\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  return defer(async () => {\n    // on a scale-builder cache miss, query building parses/builds the chain metadata\n    // (expensive, indivisible) — give it its own macrotask so it doesn't stack with\n    // the current tick's other work\n    await yieldToEventLoop()\n    return buildBaseQueries(networkId, balanceDefs, miniMetadata)\n  }).pipe(\n    switchMap((baseQueries) => getRpcQueryPack$(connector, networkId, baseQueries)),\n    switchMap((partialBalances) => {\n      // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool\n      const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata)\n      return getRpcQueryPack$(connector, networkId, nomPoolQueries)\n    }),\n    map((balances) => ({\n      success: balances,\n      errors: [],\n    }))\n  )\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport {\n  type MiniMetadataExtra,\n  MODULE_TYPE,\n  type ModuleConfig,\n  PLATFORM,\n  type TokenConfig,\n} from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SubNativeBalanceModule: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SubNativeTokenConfigSchema = z.strictObject({\n  ...TokenConfigBaseSchema.shape,\n})\n\n// Do not use this type outside of this module\nexport type SubNativeTokenConfig = z.infer<typeof SubNativeTokenConfigSchema>\n\nexport const SubNativeModuleConfigSchema = z.strictObject({\n  disable: z.boolean().optional(),\n})\n\n// Do not use this type outside of this module\nexport type SubNativeModuleConfig = z.infer<typeof SubNativeModuleConfigSchema>\n\nexport const SubNativeMiniMetadataExtraSchema = z.strictObject({\n  disable: z.boolean().optional(),\n  useLegacyTransferableCalculation: z.boolean().optional(),\n  existentialDeposit: z.string().optional(),\n  nominationPoolsPalletId: z.string().optional(),\n})\n\n// Do not use this type outside of this module\nexport type SubNativeMiniMetadataExtra = z.infer<typeof SubNativeMiniMetadataExtraSchema>\n","import { SubPsp22TokenSchema } from \"@talismn/chaindata-provider\"\n\nexport type { SubPsp22TokenConfig as TokenConfig } from \"./types\"\n\nexport const MODULE_TYPE = SubPsp22TokenSchema.shape.type.value\nexport const PLATFORM = SubPsp22TokenSchema.shape.platform.value\n","","import { getSs58AddressInfo } from \"@polkadot-api/substrate-bindings\"\nimport { fromHex, mergeUint8, toHex } from \"@polkadot-api/utils\"\nimport type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport { Bytes, compact, Enum, enhanceCodec, Result, Struct, u32, u128 } from \"scale-ts\"\n\nimport psp22Abi from \"../abis/psp22.json\"\n\n/** decodes an ss58 address to its 32-byte account id */\nconst accountId32 = (address: string): Uint8Array => {\n  const info = getSs58AddressInfo(address)\n  if (!info.isValid || info.publicKey.length !== 32) throw new Error(`Invalid address: ${address}`)\n  return info.publicKey\n}\n\nconst getPsp22MessageSelector = (label: string): Uint8Array => {\n  const message = psp22Abi.spec.messages.find((message) => message.label === label)\n  if (!message) throw new Error(`Unable to find message ${label} in PSP22 ABI`)\n  return fromHex(message.selector)\n}\n\nconst EMPTY_BYTES = new Uint8Array(0)\n\n/**\n * Encoders for the ink! PSP22 contract messages used by this module.\n *\n * An ink! message payload is the 4-byte selector (from the ABI) followed by the SCALE-encoded arguments.\n */\nexport const encodePsp22Message = {\n  /** PSP22::balance_of(owner: AccountId) */\n  balanceOf: (owner: string): Uint8Array =>\n    mergeUint8([getPsp22MessageSelector(\"PSP22::balance_of\"), accountId32(owner)]),\n\n  /** PSP22Metadata::token_symbol() */\n  tokenSymbol: (): Uint8Array => getPsp22MessageSelector(\"PSP22Metadata::token_symbol\"),\n\n  /** PSP22Metadata::token_decimals() */\n  tokenDecimals: (): Uint8Array => getPsp22MessageSelector(\"PSP22Metadata::token_decimals\"),\n\n  /** PSP22::transfer(to: AccountId, value: u128, data: Vec<u8>) - with empty data */\n  transfer: (to: string, value: bigint): Uint8Array =>\n    mergeUint8([\n      getPsp22MessageSelector(\"PSP22::transfer\"),\n      accountId32(to),\n      u128.enc(value),\n      Bytes().enc(EMPTY_BYTES),\n    ]),\n}\n\nconst compactBigInt = enhanceCodec(\n  compact,\n  (value: bigint) => value,\n  (value) => BigInt(value)\n)\n\nconst WeightV2 = Struct({ refTime: compactBigInt, proofSize: compactBigInt })\n\n/** pallet_contracts::ContractExecResult, as returned by the ContractsApi_call runtime api */\nconst ContractExecResultCodec = Struct({\n  gasConsumed: WeightV2,\n  gasRequired: WeightV2,\n  storageDeposit: Enum({ Refund: u128, Charge: u128 }),\n  debugMessage: Bytes(),\n  result: Result(\n    Struct({ flags: u32, data: Bytes() }),\n    Bytes(Infinity) // DispatchError - keep the raw bytes, this module doesn't consume them\n  ),\n})\n\n/** encodes the arguments of the ContractsApi_call runtime api */\nconst encodeContractsApiCallArgs = (\n  callFrom: string,\n  contractAddress: string,\n  inputData: Uint8Array\n): Uint8Array =>\n  mergeUint8([\n    // origin: AccountId\n    accountId32(callFrom),\n    // dest: AccountId\n    accountId32(contractAddress),\n    // value: Balance\n    u128.enc(0n),\n    // gasLimit: Option<WeightV2> = None\n    Uint8Array.of(0),\n    // storageDepositLimit: Option<Balance> = None\n    Uint8Array.of(0),\n    // inputData: Vec<u8>\n    Bytes().enc(inputData),\n  ])\n\nexport const makeContractCaller =\n  ({ chainConnector, chainId }: { chainConnector: IChainConnectorDot; chainId: string }) =>\n  async (callFrom: string, contractAddress: string, inputData: Uint8Array) =>\n    ContractExecResultCodec.dec(\n      await chainConnector.send<string>(chainId, \"state_call\", [\n        \"ContractsApi_call\",\n        toHex(encodeContractsApiCallArgs(callFrom, contractAddress, inputData)),\n      ])\n    )\n","import type { IBalance } from \"../../types\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { BalanceFetchError } from \"../shared\"\nimport { getBalanceDefs } from \"../shared/types\"\nimport type { MODULE_TYPE } from \"./config\"\nimport { encodePsp22Message, makeContractCaller } from \"./util\"\n\n/**\n * Reads the first 16 bytes of the contract return data as a little-endian u128.\n *\n * Note: for contracts returning `MessageResult<u128, LangError>` the data starts with the\n * `Ok` tag byte - this replicates the legacy `registry.createType(\"Balance\", data)` behavior.\n */\nconst decodeBalance = (data: Uint8Array): bigint => {\n  const bytes = data.subarray(0, 16)\n  let value = 0n\n  for (let i = bytes.length - 1; i >= 0; i--) value = (value << 8n) | BigInt(bytes[i] as number)\n  return value\n}\n\nexport const fetchBalances: IBalanceModule<typeof MODULE_TYPE>[\"fetchBalances\"] = async ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n}) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  if (!balanceDefs.length) return { success: [], errors: [] }\n\n  const contractCall = makeContractCaller({\n    chainConnector: connector,\n    chainId: networkId,\n  })\n\n  const results = await Promise.allSettled(\n    balanceDefs.map(async ({ token, address }) => {\n      const result = await contractCall(\n        address,\n        token.contractAddress,\n        encodePsp22Message.balanceOf(address)\n      )\n\n      if (!result.result.success) throw new Error(\"Failed to fetch balance\")\n\n      const value = decodeBalance(result.result.value.data).toString()\n\n      const balance: IBalance = {\n        source: \"substrate-psp22\",\n        status: \"live\",\n        address,\n        networkId: token.networkId,\n        tokenId: token.id,\n        value,\n      }\n\n      return balance\n    })\n  )\n\n  return results.reduce<FetchBalanceResults>(\n    (acc, result) => {\n      if (result.status === \"fulfilled\") acc.success.push(result.value as IBalance)\n      else {\n        const error = result.reason as BalanceFetchError\n        acc.errors.push({\n          tokenId: error.tokenId,\n          address: error.address,\n          error,\n        })\n      }\n      return acc\n    },\n    { success: [], errors: [] }\n  )\n}\n","import { toHex } from \"@polkadot-api/utils\"\nimport {\n  type SubPsp22Token,\n  SubPsp22TokenSchema,\n  subPsp22TokenId,\n} from \"@talismn/chaindata-provider\"\nimport { values } from \"lodash-es\"\n\nimport log from \"../../log\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport type { MODULE_TYPE, TokenConfig } from \"./config\"\nimport { encodePsp22Message, makeContractCaller } from \"./util\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  connector,\n}) => {\n  if (!tokens.length) return []\n\n  const contractCall = makeContractCaller({\n    chainConnector: connector,\n    chainId: networkId,\n  })\n\n  const tokenList: Record<string, SubPsp22Token> = {}\n\n  for (const tokenConfig of tokens ?? []) {\n    try {\n      let symbol = tokenConfig?.symbol ?? \"Unit\"\n      let decimals = tokenConfig?.decimals ?? 0\n      const contractAddress = tokenConfig?.contractAddress ?? undefined\n\n      if (contractAddress === undefined) continue\n\n      const [symbolResult, decimalsResult] = await Promise.all([\n        contractCall(contractAddress, contractAddress, encodePsp22Message.tokenSymbol()),\n        contractCall(contractAddress, contractAddress, encodePsp22Message.tokenDecimals()),\n      ])\n\n      if (symbolResult.result.success) {\n        const data = symbolResult.result.value.data\n        if (!data.length) throw new Error(\"Empty token_symbol response\")\n        // utf8-decode the raw return data, then strip non-printable characters\n        // (drops the SCALE framing bytes: Ok tag, Option tag and compact length prefix)\n        symbol = new TextDecoder().decode(data).replace(/\\p{C}/gu, \"\")\n      }\n\n      if (decimalsResult.result.success) {\n        // interpret the whole return data (Ok tag included) as a big-endian number\n        decimals = Number(toHex(decimalsResult.result.value.data))\n      }\n\n      const id = subPsp22TokenId(networkId, contractAddress)\n      const token: SubPsp22Token = {\n        id,\n        type: \"substrate-psp22\",\n        platform: \"polkadot\",\n        isDefault: tokenConfig.isDefault ?? true,\n        symbol,\n        decimals,\n        name: tokenConfig?.name || symbol,\n        logo: tokenConfig?.logo,\n        contractAddress,\n        networkId,\n      }\n\n      if (tokenConfig?.coingeckoId) token.coingeckoId = tokenConfig?.coingeckoId\n      if (tokenConfig?.mirrorOf) token.mirrorOf = tokenConfig?.mirrorOf\n\n      tokenList[token.id] = token\n    } catch (error) {\n      log.error(\n        `Failed to build substrate-psp22 token ${tokenConfig.contractAddress} (${tokenConfig.symbol}) on ${networkId}`,\n        (error as Error)?.message ?? error\n      )\n    }\n  }\n\n  return values(tokenList).filter((t) => {\n    const parsed = SubPsp22TokenSchema.safeParse(t)\n    // if (!parsed.success) log.warn(`Ignoring invalid token ${MODULE_TYPE}`, t)\n\n    return parsed.success\n  })\n}\n","import { type AnyMiniMetadata, MINIMETADATA_VERSION } from \"@talismn/chaindata-provider\"\nimport { parseMetadataRpc } from \"@talismn/scale\"\n\nimport { deriveMiniMetadataId } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getConstantValue } from \"../shared\"\nimport { MODULE_TYPE } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<typeof MODULE_TYPE>[\"getMiniMetadata\"] = ({\n  networkId,\n  specVersion,\n  metadataRpc,\n}) => {\n  const source = MODULE_TYPE\n  const chainId = networkId\n\n  const systemVersion = getConstantValue<{ spec_version: number }>(metadataRpc, \"System\", \"Version\")\n  if (specVersion !== systemVersion.spec_version)\n    throw new Error(\n      `specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`\n    )\n  const id = deriveMiniMetadataId({ source, chainId, specVersion })\n\n  const { unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  if (unifiedMetadata.version < 14)\n    throw new Error(\n      `Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`\n    )\n\n  return {\n    id,\n    source,\n    chainId,\n    specVersion,\n    version: MINIMETADATA_VERSION,\n    data: null,\n    extra: null,\n  } as AnyMiniMetadata\n}\n","import { Binary, Enum } from \"@polkadot-api/substrate-bindings\"\nimport { mergeUint8 } from \"@polkadot-api/utils\"\nimport { isTokenOfType, parseTokenId } from \"@talismn/chaindata-provider\"\nimport { parseMetadataRpc } from \"@talismn/scale\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { encodePsp22Message, makeContractCaller } from \"./util\"\n\nexport const getTransferCallData: IBalanceModule<typeof MODULE_TYPE>[\"getTransferCallData\"] =\n  async ({ from, to, value, token, metadataRpc, connector }) => {\n    if (!isTokenOfType(token, MODULE_TYPE))\n      throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n    const networkId = parseTokenId(token.id).networkId\n    const { builder } = parseMetadataRpc(metadataRpc)\n    const { codec, location } = builder.buildCall(\"Contracts\", \"call\")\n\n    const contractCall = makeContractCaller({\n      chainConnector: connector,\n      chainId: networkId,\n    })\n\n    const data = encodePsp22Message.transfer(to, BigInt(value))\n\n    const dryRunResult = await contractCall(from, token.contractAddress, data)\n\n    const args = codec.enc({\n      dest: Enum(\"Id\", token.contractAddress),\n      value: 0,\n      gas_limit: {\n        ref_time: dryRunResult.gasRequired.refTime,\n        proof_size: dryRunResult.gasRequired.proofSize,\n      },\n      storage_deposit_limit:\n        dryRunResult.storageDeposit.tag === \"Charge\" ? dryRunResult.storageDeposit.value : null,\n      data,\n    })\n\n    const callData = mergeUint8([new Uint8Array(location), args])\n\n    return {\n      address: from,\n      method: Binary.toHex(callData) as `0x${string}`,\n    }\n  }\n","import { reportJsActivity } from \"@talismn/util\"\nimport { distinctUntilChanged, Observable, of } from \"rxjs\"\n\nimport log from \"../../log\"\nimport { isEqualModuleResults } from \"../../types/fingerprint\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\n\nconst SUBSCRIPTION_INTERVAL = 6_000\n\nexport const subscribeBalances: IBalanceModule<typeof MODULE_TYPE>[\"subscribeBalances\"] = ({\n  networkId,\n  tokensWithAddresses,\n  connector,\n  miniMetadata,\n}) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  return new Observable<FetchBalanceResults>((subscriber) => {\n    const abortController = new AbortController()\n\n    // on hydration balances are fetched using a runtimeApi, which can't be subscribed to.\n    // => poll values for each block\n    const poll = async () => {\n      try {\n        if (abortController.signal.aborted) return\n\n        const balances = await fetchBalances({\n          networkId,\n          tokensWithAddresses: tokensWithAddresses,\n          connector,\n          miniMetadata,\n        })\n\n        if (abortController.signal.aborted) return\n\n        // poll-completion marker: fires even when the dedup gate below suppresses the\n        // emission, so stall watchdogs can attribute the poll's fetch/decode compute\n        reportJsActivity(`poll ${MODULE_TYPE} ${networkId} (${balances.success.length})`)\n\n        subscriber.next(balances)\n\n        setTimeout(poll, SUBSCRIPTION_INTERVAL)\n      } catch (error) {\n        log.error(\"Error\", {\n          module: MODULE_TYPE,\n          networkId,\n          miniMetadata,\n          addressesByToken: tokensWithAddresses,\n          error,\n        })\n        subscriber.error(error)\n      }\n    }\n\n    poll()\n\n    return () => {\n      abortController.abort()\n    }\n  }).pipe(distinctUntilChanged(isEqualModuleResults))\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SubPsp22BalanceModule: IBalanceModule<typeof MODULE_TYPE, TokenConfig> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { SubPsp22TokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SubPsp22TokenConfigSchema = z.strictObject({\n  contractAddress: SubPsp22TokenSchema.shape.contractAddress,\n  ...TokenConfigBaseSchema.shape,\n})\n\nexport type SubPsp22TokenConfig = z.infer<typeof SubPsp22TokenConfigSchema>\n","import { SubTokensTokenSchema } from \"@talismn/chaindata-provider\"\n\nexport type {\n  SubTokensMiniMetadataExtra as MiniMetadataExtra,\n  SubTokensModuleConfig as ModuleConfig,\n  SubTokensTokenConfig as TokenConfig,\n} from \"./types\"\n\nexport const MODULE_TYPE = SubTokensTokenSchema.shape.type.value\nexport const PLATFORM = SubTokensTokenSchema.shape.platform.value\n","import { decodeScale, papiParse } from \"@talismn/scale\"\nimport { isNotNil } from \"@talismn/util\"\n\nimport log from \"../../log\"\nimport type { AmountWithLabel, IBalance, MiniMetadata } from \"../../types\"\nimport { buildNetworkStorageCoders } from \"../shared\"\nimport type { MaybeStateKey, RpcQueryPack } from \"../shared/rpcQueryPack\"\nimport type { BalanceDef } from \"../shared/types\"\nimport type { MiniMetadataExtra, MODULE_TYPE } from \"./config\"\n\nexport const buildQueries = (\n  networkId: string,\n  balanceDefs: BalanceDef<typeof MODULE_TYPE>[],\n  miniMetadata: MiniMetadata<MiniMetadataExtra>\n): Array<RpcQueryPack<IBalance>> => {\n  const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {\n    storage: [miniMetadata.extra.palletId, \"Accounts\"],\n  })\n\n  return balanceDefs\n    .map(({ token, address }): RpcQueryPack<IBalance> | null => {\n      const scaleCoder = networkStorageCoders?.storage\n\n      const getStateKey = (onChainId: string | number) => {\n        try {\n          return scaleCoder!.keys.enc(address, papiParse(onChainId)) as MaybeStateKey\n        } catch {\n          return null\n        }\n      }\n\n      const stateKey = getStateKey(token.onChainId)\n\n      if (!stateKey) {\n        log.warn(\n          `Invalid assetId / address in ${networkId} storage query ${token.onChainId} / ${address}`\n        )\n        return null\n      }\n\n      const decodeResult = (changes: MaybeStateKey[]) => {\n        /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */\n        type DecodedType = {\n          free?: bigint\n          reserved?: bigint\n          frozen?: bigint\n        }\n\n        const decoded = decodeScale<DecodedType>(\n          scaleCoder,\n          changes[0],\n          `Failed to decode substrate-tokens balance on chain ${networkId}`\n        ) ?? { free: 0n, reserved: 0n, frozen: 0n }\n\n        const free = (decoded?.free ?? 0n).toString()\n        const reserved = (decoded?.reserved ?? 0n).toString()\n        const frozen = (decoded?.frozen ?? 0n).toString()\n\n        const balanceValues: Array<AmountWithLabel<string>> = [\n          { type: \"free\", label: \"free\", amount: free.toString() },\n          { type: \"reserved\", label: \"reserved\", amount: reserved.toString() },\n          { type: \"locked\", label: \"frozen\", amount: frozen.toString() },\n        ]\n\n        return {\n          source: \"substrate-tokens\",\n          status: \"live\",\n          address,\n          networkId,\n          tokenId: token.id,\n          values: balanceValues,\n        } as IBalance\n      }\n\n      return {\n        stateKeys: [stateKey],\n        decodeResult,\n      }\n    })\n    .filter(isNotNil)\n}\n","import log from \"../../log\"\nimport type { FetchBalanceResults, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { fetchRpcQueryPack } from \"../shared/rpcQueryPack\"\nimport { getBalanceDefs } from \"../shared/types\"\nimport { buildQueries } from \"./buildQueries\"\nimport { type MiniMetadataExtra, MODULE_TYPE, type ModuleConfig, type TokenConfig } from \"./config\"\n\nexport const fetchBalances: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n>[\"fetchBalances\"] = async ({ networkId, tokensWithAddresses, connector, miniMetadata }) => {\n  if (!tokensWithAddresses.length) return { success: [], errors: [] }\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  if (!miniMetadata?.data) {\n    log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(\"Minimetadata is required for fetching balances\"),\n      })),\n    }\n  }\n  if (miniMetadata.source !== MODULE_TYPE) {\n    log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE}.`)\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE}`),\n      })),\n    }\n  }\n  if (miniMetadata.chainId !== networkId) {\n    log.warn(\n      `Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE}. Expected chainId is ${networkId}`\n    )\n    return {\n      success: [],\n      errors: balanceDefs.map((def) => ({\n        tokenId: def.token.id,\n        address: def.address,\n        error: new Error(`Invalid request: Expected chainId is ${networkId}`),\n      })),\n    }\n  }\n\n  const queries = buildQueries(networkId, balanceDefs, miniMetadata)\n\n  const balances = await fetchRpcQueryPack(connector, networkId, queries)\n\n  return balanceDefs.reduce<FetchBalanceResults>(\n    (acc, def) => {\n      const balance = balances.find(\n        (b) => b?.address === def.address && b?.tokenId === def.token.id\n      )\n      if (balance) acc.success.push(balance)\n      //if no entry consider empty balance\n      else\n        acc.success.push({\n          address: def.address,\n          networkId,\n          tokenId: def.token.id,\n          source: MODULE_TYPE,\n          status: \"live\",\n          values: [\n            { type: \"free\", label: \"free\", amount: \"0\" },\n            { type: \"locked\", label: \"frozen\", amount: \"0\" },\n          ],\n        })\n      return acc\n    },\n    { success: [], errors: [] }\n  )\n}\n","import { type SubTokensToken, subTokensTokenId } from \"@talismn/chaindata-provider\"\nimport { assign } from \"lodash-es\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, PLATFORM, type TokenConfig } from \"./config\"\n\nexport const fetchTokens: IBalanceModule<typeof MODULE_TYPE, TokenConfig>[\"fetchTokens\"] = async ({\n  networkId,\n  tokens,\n  miniMetadata,\n}) => {\n  if (!miniMetadata?.data) return []\n\n  // in this module we do not fetch any token information from the chain\n  // this is because there are basically as many pallet implementations as there are networks (Expect Chaos, they said)\n  // we rely on the config to provide all the info we need\n  return tokens.map(\n    (tokenConfig): SubTokensToken =>\n      assign(\n        {\n          id: subTokensTokenId(networkId, tokenConfig.onChainId),\n          type: MODULE_TYPE,\n          platform: PLATFORM,\n          networkId,\n          onChainId: tokenConfig.onChainId,\n          symbol: tokenConfig.symbol ?? \"Unit\",\n          decimals: tokenConfig.decimals ?? 0,\n          name: tokenConfig.name ?? tokenConfig.symbol ?? \"Unit\",\n          existentialDeposit: tokenConfig.existentialDeposit ?? \"0\",\n          isDefault: true,\n        },\n        tokenConfig\n      )\n  )\n}\n","import { MINIMETADATA_VERSION } from \"@talismn/chaindata-provider\"\nimport { compactMetadata, encodeMetadata, parseMetadataRpc } from \"@talismn/scale\"\n\nimport { deriveMiniMetadataId } from \"../../types\"\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getConstantValue, hasStorageItems } from \"../shared\"\nimport { type MiniMetadataExtra, MODULE_TYPE, type ModuleConfig, type TokenConfig } from \"./config\"\n\nexport const getMiniMetadata: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n>[\"getMiniMetadata\"] = ({ networkId, specVersion, metadataRpc, config }) => {\n  const source = MODULE_TYPE\n  const chainId = networkId\n\n  const systemVersion = getConstantValue<{ spec_version: number }>(metadataRpc, \"System\", \"Version\")\n  if (specVersion !== systemVersion.spec_version)\n    throw new Error(\n      `specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`\n    )\n\n  const id = deriveMiniMetadataId({ source, chainId, specVersion })\n\n  const { unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  if (unifiedMetadata.version < 14)\n    throw new Error(\n      `Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`\n    )\n\n  const extra: MiniMetadataExtra = { palletId: config?.palletId ?? \"Tokens\" }\n\n  return {\n    id,\n    source,\n    chainId,\n    specVersion,\n    version: MINIMETADATA_VERSION,\n    data: getData(metadataRpc, extra.palletId),\n    extra,\n  }\n}\n\nconst getData = (metadataRpc: `0x${string}`, pallet: string): `0x${string}` | null => {\n  const { metadata, unifiedMetadata } = parseMetadataRpc(metadataRpc)\n\n  // ensure the network has all the required bits\n  if (!hasStorageItems(unifiedMetadata, pallet, [\"Accounts\"])) return null\n\n  compactMetadata(metadata, [{ pallet, items: [\"Accounts\"] }])\n\n  return encodeMetadata(metadata)\n}\n","import { Binary, Enum } from \"@polkadot-api/substrate-bindings\"\nimport { mergeUint8 } from \"@polkadot-api/utils\"\nimport { isTokenOfType, type SubTokensToken } from \"@talismn/chaindata-provider\"\nimport { type MetadataBuilder, papiParse, parseMetadataRpc } from \"@talismn/scale\"\n\nimport type { BalanceTransferType, IBalanceModule } from \"../../types/IBalanceModule\"\nimport { MODULE_TYPE, type ModuleConfig, type TokenConfig } from \"./config\"\n\nexport const getTransferCallData: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig\n>[\"getTransferCallData\"] = ({ from, to, value, token, type, metadataRpc, config }) => {\n  if (!isTokenOfType(token, MODULE_TYPE))\n    throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)\n\n  const { builder } = parseMetadataRpc(metadataRpc)\n\n  // each chain has its own way of encoding the transfer call data\n  // let's try our luck until one works!\n  const options = getCallDataOptions(to, token, value, type, config)\n  const callData = getCallDataFromOptions(builder, options)\n\n  return {\n    address: from,\n    method: Binary.toHex(callData) as `0x${string}`,\n  }\n}\n\nconst getTransferMethod = (type: BalanceTransferType) => {\n  switch (type) {\n    case \"keep-alive\":\n      return \"transfer_keep_alive\"\n    case \"all\":\n      return \"transfer_all\"\n    case \"allow-death\":\n      return \"transfer\"\n  }\n}\n\ntype CallDataOption = {\n  pallet: string\n  method: string\n  getArgs: () => unknown\n}\n\nconst getCallDataFromOptions = (\n  builder: MetadataBuilder,\n  options: CallDataOption[]\n): Uint8Array => {\n  for (const { pallet, method, getArgs } of options) {\n    try {\n      return buildCallData(builder, pallet, method, getArgs())\n    } catch {\n      // wrong inputs, ignore and try the next one\n    }\n  }\n  throw new Error(\"Failed to encode call data\")\n}\n\nconst buildCallData = (builder: MetadataBuilder, pallet: string, method: string, args: unknown) => {\n  const { location, codec } = builder.buildCall(pallet, method)\n  return mergeUint8([new Uint8Array(location), codec.enc(args)])\n}\n\nconst getCallDataOptions = (\n  to: string,\n  token: SubTokensToken,\n  value: string,\n  type: BalanceTransferType,\n  config: ModuleConfig | undefined\n): CallDataOption[] => {\n  const onChainId = papiParse(token.onChainId)\n  const method = getTransferMethod(type)\n\n  return [\n    {\n      pallet: \"Currencies\",\n      method: \"transfer\",\n      getArgs: () => ({\n        dest: Enum(\"Id\", to),\n        currency_id: onChainId,\n        amount: BigInt(value),\n      }),\n    },\n    {\n      pallet: \"Currencies\",\n      method: \"transfer\",\n      getArgs: () => ({\n        dest: to,\n        currency_id: onChainId,\n        amount: BigInt(value),\n      }),\n    },\n    {\n      pallet: \"Tokens\",\n      method,\n      getArgs: () =>\n        method === \"transfer_all\"\n          ? {\n              dest: Enum(\"Id\", to),\n              currency_id: onChainId,\n              keepAlive: false,\n            }\n          : {\n              dest: Enum(\"Id\", to),\n              currency_id: onChainId,\n              amount: BigInt(value),\n            },\n    },\n    {\n      pallet: \"Tokens\",\n      method,\n      getArgs: () =>\n        method === \"transfer_all\"\n          ? {\n              dest: to,\n              currency_id: onChainId,\n              keepAlive: false,\n            }\n          : {\n              dest: to,\n              currency_id: onChainId,\n              amount: BigInt(value),\n            },\n    },\n  ].concat(\n    ...(config?.palletId\n      ? [\n          {\n            pallet: config.palletId,\n            method,\n            getArgs: () =>\n              method === \"transfer_all\"\n                ? {\n                    dest: Enum(\"Id\", to),\n                    currency_id: onChainId,\n                    keepAlive: false,\n                  }\n                : {\n                    dest: Enum(\"Id\", to),\n                    currency_id: onChainId,\n                    amount: BigInt(value),\n                  },\n          },\n          {\n            pallet: config.palletId,\n            method,\n            getArgs: () =>\n              method === \"transfer_all\"\n                ? {\n                    dest: to,\n                    currency_id: onChainId,\n                    keepAlive: false,\n                  }\n                : {\n                    dest: to,\n                    currency_id: onChainId,\n                    amount: BigInt(value),\n                  },\n          },\n        ]\n      : [])\n  )\n}\n","import { yieldToEventLoop } from \"@talismn/util\"\nimport { defer, map, of, switchMap } from \"rxjs\"\n\nimport type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport { getBalanceDefs } from \"../shared\"\nimport { getRpcQueryPack$ } from \"../shared/rpcQueryPack\"\nimport { buildQueries } from \"./buildQueries\"\nimport type { MiniMetadataExtra, MODULE_TYPE, ModuleConfig, TokenConfig } from \"./config\"\n\nexport const subscribeBalances: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n>[\"subscribeBalances\"] = ({ networkId, tokensWithAddresses, connector, miniMetadata }) => {\n  if (!tokensWithAddresses.length) return of({ success: [], errors: [] })\n\n  const balanceDefs = getBalanceDefs<typeof MODULE_TYPE>(tokensWithAddresses)\n\n  return defer(async () => {\n    // on a scale-builder cache miss, query building parses/builds the chain metadata\n    // (expensive, indivisible) — give it its own macrotask so it doesn't stack with\n    // the current tick's other work\n    await yieldToEventLoop()\n    return buildQueries(networkId, balanceDefs, miniMetadata)\n  }).pipe(\n    switchMap((queries) => getRpcQueryPack$(connector, networkId, queries)),\n    map((balances) => ({\n      success: balances,\n      errors: [],\n    }))\n  )\n}\n","import type { IBalanceModule } from \"../../types/IBalanceModule\"\nimport {\n  type MiniMetadataExtra,\n  MODULE_TYPE,\n  type ModuleConfig,\n  PLATFORM,\n  type TokenConfig,\n} from \"./config\"\nimport { fetchBalances } from \"./fetchBalances\"\nimport { fetchTokens } from \"./fetchTokens\"\nimport { getMiniMetadata } from \"./getMiniMetadata\"\nimport { getTransferCallData } from \"./getTransferCallData\"\nimport { subscribeBalances } from \"./subscribeBalances\"\n\nexport const SubTokensBalanceModule: IBalanceModule<\n  typeof MODULE_TYPE,\n  TokenConfig,\n  ModuleConfig,\n  MiniMetadataExtra\n> = {\n  type: MODULE_TYPE,\n  platform: PLATFORM,\n  getMiniMetadata,\n  fetchTokens,\n  fetchBalances,\n  subscribeBalances,\n  getTransferCallData,\n}\n","import { SubTokensTokenSchema } from \"@talismn/chaindata-provider\"\nimport z from \"zod/v4\"\n\nimport { TokenConfigBaseSchema } from \"../../types/tokens\"\n\n// to be used by chaindata too\nexport const SubTokensTokenConfigSchema = z.strictObject({\n  onChainId: SubTokensTokenSchema.shape.onChainId,\n  ...TokenConfigBaseSchema.shape,\n\n  // force these 3 fields because in this module we wont pull anything from chain\n  symbol: z.string().nonempty(),\n  decimals: z.number(),\n  existentialDeposit: z.string().nonempty(),\n})\n\n// Do not use this type outside of this module\nexport type SubTokensTokenConfig = z.infer<typeof SubTokensTokenConfigSchema>\n\nexport const SubTokensModuleConfigSchema = z.strictObject({\n  palletId: z.string().optional(),\n})\n\n// Do not use this type outside of this module\nexport type SubTokensModuleConfig = z.infer<typeof SubTokensModuleConfigSchema>\n\nexport const SubTokensMiniMetadataExtraSchema = z.strictObject({\n  palletId: z.string(),\n})\n\nexport type SubTokensMiniMetadataExtra = z.infer<typeof SubTokensMiniMetadataExtraSchema>\n","import { EvmErc20BalanceModule } from \"./evm-erc20\"\nimport { EvmNativeBalanceModule } from \"./evm-native\"\nimport { EvmUniswapV2BalanceModule } from \"./evm-uniswapv2\"\nimport { SolNativeBalanceModule } from \"./sol-native\"\nimport { SolSplBalanceModule } from \"./sol-spl\"\nimport { SolToken2022BalanceModule } from \"./sol-token2022\"\nimport { SubAssetsBalanceModule } from \"./substrate-assets\"\nimport { SubDTaoBalanceModule } from \"./substrate-dtao\"\nimport { SubForeignAssetsBalanceModule } from \"./substrate-foreignassets\"\nimport { SubHydrationBalanceModule } from \"./substrate-hydration\"\nimport { SubNativeBalanceModule } from \"./substrate-native\"\nimport { SubPsp22BalanceModule } from \"./substrate-psp22\"\nimport { SubTokensBalanceModule } from \"./substrate-tokens\"\n\nexport const BALANCE_MODULES = [\n  SubNativeBalanceModule,\n  SubAssetsBalanceModule,\n  SubDTaoBalanceModule,\n  SubHydrationBalanceModule,\n  SubForeignAssetsBalanceModule,\n  SubPsp22BalanceModule,\n  SubTokensBalanceModule,\n  EvmErc20BalanceModule,\n  EvmUniswapV2BalanceModule,\n  EvmNativeBalanceModule,\n  SolNativeBalanceModule,\n  SolSplBalanceModule,\n  SolToken2022BalanceModule,\n]\n\nexport type AnyBalanceModule = (typeof BALANCE_MODULES)[number] // TODO yeet ? should use IBalance\n\nexport * from \"../types/IBalanceModule\"\nexport * from \"./abis\"\nexport * from \"./evm-erc20\"\nexport * from \"./evm-native\"\nexport * from \"./evm-uniswapv2\"\nexport * from \"./sol-native\"\nexport * from \"./sol-spl\"\nexport * from \"./sol-token2022\"\nexport * from \"./substrate-assets\"\nexport * from \"./substrate-dtao\"\nexport * from \"./substrate-foreignassets\"\nexport * from \"./substrate-hydration\"\nexport * from \"./substrate-native\"\nexport * from \"./substrate-psp22\"\nexport * from \"./substrate-tokens\"\n","import type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport type { DotNetworkId } from \"@talismn/chaindata-provider\"\nimport { fetchBestMetadata } from \"@talismn/sapi\"\nimport { isAbortError } from \"@talismn/util\"\n\n// share requests as all modules will call this at once\nconst CACHE = new Map<string, Promise<`0x${string}`>>()\n\nexport const getMetadataRpc = async (\n  chainConnector: IChainConnectorDot,\n  networkId: DotNetworkId\n) => {\n  if (CACHE.has(networkId)) return CACHE.get(networkId)!\n\n  const pResult = fetchBestMetadata(\n    (method, params, isCacheable) =>\n      chainConnector.send(networkId, method, params, isCacheable, { expectErrors: true }),\n    // do not allow fallback to v14 unless unavailable.\n    // substrate-native and substrate-hydration need v15 metadata for runtime api calls\n    false\n  )\n\n  CACHE.set(networkId, pResult)\n\n  try {\n    return await pResult\n  } catch (cause) {\n    if (isAbortError(cause)) throw cause\n    throw new Error(`Failed to fetch metadataRpc for network ${networkId}`, { cause })\n  } finally {\n    CACHE.delete(networkId)\n  }\n}\n","import type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport type { DotNetworkId } from \"@talismn/chaindata-provider\"\n\n// cache the promise so it can be shared across multiple calls\nconst CACHE_GET_SPEC_VERSION = new Map<string, Promise<number>>()\n\nconst fetchSpecVersion = async (chainConnector: IChainConnectorDot, networkId: DotNetworkId) => {\n  const { specVersion } = await chainConnector.send<{ specVersion: number }>(\n    networkId,\n    \"state_getRuntimeVersion\",\n    [],\n    true\n  )\n  return specVersion\n}\n\n/**\n * fetches the spec version of a network. current request is cached in case of multiple calls (all balance modules will kick in at once)\n */\nexport const getSpecVersion = async (\n  chainConnector: IChainConnectorDot,\n  networkId: DotNetworkId\n) => {\n  if (CACHE_GET_SPEC_VERSION.has(networkId)) return CACHE_GET_SPEC_VERSION.get(networkId)!\n\n  const pResult = fetchSpecVersion(chainConnector, networkId)\n\n  CACHE_GET_SPEC_VERSION.set(networkId, pResult)\n\n  try {\n    return await pResult\n  } catch (cause) {\n    throw new Error(`Failed to fetch specVersion for network ${networkId}`, { cause })\n  } finally {\n    CACHE_GET_SPEC_VERSION.delete(networkId)\n  }\n}\n","import type { IChainConnectorDot } from \"@talismn/chain-connectors\"\nimport type { ChaindataProvider, DotNetworkId } from \"@talismn/chaindata-provider\"\nimport { reportJsActivity, yieldToEventLoop } from \"@talismn/util\"\nimport PQueue from \"p-queue\"\n\nimport log from \"../log\"\nimport { BALANCE_MODULES } from \"../modules\"\nimport type { MiniMetadata } from \"../types\"\nimport { getMetadataRpc } from \"./getMetadataRpc\"\nimport { getSpecVersion } from \"./getSpecVersion\"\n\nexport { getSpecVersion } from \"./getSpecVersion\"\n\nconst getCacheKey = (networkId: string, specVersion: number) => `${networkId}:${specVersion}`\n\nconst CACHE = new Map<string, Promise<MiniMetadata[]>>()\n\n// ensures we dont fetch miniMetadatas on more than 4 chains at once\nconst POOL = new PQueue({ concurrency: 4 })\n\nexport const getMiniMetadatas = async (\n  chainConnector: IChainConnectorDot,\n  chaindataProvider: ChaindataProvider,\n  networkId: DotNetworkId,\n  specVersion?: number\n) => {\n  if (specVersion === undefined) specVersion = await getSpecVersion(chainConnector, networkId)\n\n  const cacheKey = getCacheKey(networkId, specVersion)\n  if (CACHE.has(cacheKey)) return CACHE.get(cacheKey)!\n\n  const pResult = POOL.add(() =>\n    fetchMiniMetadatas(chainConnector, chaindataProvider, networkId, specVersion)\n  ) as Promise<MiniMetadata[]>\n\n  // keep the results in cache (unless call fails) as observables call this function a lot of times\n  CACHE.set(cacheKey, pResult)\n\n  try {\n    return await pResult\n  } catch (cause) {\n    CACHE.delete(cacheKey)\n    throw new Error(`Failed to fetch metadataRpc for network ${networkId}`, { cause })\n  }\n}\n\nconst fetchMiniMetadatas = async (\n  chainConnector: IChainConnectorDot,\n  chaindataProvider: ChaindataProvider,\n  chainId: DotNetworkId,\n  specVersion: number\n) => {\n  const start = performance.now()\n  log.info(\"[miniMetadata] fetching minimetadatas for %s\", chainId)\n\n  try {\n    const network = await chaindataProvider.getNetworkById(chainId, \"polkadot\")\n    if (!network) throw new Error(`Network ${chainId} not found in chaindataProvider`)\n\n    const metadataRpc = await getMetadataRpc(chainConnector, chainId)\n\n    // sequential with yields, NOT Promise.all: each module's build does a full\n    // parse+compact+encode of the metadata — synchronous and potentially seconds each on\n    // large chains. Promise.all starts them all in one tick, fusing the builds into a\n    // single 10s+ JS-thread block. The work is CPU-bound, so sequencing costs no\n    // wall-clock time; the yields let the app respond between builds.\n    const miniMetadatas: MiniMetadata[] = []\n    for (const mod of BALANCE_MODULES.filter((m) => m.platform === \"polkadot\")) {\n      const buildStart = performance.now()\n      miniMetadatas.push(\n        await mod.getMiniMetadata({\n          networkId: chainId,\n          metadataRpc,\n          specVersion,\n          config: network.balancesConfig?.[mod.type],\n        })\n      )\n      reportJsActivity(`getMiniMetadata ${mod.type} ${chainId}`, performance.now() - buildStart)\n      await yieldToEventLoop()\n    }\n    return miniMetadatas\n  } finally {\n    // end-of-work marker (no duration: the span includes async fetch time; the heavy\n    // sync parse is reported separately by parseMetadataRpcCached) — lets host stall\n    // watchdogs place miniMetadata builds inside a stall window\n    reportJsActivity(`getMiniMetadatas ${chainId}`)\n    log.debug(\n      \"[miniMetadata] updated miniMetadatas for %s in %sms\",\n      chainId,\n      (performance.now() - start).toFixed(2)\n    )\n  }\n}\n","import {\n  type AnyMiniMetadata,\n  type ChaindataProvider,\n  type DotNetworkId,\n  isNetworkDot,\n  type Network,\n  type NetworkId,\n  parseTokenId,\n  type Token,\n  type TokenId,\n} from \"@talismn/chaindata-provider\"\nimport {\n  type AccountPlatform,\n  getAccountPlatformFromAddress,\n  normalizeAddress,\n} from \"@talismn/crypto\"\nimport {\n  getSharedObservable,\n  isNotNil,\n  isTruthy,\n  keepAlive,\n  mapWithYield,\n  reportJsActivity,\n  switchMapChunked,\n  type TimeSlicer,\n} from \"@talismn/util\"\nimport { assign, fromPairs, isEqual, keyBy, keys, toPairs, uniq, values } from \"lodash-es\"\nimport {\n  auditTime,\n  catchError,\n  combineLatest,\n  defer,\n  distinctUntilChanged,\n  EMPTY,\n  filter,\n  firstValueFrom,\n  from,\n  map,\n  type Observable,\n  of,\n  ReplaySubject,\n  shareReplay,\n  startWith,\n  switchMap,\n  tap,\n  timer,\n} from \"rxjs\"\nimport { withRetry } from \"viem\"\n\nimport { BALANCE_MODULES, type ChainConnectors, findDTaoConvictionLock } from \".\"\nimport { getMiniMetadatas, getSpecVersion } from \"./getMiniMetadatas\"\nimport log from \"./log\"\nimport { getDetectedTokensIds$ } from \"./modules/shared/detectedTokens\"\nimport {\n  classifySmallAmountDrift,\n  stabilizeModuleResults,\n} from \"./modules/shared/stabilizeBalances\"\nimport {\n  type Address,\n  deriveMiniMetadataId,\n  getBalanceId,\n  getBalanceStorageFingerprint,\n  getRawLocks,\n  getRawTotalPlanck,\n  type IBalance,\n  isEqualBalancesResult,\n  isEqualMiniMetadatas,\n  type MiniMetadata,\n} from \"./types\"\nimport type { TokensWithAddresses } from \"./types/IBalanceModule\"\n\ntype BalancesStatus = \"initialising\" | \"live\"\n\n/**\n * Cross-module drift tolerance (see classifySmallAmountDrift): amounts moving by no more\n * than this classify as drift and re-emit at most once per stabilizer refresh interval.\n * Kept tight — a real incoming transfer above 0.1% of the position emits immediately.\n */\nconst GENERIC_DRIFT_TOLERANCE_BPS = 10n\n\nexport type BalancesResult = {\n  status: BalancesStatus\n  balances: IBalance[]\n  failedBalanceIds: string[] // balance ids that failed to fetch\n}\n\nexport type BalancesStorage = {\n  balances: IBalance[]\n  miniMetadatas: MiniMetadata[]\n}\n\ntype ProviderBalancesStorage = {\n  balances: Record<string, IBalance>\n  miniMetadatas: Record<string, MiniMetadata>\n}\n\nconst DEFAULT_STORAGE: BalancesStorage = {\n  balances: [],\n  miniMetadatas: [],\n}\n\nexport class BalancesProvider {\n  #chaindataProvider: ChaindataProvider\n  #chainConnectors: ChainConnectors\n  #storage: ReplaySubject<ProviderBalancesStorage>\n  #storageValue: ProviderBalancesStorage\n  #storage$: Observable<BalancesStorage>\n  // balance ids whose most recent module emission was live, by confirmation time. Stored\n  // content always mirrors the last live emission (see updateStorage$), so on a pipeline\n  // restart the seed can re-emit recently-confirmed entries with their \"live\" status\n  // intact instead of downgrading the whole snapshot to \"cache\" and flipping it back\n  // once modules reconnect\n  #lastLiveAt = new Map<string, number>()\n\n  constructor(\n    chaindataProvider: ChaindataProvider,\n    chainConnectors: ChainConnectors,\n    storage: BalancesStorage = DEFAULT_STORAGE\n  ) {\n    this.#chaindataProvider = chaindataProvider\n    this.#chainConnectors = chainConnectors\n    this.#storageValue = {\n      balances: keyBy(storage.balances.filter(isNotNil), (b) => getBalanceId(b)),\n      miniMetadatas: keyBy(storage.miniMetadatas.filter(isNotNil), (m) => m.id),\n    }\n    this.#storage = new ReplaySubject<ProviderBalancesStorage>(1)\n    this.#storage.next(this.#storageValue)\n    // built once so the sort/projection is shared by all subscribers (a previous version\n    // passed shareReplay as a 2nd argument to map, which made it inert — every subscriber\n    // re-ran the sort on every emission)\n    this.#storage$ = this.#storage.pipe(\n      map(\n        ({ balances, miniMetadatas }): BalancesStorage => ({\n          balances: values(balances).filter(isNotNil).sort(sortByBalanceId),\n          miniMetadatas: values(miniMetadatas).filter(isNotNil).sort(sortByMiniMetadataId),\n        })\n      ),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n  }\n\n  get storage$() {\n    return this.#storage$\n  }\n\n  #nextStorage(value: ProviderBalancesStorage) {\n    this.#storageValue = value\n    this.#storage.next(value)\n  }\n\n  private get storedMiniMetadataMapById$() {\n    return this.#storage.pipe(\n      // storage.miniMetadatas is already keyed by id, and its object reference is only\n      // replaced when miniMetadatas are actually written (see getMiniMetadatas$ tap) —\n      // so a reference compare replaces the old keyBy + deep isEqual on every emission\n      map((storage) => storage.miniMetadatas),\n      distinctUntilChanged(),\n      shareReplay(1)\n    )\n  }\n\n  // this is the only public method\n  public getBalances$(addressesByTokenId: Record<TokenId, Address[]>): Observable<BalancesResult> {\n    return this.cleanupAddressesByTokenId$(addressesByTokenId).pipe(\n      map(\n        // split by network\n        (addressesByTokenId): Record<NetworkId, Record<TokenId, Address[]>> =>\n          toPairs(addressesByTokenId).reduce(\n            (acc, [tokenId, addresses]) => {\n              const networkId = parseTokenId(tokenId).networkId\n              if (!acc[networkId]) acc[networkId] = {}\n              acc[networkId][tokenId] = addresses\n              return acc\n            },\n            {} as Record<NetworkId, Record<TokenId, Address[]>>\n          )\n      ),\n      switchMap((addressesByTokenIdByNetworkId) => {\n        // after cleanup we might end up without entries to fetch, which would break the combineLatest below\n        if (!keys(addressesByTokenIdByNetworkId).length) return of({ isStale: false, results: [] })\n\n        // fetch balances and start a 30s timer to mark the whole subscription live after 30s\n        return combineLatest({\n          isStale: timer(30_000).pipe(\n            map(() => true),\n            startWith(false)\n          ),\n          results: combineLatest(\n            toPairs(addressesByTokenIdByNetworkId).map(([networkId]) =>\n              this.getNetworkBalances$(networkId, addressesByTokenIdByNetworkId[networkId])\n            )\n          ).pipe(\n            // each network is an independent emission train (per-block for substrate\n            // subscriptions, 6s polls for the rest): coalesce near-simultaneous network\n            // emissions so the aggregation below runs at most once per window instead of\n            // once per network (matters most during the startup storm)\n            auditTime(100)\n          ),\n        })\n      }),\n      // aggregation is time-sliced: yields the JS thread on budget, and a newer emission\n      // aborts the in-flight pass (latest-wins)\n      switchMapChunked(\n        async ({ isStale, results }, { slicer }): Promise<BalancesResult> => {\n          const balanceArrays = await mapWithYield(\n            results,\n            (result) => (isStale ? result.balances.map(getSweepStaleVariant) : result.balances),\n            { slicer }\n          )\n\n          return {\n            status:\n              !isStale && results.some(({ status }) => status === \"initialising\")\n                ? \"initialising\"\n                : \"live\",\n            // per-network arrays are already sorted (see getNetworkBalances$): merge instead\n            // of re-sorting the whole set\n            balances: await mergeSortedBalanceArrays(balanceArrays, slicer),\n            failedBalanceIds: results.flatMap((result) => result.failedBalanceIds),\n          }\n        },\n        { label: \"balances aggregate\" }\n      ),\n      distinctUntilChanged(isEqualBalancesResult)\n    )\n  }\n\n  public fetchBalances(addressesByTokenId: Record<TokenId, Address[]>): Promise<IBalance[]> {\n    return firstValueFrom(\n      this.getBalances$(addressesByTokenId).pipe(\n        filter(({ status }) => status === \"live\"),\n        map(({ balances }) => balances)\n      )\n    )\n  }\n\n  public getDetectedTokensId$(address: string): Observable<TokenId[]> {\n    return getDetectedTokensIds$(address)\n  }\n\n  private getNetworkBalances$(\n    networkId: string,\n    addressesByTokenId: Record<TokenId, Address[]>\n  ): Observable<BalancesResult> {\n    const network$ = this.#chaindataProvider.getNetworkById$(networkId)\n    const tokensMapById$ = this.#chaindataProvider.getTokensMapById$()\n\n    return combineLatest([network$, tokensMapById$]).pipe(\n      // only re-subscribe the module pipelines below when THIS network or the tokens THIS\n      // pipeline uses actually change — chaindata emissions for unrelated networks/tokens\n      // must not tear down live balance subscriptions. Relies on chaindata-provider's\n      // per-item reference stability (combinedChaindata section stabilizer).\n      map(([network, tokensMapById]) => ({\n        network,\n        // keys(addressesByTokenId) and toPairs(addressesByTokenId) enumerate in the same\n        // order, so indexing tokens by position below is safe\n        tokens: keys(addressesByTokenId).map((tokenId) => tokensMapById[tokenId]),\n      })),\n      distinctUntilChanged(\n        (a, b) => a.network === b.network && a.tokens.every((token, i) => token === b.tokens[i])\n      ),\n      switchMap(({ network, tokens }) => {\n        const tokensAndAddresses: TokensWithAddresses = toPairs(addressesByTokenId).map(\n          ([, addresses], i) => [tokens[i], addresses] as [Token, Address[]]\n        )\n\n        return combineLatest(\n          BALANCE_MODULES.filter((mod) => mod.platform === network?.platform).map((mod) => {\n            const tokensWithAddresses = tokensAndAddresses.filter(\n              // token is undefined when the request map references a tokenId missing\n              // from chaindata (e.g. a custom or dynamic token this provider doesn't\n              // know) — skip those instead of throwing and killing the whole stream\n              ([token]) => token?.type === mod.type\n            )\n\n            switch (mod.platform) {\n              case \"ethereum\": {\n                return this.getEthereumNetworkModuleBalances$(networkId, tokensWithAddresses, mod)\n              }\n              case \"solana\": {\n                return this.getSolanaNetworkModuleBalances$(networkId, tokensWithAddresses, mod)\n              }\n              case \"polkadot\": {\n                return this.getPolkadotNetworkModuleBalances$(networkId, tokensWithAddresses, mod)\n              }\n              default: {\n                log.warn(\"[balances] Unsupported network platform for module\", { networkId, mod })\n                return of<BalancesResult>({ status: \"live\", balances: [], failedBalanceIds: [] })\n              }\n            }\n          })\n        )\n      }),\n      switchMapChunked(\n        async (results, { slicer }): Promise<BalancesResult> => {\n          // for each balance that could not be fetched, see if we have a stored balance and return it, marked as stale\n          const errorBalanceIds = results.flatMap((result) => result.failedBalanceIds)\n          const staleBalances = errorBalanceIds\n            .map((balanceId) => this.#storageValue.balances[balanceId])\n            .filter(isNotNil)\n            .map(getStaleVariant)\n\n          const balances = results.flatMap((result) => result.balances).concat(staleBalances)\n\n          // yield before the (atomic) sort so it starts on a fresh slice; per-network result\n          // sets are small enough that the sort itself stays within a frame\n          const yielded = slicer.yieldIfNeeded()\n          if (yielded) await yielded\n\n          return {\n            status: results.some(({ status }) => status === \"initialising\")\n              ? \"initialising\"\n              : \"live\",\n            balances: balances.sort(sortByBalanceId),\n            failedBalanceIds: [],\n          }\n        },\n        { label: `network balances ${networkId}` }\n      ),\n      distinctUntilChanged(isEqualBalancesResult)\n    )\n  }\n\n  private getPolkadotNetworkModuleBalances$(\n    networkId: DotNetworkId,\n    tokensWithAddresses: TokensWithAddresses,\n    mod: Extract<(typeof BALANCE_MODULES)[number], { platform: \"polkadot\" }>\n  ): Observable<BalancesResult> {\n    return getSharedObservable(\n      `BalancesProvider.getPolkadotNetworkModuleBalances$`,\n      { networkId, mod, tokensWithAddresses },\n      () => {\n        if (!tokensWithAddresses.length)\n          return of<BalancesResult>({ status: \"live\", balances: [], failedBalanceIds: [] })\n\n        const moduleAddressesByTokenId = fromPairs(\n          tokensWithAddresses.map(([token, addresses]) => [token.id, addresses])\n        )\n\n        // all balance ids expected in result set\n        const balanceIds = toPairs(moduleAddressesByTokenId).flatMap(([tokenId, addresses]) =>\n          addresses.map((address) => getBalanceId({ tokenId, address }))\n        )\n\n        if (!this.#chainConnectors.substrate) {\n          log.warn(\"[balances] no substrate connector or miniMetadata for module\", mod.type)\n          return defer(() =>\n            of<BalancesResult>({\n              status: \"initialising\",\n              balances: this.getStoredBalances(moduleAddressesByTokenId),\n              failedBalanceIds: [],\n            })\n          )\n        }\n\n        const moduleBalances$ = this.getNetworkMiniMetadatas$(networkId).pipe(\n          map((miniMetadatas) => miniMetadatas.find((m) => m.source === mod.type)),\n          switchMap((miniMetadata) =>\n            mod.subscribeBalances({\n              networkId,\n              tokensWithAddresses,\n              connector: this.#chainConnectors.substrate!,\n              miniMetadata: miniMetadata as AnyMiniMetadata,\n            })\n          ),\n          // keep unchanged balances reference-stable across emissions (module decode\n          // allocates all-new objects every block), so downstream fingerprint caches and\n          // per-item === compares hit instead of re-serializing the whole result set.\n          // dtao ships its own drift classifier (inside its subscribeBalances); everyone\n          // else gets the generic small-amount-drift classifier so continuously-moving\n          // positions (LP shares, yield-bearing tokens) can't re-emit on every poll\n          stabilizeModuleResults(\n            mod.type === \"substrate-dtao\"\n              ? undefined\n              : classifySmallAmountDrift(GENERIC_DRIFT_TOLERANCE_BPS)\n          ),\n          catchError(() => EMPTY), // don't emit, let provider mark balances stale\n          tap((results) => {\n            // marks which module's poll/subscription just produced results, so JS-thread\n            // stall reports can attribute blocked windows to the right pipeline\n            reportJsActivity(`module ${mod.type} ${networkId} (${results.success.length})`)\n\n            if (results.dynamicTokens?.length) {\n              // register missing tokens in the chaindata provider\n              this.#chaindataProvider.registerDynamicTokens(results.dynamicTokens)\n            }\n          }),\n          map(\n            (results): BalancesResult => ({\n              status: \"live\",\n              // exclude zero balances, but keep balances that only hold a lock\n              // (eg dtao conviction locks, reported on the subnet's base token — including\n              // zero-mass \"ghost\" locks with residual conviction, which still pin the hotkey\n              // of future lock_stake calls)\n              // raw helpers instead of new Balance(b): this filter runs per result per\n              // block, and Balance.total allocates several BalanceFormatters per access\n              balances: results.success.filter((b) => {\n                const rawLocks = getRawLocks(b)\n                return (\n                  getRawTotalPlanck(b) > 0n ||\n                  rawLocks.some((lock) => BigInt(lock.amount) > 0n) ||\n                  !!findDTaoConvictionLock(\n                    rawLocks.map((lock) => ({\n                      amount: { planck: BigInt(lock.amount) },\n                      meta: lock.meta,\n                    }))\n                  )\n                )\n              }),\n              failedBalanceIds: results.errors.map(({ tokenId, address }) =>\n                getBalanceId({ tokenId, address })\n              ),\n            })\n          ),\n          tap((results) => {\n            this.updateStorage$(balanceIds, results)\n          }),\n          // shareReplay + keepAlive(0) keep the subscription alive while root observable is being unsubscribed+resubscribed, in case any input change\n          shareReplay({ refCount: true, bufferSize: 1 }),\n          keepAlive(0)\n        )\n\n        // defer the startWith call to start with up to date balances each time the observable is re-subscribed to\n        return defer(() =>\n          moduleBalances$.pipe(\n            startWith<BalancesResult>({\n              status: \"initialising\",\n              balances: this.getStoredBalances(moduleAddressesByTokenId),\n              failedBalanceIds: [],\n            })\n          )\n        )\n      }\n    )\n  }\n\n  private getEthereumNetworkModuleBalances$(\n    networkId: DotNetworkId,\n    tokensWithAddresses: TokensWithAddresses,\n    mod: Extract<(typeof BALANCE_MODULES)[number], { platform: \"ethereum\" }>\n  ): Observable<BalancesResult> {\n    return getSharedObservable(\n      `BalancesProvider.getEthereumNetworkModuleBalances$`,\n      { networkId, mod, tokensWithAddresses },\n      () => {\n        if (!tokensWithAddresses.length)\n          return of<BalancesResult>({ status: \"live\", balances: [], failedBalanceIds: [] })\n\n        const moduleAddressesByTokenId = fromPairs(\n          tokensWithAddresses.map(([token, addresses]) => [token.id, addresses])\n        )\n\n        // all balance ids expected in result set\n        const balanceIds = toPairs(moduleAddressesByTokenId).flatMap(([tokenId, addresses]) =>\n          addresses.map((address) => getBalanceId({ tokenId, address }))\n        )\n\n        if (!this.#chainConnectors.evm) {\n          log.warn(\"[balances] no ethereum connector for module\", mod.type)\n          return defer(() =>\n            of<BalancesResult>({\n              status: \"initialising\",\n              balances: this.getStoredBalances(moduleAddressesByTokenId),\n              failedBalanceIds: [],\n            })\n          )\n        }\n\n        const moduleBalances$ = mod\n          .subscribeBalances({\n            networkId,\n            tokensWithAddresses,\n            connector: this.#chainConnectors.evm,\n          })\n          .pipe(\n            tap((results) =>\n              reportJsActivity(`module ${mod.type} ${networkId} (${results.success.length})`)\n            ),\n            // keep unchanged balances reference-stable across poll emissions (see the\n            // polkadot pipeline for rationale)\n            stabilizeModuleResults(classifySmallAmountDrift(GENERIC_DRIFT_TOLERANCE_BPS)),\n            catchError(() => EMPTY), // don't emit, let provider mark balances stale\n            map(\n              (results): BalancesResult => ({\n                status: \"live\",\n                // exclude zero balances\n                balances: results.success.filter((b) => getRawTotalPlanck(b) > 0n),\n                failedBalanceIds: results.errors.map(({ tokenId, address }) =>\n                  getBalanceId({ tokenId, address })\n                ),\n              })\n            ),\n            tap((results) => {\n              this.updateStorage$(balanceIds, results)\n            }),\n            // shareReplay + keepAlive(0) keep the subscription alive while root observable is being unsubscribed+resubscribed, in case any input change\n            shareReplay({ refCount: true, bufferSize: 1 }),\n            keepAlive(0)\n          )\n\n        // defer the startWith call to start with up to date balances each time the observable is re-subscribed to\n        return defer(() =>\n          moduleBalances$.pipe(\n            startWith<BalancesResult>({\n              status: \"initialising\",\n              balances: this.getStoredBalances(moduleAddressesByTokenId),\n              failedBalanceIds: [],\n            })\n          )\n        )\n      }\n    )\n  }\n\n  private getSolanaNetworkModuleBalances$(\n    networkId: DotNetworkId,\n    tokensWithAddresses: TokensWithAddresses,\n    mod: Extract<(typeof BALANCE_MODULES)[number], { platform: \"solana\" }>\n  ): Observable<BalancesResult> {\n    return getSharedObservable(\n      `BalancesProvider.getSolanaNetworkModuleBalances$`,\n      { networkId, mod, tokensWithAddresses },\n      () => {\n        if (!tokensWithAddresses.length)\n          return of<BalancesResult>({ status: \"live\", balances: [], failedBalanceIds: [] })\n\n        const moduleAddressesByTokenId = fromPairs(\n          tokensWithAddresses.map(([token, addresses]) => [token.id, addresses])\n        )\n\n        // all balance ids expected in result set\n        const balanceIds = toPairs(moduleAddressesByTokenId).flatMap(([tokenId, addresses]) =>\n          addresses.map((address) => getBalanceId({ tokenId, address }))\n        )\n\n        if (!this.#chainConnectors.solana) {\n          log.warn(\"[balances] no solana connector for module\", mod.type)\n          return defer(() =>\n            of<BalancesResult>({\n              status: \"initialising\",\n              balances: this.getStoredBalances(moduleAddressesByTokenId),\n              failedBalanceIds: [],\n            })\n          )\n        }\n\n        const moduleBalances$ = mod\n          .subscribeBalances({\n            networkId,\n            tokensWithAddresses,\n            connector: this.#chainConnectors.solana,\n          })\n          .pipe(\n            tap((results) =>\n              reportJsActivity(`module ${mod.type} ${networkId} (${results.success.length})`)\n            ),\n            // keep unchanged balances reference-stable across poll emissions (see the\n            // polkadot pipeline for rationale)\n            stabilizeModuleResults(classifySmallAmountDrift(GENERIC_DRIFT_TOLERANCE_BPS)),\n            catchError(() => EMPTY), // don't emit, let provider mark balances stale\n            tap((results) => {\n              if (results.dynamicTokens?.length) {\n                // register missing tokens in the chaindata provider\n                this.#chaindataProvider.registerDynamicTokens(results.dynamicTokens)\n              }\n            }),\n            map(\n              (results): BalancesResult => ({\n                status: \"live\",\n                // exclude zero balances\n                balances: results.success.filter((b) => getRawTotalPlanck(b) > 0n),\n                failedBalanceIds: results.errors.map(({ tokenId, address }) =>\n                  getBalanceId({ tokenId, address })\n                ),\n              })\n            ),\n            tap((results) => {\n              this.updateStorage$(balanceIds, results)\n            }),\n            // shareReplay + keepAlive(0) keep the subscription alive while root observable is being unsubscribed+resubscribed, in case any input change\n            shareReplay({ refCount: true, bufferSize: 1 }),\n            keepAlive(0)\n          )\n\n        // defer the startWith call to start with up to date balances each time the observable is re-subscribed to\n        return defer(() =>\n          moduleBalances$.pipe(\n            startWith<BalancesResult>({\n              status: \"initialising\",\n              balances: this.getStoredBalances(moduleAddressesByTokenId),\n              failedBalanceIds: [],\n            })\n          )\n        )\n      }\n    )\n  }\n\n  private updateStorage$(balanceIds: string[], balancesResult: BalancesResult) {\n    if (balancesResult.status !== \"live\") return\n\n    const storage = this.#storageValue\n    const failedIds = new Set(balancesResult.failedBalanceIds)\n    const incomingById = new Map(\n      balancesResult.balances.map((b) => [getBalanceIdCached(b), b] as const)\n    )\n\n    // live-status bookkeeping runs before (and regardless of) the no-op detection: a\n    // content-identical emission still confirms these balances as live\n    const now = Date.now()\n    for (const balanceId of incomingById.keys()) this.#lastLiveAt.set(balanceId, now)\n    for (const balanceId of balanceIds) {\n      if (!incomingById.has(balanceId) && !failedIds.has(balanceId))\n        this.#lastLiveAt.delete(balanceId)\n    }\n    for (const balanceId of failedIds) this.#lastLiveAt.delete(balanceId)\n\n    // no-op detection: on quiet blocks nothing changed — skip the merge, the storage$\n    // re-projection/sort and the host's downstream persistence entirely.\n    // fingerprints are status-agnostic (stored entries carry \"cache\", results \"live\"),\n    // so status transitions are checked separately.\n    let changed = false\n    for (const [balanceId, balance] of incomingById) {\n      const stored = storage.balances[balanceId]\n      if (\n        stored?.status !== \"cache\" || // missing, or e.g. a stale entry recovering\n        getBalanceStorageFingerprint(stored) !== getBalanceStorageFingerprint(balance)\n      ) {\n        changed = true\n        break\n      }\n    }\n    if (!changed) {\n      // balances expected in the result set but absent (and not failed) mean they are now\n      // empty and must be removed\n      for (const balanceId of balanceIds) {\n        if (failedIds.has(balanceId) || incomingById.has(balanceId)) continue\n        if (storage.balances[balanceId]) {\n          changed = true\n          break\n        }\n      }\n    }\n    if (!changed) {\n      // failed balances transition to stale\n      for (const errorBalanceId of balancesResult.failedBalanceIds) {\n        const stored = storage.balances[errorBalanceId]\n        if (stored && stored.status !== \"stale\") {\n          changed = true\n          break\n        }\n      }\n    }\n    if (!changed) return\n\n    const balances = { ...storage.balances }\n    // delete all balances expected in the result set (except the ones that failed). because if they are not present it means they are empty.\n    for (const balanceId of balanceIds) {\n      if (!failedIds.has(balanceId) && !incomingById.has(balanceId)) delete balances[balanceId]\n    }\n    // storage balances must have status \"cache\", because they are used as start value when initialising subsequent subscriptions\n    for (const [balanceId, balance] of incomingById) {\n      balances[balanceId] = { ...balance, status: \"cache\" } as IBalance\n    }\n\n    // update status of stale balances (copy, don't mutate: stored objects may be shared\n    // with previous storage snapshots and with the fingerprint caches)\n    for (const errorBalanceId of balancesResult.failedBalanceIds) {\n      const balance = balances[errorBalanceId]\n      if (balance && balance.status !== \"stale\")\n        balances[errorBalanceId] = { ...balance, status: \"stale\" } as IBalance\n    }\n\n    this.#nextStorage({ ...storage, balances })\n  }\n\n  private getNetworkMiniMetadatas$(networkId: NetworkId): Observable<MiniMetadata[]> {\n    return getSharedObservable(`BalancesProvider.getNetworkMiniMetadatas$`, { networkId }, () => {\n      return this.#chaindataProvider.getNetworkById$(networkId).pipe(\n        switchMap((network) =>\n          isNetworkDot(network)\n            ? this.getNetworkSpecVersion$(networkId).pipe(\n                switchMap((specVersion) =>\n                  specVersion === null ? of([]) : this.getMiniMetadatas$(networkId, specVersion)\n                )\n              )\n            : of([])\n        ),\n        distinctUntilChanged<MiniMetadata[]>(isEqualMiniMetadatas)\n      )\n    })\n  }\n\n  private getNetworkSpecVersion$(networkId: NetworkId): Observable<number | null> {\n    return from(\n      withRetry(() => getSpecVersion(this.#chainConnectors.substrate!, networkId), {\n        delay: 2_000,\n        shouldRetry: (err) => {\n          log.warn(\"Failed to fetch spec version for network, retrying...\", networkId, err)\n          return true // don't give up mate!\n        },\n      })\n    ).pipe(\n      catchError(() => {\n        log.warn(\"Failed to fetch spec version for network\", networkId)\n        return of(null as number | null)\n      })\n    )\n  }\n\n  private getMiniMetadatas$(\n    networkId: DotNetworkId,\n    specVersion: number\n  ): Observable<MiniMetadata[]> {\n    const miniMetadataIds = BALANCE_MODULES.filter((mod) => mod.platform === \"polkadot\").map(\n      (mod) =>\n        deriveMiniMetadataId({\n          chainId: networkId,\n          specVersion,\n          source: mod.type,\n        })\n    )\n\n    return combineLatest({\n      defaultMiniMetadatas: this.getDefaultMiniMetadatas$(miniMetadataIds),\n      storedMiniMetadatas: this.getStoredMiniMetadatas$(miniMetadataIds),\n    }).pipe(\n      switchMap(({ storedMiniMetadatas, defaultMiniMetadatas }) => {\n        if (defaultMiniMetadatas) return of(defaultMiniMetadatas)\n        if (storedMiniMetadatas) return of(storedMiniMetadatas)\n        if (!this.#chainConnectors.substrate) return of([])\n\n        return from(\n          withRetry(\n            () =>\n              // can fail if metadata cant be fetched\n              getMiniMetadatas(\n                this.#chainConnectors.substrate!,\n                this.#chaindataProvider,\n                networkId,\n                specVersion\n              ),\n            {\n              delay: 2_000,\n              shouldRetry: (err) => {\n                log.warn(\"Failed to fetch minimetadata for %s, retrying...\", networkId, err)\n                return true // don't give up mate!\n              },\n            }\n          )\n        ).pipe(\n          catchError(() => {\n            log.warn(\"Failed to fetch metadata for network\", networkId)\n            return of([])\n          }),\n          // and persist in storage for later reuse\n          tap((newMiniMetadatas) => {\n            if (!newMiniMetadatas.length) return\n            const storage = this.#storageValue\n            const miniMetadatas = assign(\n              // keep minimetadatas of other networks\n              keyBy(\n                values(storage.miniMetadatas).filter((m) => m.chainId !== networkId),\n                (m) => m.id\n              ),\n              // add the ones for our network\n              keyBy(newMiniMetadatas, (m) => m.id)\n            )\n\n            this.#nextStorage(assign({}, storage, { miniMetadatas }))\n          })\n        )\n      }),\n      // emit only when mini metadata changes, as a change here would restart all subscriptions for the network\n      distinctUntilChanged<MiniMetadata[]>(isEqualMiniMetadatas)\n    )\n  }\n\n  private getStoredMiniMetadatas$(miniMetadataIds: string[]): Observable<MiniMetadata[] | null> {\n    return this.storedMiniMetadataMapById$.pipe(\n      map((mapById) => {\n        const miniMetadatas = miniMetadataIds.map((id) => mapById[id])\n        return miniMetadatas.length && miniMetadatas.every(isTruthy) ? miniMetadatas : null\n      }),\n      // source changes very often\n      distinctUntilChanged<MiniMetadata[] | null>(isEqualMiniMetadatas)\n    )\n  }\n\n  private getDefaultMiniMetadatas$(miniMetadataIds: string[]): Observable<MiniMetadata[] | null> {\n    return this.#chaindataProvider.miniMetadatasMapById$.pipe(\n      map((mapById) => {\n        const miniMetadatas = miniMetadataIds.map((id) => mapById[id])\n        return miniMetadatas.length && miniMetadatas.every(isTruthy) ? miniMetadatas : null\n      })\n    )\n  }\n\n  private getStoredBalances(addressesByToken: Record<TokenId, Address[]>) {\n    const balanceDefs = toPairs(addressesByToken).flatMap(([tokenId, addresses]) =>\n      addresses.map((address) => [tokenId, address] as [TokenId, Address])\n    )\n\n    const now = Date.now()\n    return balanceDefs\n      .map(([tokenId, address]) => {\n        const balanceId = getBalanceId({ address, tokenId })\n        const stored = this.#storageValue.balances[balanceId]\n        if (!stored) return stored\n        // balances confirmed live recently enough seed with their exact last live result\n        // — downstream fingerprints match and the UI keeps its Balance instances. Older\n        // confirmations mean the balance's scope left the subscription for a while\n        // (network/token deactivated, account removed, machine slept): that data is\n        // genuinely old, and the cache status with its loading state is the honest signal\n        const lastLiveAt = this.#lastLiveAt.get(balanceId)\n        return lastLiveAt !== undefined && now - lastLiveAt < LIVE_SEED_MAX_AGE_MS\n          ? getLiveVariant(stored)\n          : stored\n      })\n      .filter(isNotNil)\n      .sort(sortByBalanceId) as IBalance[]\n  }\n\n  private cleanupAddressesByTokenId$(addressesByTokenId: Record<TokenId, Address[]>) {\n    return this.#chaindataProvider.getNetworksMapById$().pipe(\n      map((networksById): Record<TokenId, Address[]> => {\n        return fromPairs(\n          toPairs(addressesByTokenId)\n            .map(([tokenId, addresses]) => {\n              const networkId = parseTokenId(tokenId).networkId\n              const network = networksById[networkId]\n              return [\n                tokenId,\n                uniq(addresses.map(normalizeAddress)).filter(\n                  (address) => network && isAddressCompatibleWithNetwork(network, address)\n                ),\n              ] as [TokenId, Address[]]\n            })\n            .filter(([, addresses]) => addresses.length > 0)\n        )\n      }),\n      // the produced record is small (token ids → addresses): a deep compare here\n      // prevents unrelated network-map emissions from re-running the whole getBalances$\n      // switchMap (which would tear down and restart every module subscription)\n      distinctUntilChanged<Record<TokenId, Address[]>>(isEqual)\n    )\n  }\n}\n\nconst isAccountPlatformCompatibleWithNetwork = (network: Network, platform: AccountPlatform) => {\n  switch (network.platform) {\n    case \"ethereum\":\n      return platform === \"ethereum\"\n    case \"solana\":\n      return platform === \"solana\"\n    case \"polkadot\": {\n      switch (network.account) {\n        case \"secp256k1\":\n          return platform === \"ethereum\"\n        case \"*25519\":\n          return platform === \"polkadot\"\n        default:\n          throw new Error(`Unsupported polkadot network account type ${network.account}`)\n      }\n    }\n    default:\n      log.warn(\"Unsupported network platform\", network)\n      throw new Error(\"Unsupported network platform\")\n  }\n}\n\n/**\n * If this is the address of an account, use isAccountCompatibleWithChain instead.\n * Otherwise it could lead to a loss of funds\n * @param chain\n * @param address\n * @returns\n */\nconst isAddressCompatibleWithNetwork = (network: Network, address: string) => {\n  // TODO try with return true to check if wallet filters correctly upfront\n  const accountPlatform = getAccountPlatformFromAddress(address)\n  return isAccountPlatformCompatibleWithNetwork(network, accountPlatform)\n}\n\n// memoized: getBalanceId is called O(n log n) times per sort, on every storage$ emission\nconst balanceIdCache = new WeakMap<IBalance, string>()\nconst getBalanceIdCached = (balance: IBalance): string => {\n  let id = balanceIdCache.get(balance)\n  if (id === undefined) {\n    id = getBalanceId(balance)\n    balanceIdCache.set(balance, id)\n  }\n  return id\n}\n\n// plain string compare instead of localeCompare: ids are ASCII `address::tokenId` and\n// locale collation is ~10x slower (note: sort order differs for non-ASCII ids only)\nconst sortByBalanceId = (a: IBalance, b: IBalance) => {\n  const aId = getBalanceIdCached(a)\n  const bId = getBalanceIdCached(b)\n  return aId < bId ? -1 : aId > bId ? 1 : 0\n}\n\n// memoized `{ ...b, status: \"stale\" }`: stale-marking runs on every aggregation pass\n// while a network is stale/failed, and a fresh copy each pass would break the reference\n// stability that downstream fingerprint caches and === compares rely on\nconst staleVariants = new WeakMap<IBalance, IBalance>()\nconst getStaleVariant = (balance: IBalance): IBalance => {\n  if (balance.status === \"stale\") return balance\n  let variant = staleVariants.get(balance)\n  if (variant === undefined) {\n    variant = { ...balance, status: \"stale\" } as IBalance\n    staleVariants.set(balance, variant)\n  }\n  return variant\n}\n\n// seeds only re-emit \"live\" for balances confirmed live this recently. Connected module\n// subscriptions refresh their timestamps on every emission (~6s polls, per-block\n// substrate), so the window only expires when a balance's scope left the subscription\n// (network/token deactivated, account removed) or the machine slept\nconst LIVE_SEED_MAX_AGE_MS = 5 * 60_000\n\n// memoized `{ ...b, status: \"live\" }`: seeds re-emit on every pipeline restart, and a\n// reference-stable variant lets downstream fingerprint caches and === compares treat\n// repeated seeds of the same stored entry as unchanged\nconst liveVariants = new WeakMap<IBalance, IBalance>()\nconst seededLiveVariants = new WeakSet<IBalance>()\nconst getLiveVariant = (balance: IBalance): IBalance => {\n  if (balance.status === \"live\") return balance\n  let variant = liveVariants.get(balance)\n  if (variant === undefined) {\n    variant = { ...balance, status: \"live\" } as IBalance\n    liveVariants.set(balance, variant)\n    seededLiveVariants.add(variant)\n  }\n  return variant\n}\n\n// the periodic stale sweep must also downgrade seeded live variants: their status is\n// inherited from before a restart, not confirmed by a module emission on the current\n// subscription — a module that never re-emits (dead RPC) would otherwise leave seed\n// content labelled live forever. Exported for tests\nexport const getSweepStaleVariant = (balance: IBalance): IBalance =>\n  balance.status !== \"live\" || seededLiveVariants.has(balance) ? getStaleVariant(balance) : balance\n\nconst mergeTwoSortedBalanceArrays = async (\n  a: IBalance[],\n  b: IBalance[],\n  slicer: TimeSlicer\n): Promise<IBalance[]> => {\n  if (!a.length) return b\n  if (!b.length) return a\n\n  const merged: IBalance[] = new Array(a.length + b.length)\n  let i = 0\n  let j = 0\n  let k = 0\n  while (i < a.length && j < b.length) {\n    const yielded = slicer.yieldIfNeeded()\n    if (yielded) await yielded\n    merged[k++] = sortByBalanceId(a[i], b[j]) <= 0 ? a[i++] : b[j++]\n  }\n  while (i < a.length) merged[k++] = a[i++]\n  while (j < b.length) merged[k++] = b[j++]\n  return merged\n}\n\n/**\n * K-way merge of per-network arrays that are each already sorted by balance id —\n * O(N log K) instead of the O(N log N) full re-sort, and it yields the JS thread on\n * budget (Array.prototype.sort is atomic and cannot).\n */\nconst mergeSortedBalanceArrays = async (\n  arrays: IBalance[][],\n  slicer: TimeSlicer\n): Promise<IBalance[]> => {\n  if (!arrays.length) return []\n\n  let round = arrays\n  while (round.length > 1) {\n    const next: IBalance[][] = []\n    for (let i = 0; i < round.length; i += 2) {\n      next.push(\n        i + 1 < round.length\n          ? await mergeTwoSortedBalanceArrays(round[i], round[i + 1], slicer)\n          : round[i]\n      )\n    }\n    round = next\n  }\n  return round[0]\n}\n\nconst sortByMiniMetadataId = (a: MiniMetadata, b: MiniMetadata) =>\n  a.id < b.id ? -1 : a.id > b.id ? 1 : 0\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAOA,UAAU,IAAI,EAAE,QAAQ,MAAM,CAAC;AAE/B,IAAA,6BAAe;;;AELf,IAAA,cAAe,UAAUA,mBAAgB;;;ACFzC,MAAaC,iBAAc,oBAAoB,MAAM,KAAK;AAC1D,MAAaC,cAAW,oBAAoB,MAAM,SAAS;;;ACD3D,MAAa,6BAA6B,SAAS,CACjD,yDACA,+FACF,CAAU;;;ACHV,MAAa,eAAe,SAAS;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAU;;;ACvBV,MAAa,mBAAmB;CAC9B;EACE,WAAW;EACX,QAAQ;GACN;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;EACF;EACA,MAAM;EACN,MAAM;CACR;CACA;EACE,WAAW;EACX,QAAQ;GACN;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;EACF;EACA,MAAM;EACN,MAAM;CACR;CACA;EACE,WAAW;EACX,QAAQ;GACN;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;EACF;EACA,MAAM;EACN,MAAM;CACR;CACA;EACE,WAAW;EACX,QAAQ;GACN;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;EACF;EACA,MAAM;EACN,MAAM;CACR;CACA;EACE,WAAW;EACX,QAAQ,CACN;GACE,SAAS;GACT,cAAc;GACd,MAAM;GACN,MAAM;EACR,GACA;GACE,SAAS;GACT,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,MAAM;CACR;CACA;EACE,WAAW;EACX,QAAQ;GACN;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,SAAS;IACT,cAAc;IACd,MAAM;IACN,MAAM;GACR;EACF;EACA,MAAM;EACN,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,GACA;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,GACA;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,GACA;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS;GACP;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;EACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,GACA;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,SAAS,CAAC;EACV,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ;GACN;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;EACF;EACA,MAAM;EACN,SAAS,CAAC;EACV,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,MAAM;EACN,SAAS,CAAC;EACV,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ;GACN;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;GACA;IACE,cAAc;IACd,MAAM;IACN,MAAM;GACR;EACF;EACA,MAAM;EACN,SAAS,CAAC;EACV,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CAAC;EACV,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CAAC;EACT,MAAM;EACN,SAAS,CACP;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,SAAS;EACT,iBAAiB;EACjB,MAAM;CACR;CACA;EACE,UAAU;EACV,QAAQ,CACN;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,GACA;GACE,cAAc;GACd,MAAM;GACN,MAAM;EACR,CACF;EACA,M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"}