@moonbeam-network/xcm-builder
Version:
Moonbeam XCM builder
1 lines • 388 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/extrinsic/ExtrinsicBuilder.utils.ts","../src/extrinsic/ExtrinsicBuilder.interfaces.ts","../src/types/BaseConfig.ts","../src/types/substrate/SubstrateQueryConfig.ts","../src/asset-min/AssetMinBuilder.ts","../src/balance/BalanceBuilder.ts","../src/types/evm/ContractConfig.ts","../src/contract/contracts/XcmPrecompile/XcmPrecompile.ts","../src/types/evm/EvmQueryConfig.ts","../src/types/substrate/ExtrinsicConfig.ts","../src/types/substrate/SubstrateCallConfig.ts","../src/contract/ContractBuilder.interfaces.ts","../src/contract/ContractBuilder.utils.ts","../src/extrinsic/pallets/polkadotXcm/polkadotXcm.util.ts","../src/contract/contracts/XcmPrecompile/XcmPrecompileAbi.ts","../src/contract/contracts/Xtokens/Xtokens.ts","../src/contract/contracts/Xtokens/XtokensABI.ts","../src/contract/ContractBuilder.ts","../src/balance/Erc20Abi.ts","../src/extrinsic/pallets/eqBalances/eqBalances.ts","../src/extrinsic/pallets/polkadotXcm/polkadotXcm.ts","../src/extrinsic/pallets/xcmPallet/xcmPallet.ts","../src/extrinsic/pallets/xTokens/xTokens.utils.ts","../src/extrinsic/pallets/xTokens/xTokens.ts","../src/extrinsic/pallets/xTransfer/xTransfer.ts","../src/extrinsic/ExtrinsicBuilder.ts","../src/fee/gateway/gateway.ts","../src/mrl/providers/snowbridge/contract/Gateway/GatewayAbi.ts","../src/fee/outboundQueueApi/outboundQueueApi.ts","../src/fee/FeeBuilder.utils.ts","../src/fee/VersionedAssetBuilder.ts","../src/fee/xcmPaymentApi/xcmPaymentApi.utils.ts","../src/fee/xcmPaymentApi/xcmPaymentApi.ts","../src/fee/FeeBuilder.ts","../src/monitoring/eventMonitoring/eventMonitoring.ts","../src/monitoring/eventMonitoring/eventMonitoring.utils.ts","../src/monitoring/MonitoringBuilder.ts","../src/mrl/providers/snowbridge/contract/Gateway/Gateway.ts","../src/mrl/MrlBuilder.interfaces.ts","../src/mrl/providers/snowbridge/snowbridge/SnowbridgeConfig.ts","../src/mrl/providers/snowbridge/contract/index.ts","../src/mrl/providers/snowbridge/extrinsic/ethereumTokenTransfer/ethereumTokenTransfers.ts","../src/mrl/providers/snowbridge/extrinsic/polkadotXcm/polkadotXcm.ts","../src/mrl/providers/snowbridge/extrinsic/xcmPallet/xcmPallet.ts","../src/mrl/providers/snowbridge/extrinsic/xcmPallet/xcmPallet.utils.ts","../src/mrl/providers/snowbridge/extrinsic/index.ts","../src/mrl/providers/snowbridge/index.ts","../src/mrl/providers/wormhole/contract/Batch/Batch.ts","../src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts","../src/mrl/providers/wormhole/contract/Batch/abi/BatchContractAbi.ts","../src/mrl/providers/wormhole/contract/Batch/abi/XcmUtilsContractAbi.ts","../src/mrl/providers/wormhole/contract/Batch/abi/XtokensContractAbi.ts","../src/mrl/providers/wormhole/contract/Batch/abi/abi.helpers.ts","../src/mrl/providers/wormhole/contract/Gmp/Gmp.ts","../src/mrl/providers/wormhole/contract/Gmp/GmpAbi.ts","../src/mrl/providers/wormhole/contract/TokenBridge/TokenBridge.ts","../src/mrl/providers/wormhole/wormhole/WormholeConfig.ts","../src/mrl/providers/wormhole/wormhole/wormhole.ts","../src/mrl/providers/wormhole/wormhole/wormholeFactory.ts","../src/mrl/providers/wormhole/contract/TokenBridge/TokenBridgeAbi.ts","../src/mrl/providers/wormhole/contract/TokenBridgeRelayer/TokenBridgeRelayer.ts","../src/mrl/providers/wormhole/contract/TokenBridgeRelayer/TokenBridgeRelayerAbi.ts","../src/mrl/providers/wormhole/contract/index.ts","../src/mrl/providers/wormhole/extrinsic/ethereumXcm/ethereumXcm.ts","../src/mrl/MrlBuilder.constants.ts","../src/mrl/providers/wormhole/extrinsic/ethereumXcm/BatchContractAbi.ts","../src/mrl/providers/wormhole/extrinsic/index.ts","../src/mrl/providers/wormhole/index.ts","../src/mrl/MrlBuilder.ts"],"sourcesContent":["import '@polkadot/api-augment';\n\nexport * from './asset-min';\nexport * from './balance';\nexport * from './builder.interfaces';\nexport * from './contract';\nexport * from './extrinsic';\nexport * from './fee';\nexport * from './monitoring';\nexport * from './mrl';\nexport * from './types';\n","import { isEthAddress } from '@moonbeam-network/xcm-utils';\nimport type { SubmittableExtrinsicFunction } from '@polkadot/api/types';\nimport { getTypeDef } from '@polkadot/types';\nimport type { AnyJson } from '@polkadot/types/types';\nimport { u8aToHex } from '@polkadot/util';\nimport { decodeAddress } from '@polkadot/util-crypto';\nimport { XcmVersion } from './ExtrinsicBuilder.interfaces';\n\nexport function getExtrinsicArgumentVersion(\n func?: SubmittableExtrinsicFunction<'promise'>,\n index = 0,\n): XcmVersion {\n if (!func) return XcmVersion.v1;\n\n const { type } = func.meta.args[index];\n const instance = func.meta.registry.createType(type.toString());\n const raw = getTypeDef(instance?.toRawType());\n\n if (!raw.sub) {\n return XcmVersion.v1;\n }\n\n const versions = Array.isArray(raw.sub)\n ? raw.sub.map((x) => x.name)\n : [raw.sub.name];\n\n if (versions.includes(XcmVersion.v5)) {\n return XcmVersion.v5;\n }\n\n if (versions.includes(XcmVersion.v4)) {\n return XcmVersion.v4;\n }\n\n if (versions.includes(XcmVersion.v3)) {\n return XcmVersion.v3;\n }\n\n if (versions.includes(XcmVersion.v2)) {\n return XcmVersion.v2;\n }\n\n if (versions.includes(XcmVersion.v1)) {\n return XcmVersion.v1;\n }\n\n throw new Error(\"Can't find XCM version\");\n}\n\nexport function getExtrinsicAccount(address: string) {\n return isEthAddress(address)\n ? {\n AccountKey20: {\n key: address,\n },\n }\n : {\n AccountId32: {\n id: u8aToHex(decodeAddress(address)),\n network: null,\n },\n };\n}\n\nexport function isXcmV4(xcmVersion: XcmVersion): boolean {\n return xcmVersion >= XcmVersion.v4;\n}\n\nexport function normalizeX1(\n xcmVersion: XcmVersion,\n versionedObject: Record<string, AnyJson | object>,\n) {\n if (!isXcmV4(xcmVersion)) return versionedObject;\n\n const normalizedObject = { ...versionedObject };\n const interior = normalizedObject.interior as object;\n\n if ('X1' in interior && interior?.X1 && !Array.isArray(interior.X1)) {\n interior.X1 = [interior.X1];\n } else if ('x1' in interior && interior?.x1 && !Array.isArray(interior.x1)) {\n interior.x1 = [interior.x1];\n }\n\n return normalizedObject;\n}\n\nexport function normalizeConcrete(\n xcmVersion: XcmVersion,\n versionedObject: object,\n) {\n return isXcmV4(xcmVersion)\n ? versionedObject\n : applyConcreteWrapper(versionedObject);\n}\n\nexport function applyConcreteWrapper(versionedObject: object) {\n return {\n Concrete: { ...versionedObject },\n };\n}\n","import type { ConfigBuilder } from '../builder.interfaces';\nimport type { ExtrinsicConfig } from '../types/substrate/ExtrinsicConfig';\n\nexport type ExtrinsicConfigBuilder = ConfigBuilder<ExtrinsicConfig>;\n\nexport enum XcmVersion {\n v1 = 'V1',\n v2 = 'V2',\n v3 = 'V3',\n v4 = 'V4',\n v5 = 'V5',\n}\n\nexport type Parents = 0 | 1;\n","export interface BaseConfigConstructorParams {\n module: string;\n func: string;\n}\n\nexport class BaseConfig {\n readonly module: string;\n\n readonly func: string;\n\n constructor({ module, func }: BaseConfigConstructorParams) {\n this.module = module;\n this.func = func;\n }\n}\n","import { BaseConfig, type BaseConfigConstructorParams } from '../BaseConfig';\n\ntype QueryType = 'query' | 'call';\n\nexport interface QueryConfigConstructorParams\n extends BaseConfigConstructorParams {\n queryType?: QueryType;\n args?: unknown[];\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n transform: (data: any) => Promise<bigint>;\n}\n\nexport class SubstrateQueryConfig extends BaseConfig {\n readonly args: unknown[];\n\n readonly queryType: QueryType;\n\n readonly transform: (data: unknown) => Promise<bigint>;\n\n static is(obj: unknown): obj is SubstrateQueryConfig {\n return obj instanceof SubstrateQueryConfig;\n }\n\n constructor({\n args = [],\n transform,\n queryType = 'query',\n ...other\n }: QueryConfigConstructorParams) {\n super({ ...other });\n\n this.args = args;\n this.queryType = queryType;\n this.transform = transform;\n }\n}\n","import type { Option } from '@polkadot/types';\nimport type { PalletAssetsAssetDetails } from '@polkadot/types/lookup';\nimport { getExtrinsicAccount } from '../extrinsic/ExtrinsicBuilder.utils';\nimport { SubstrateQueryConfig } from '../types/substrate/SubstrateQueryConfig';\nimport type { AssetMinConfigBuilder } from './AssetMinBuilder.interfaces';\n\nexport function AssetMinBuilder() {\n return {\n assetRegistry,\n assets,\n foreignAssets,\n };\n}\n\nfunction assetRegistry() {\n const pallet = 'assetRegistry';\n return {\n assetMetadatas: (): AssetMinConfigBuilder => ({\n build: ({ asset }) =>\n new SubstrateQueryConfig({\n module: pallet,\n func: 'assetMetadatas',\n args: [asset],\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n transform: async (response: Option<any>): Promise<bigint> =>\n response.unwrapOrDefault().minimalBalance.toBigInt(),\n }),\n }),\n currencyMetadatas: (): AssetMinConfigBuilder => ({\n build: ({ asset }) =>\n new SubstrateQueryConfig({\n module: pallet,\n func: 'currencyMetadatas',\n args: [asset],\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n transform: async (response: Option<any>): Promise<bigint> =>\n response.unwrapOrDefault().minimalBalance.toBigInt(),\n }),\n }),\n metadata: (): AssetMinConfigBuilder => ({\n build: ({ asset }) =>\n new SubstrateQueryConfig({\n module: pallet,\n func: 'metadata',\n args: [asset],\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n transform: async (response: Option<any>): Promise<bigint> =>\n response.unwrapOrDefault().existentialDeposit.toBigInt(),\n }),\n }),\n };\n}\n\nfunction assets() {\n return {\n asset: (): AssetMinConfigBuilder => ({\n build: ({ asset }) =>\n new SubstrateQueryConfig({\n module: 'assets',\n func: 'asset',\n args: [asset],\n transform: async (\n response: Option<PalletAssetsAssetDetails>,\n ): Promise<bigint> =>\n response.unwrapOrDefault().minBalance.toBigInt(),\n }),\n }),\n };\n}\n\nfunction foreignAssets() {\n return {\n asset: (): AssetMinConfigBuilder => ({\n build: ({ address }) => {\n if (!address) {\n throw new Error(\n 'Asset address is missing for foreignAssets.asset min calculation',\n );\n }\n const multilocation = {\n parents: 2,\n interior: {\n X2: [\n {\n globalconsensus: {\n ethereum: {\n chainId: 1,\n },\n },\n },\n getExtrinsicAccount(address),\n ],\n },\n };\n return new SubstrateQueryConfig({\n module: 'foreignAssets',\n func: 'asset',\n args: [multilocation],\n transform: async (\n response: Option<PalletAssetsAssetDetails>,\n ): Promise<bigint> =>\n response.unwrapOrDefault().minBalance.toBigInt(),\n });\n },\n }),\n };\n}\n","import type { Option } from '@polkadot/types';\nimport type {\n FrameSystemAccountInfo,\n PalletAssetsAssetAccount,\n PalletBalancesAccountData,\n} from '@polkadot/types/lookup';\nimport { evmToAddress } from '@polkadot/util-crypto';\nimport type { Address } from 'viem';\nimport { ContractConfig } from '../contract';\nimport { getExtrinsicAccount } from '../extrinsic/ExtrinsicBuilder.utils';\nimport { EvmQueryConfig } from '../types/evm/EvmQueryConfig';\nimport { SubstrateQueryConfig } from '../types/substrate/SubstrateQueryConfig';\nimport type {\n BalanceConfigBuilder,\n EquilibriumSystemBalanceData,\n PalletBalancesAccountDataOld,\n TokensPalletAccountData,\n} from './BalanceBuilder.interfaces';\nimport { ERC20_ABI } from './Erc20Abi';\n\nexport function BalanceBuilder() {\n return {\n evm,\n substrate,\n };\n}\n\nexport function evm() {\n return {\n erc20,\n native,\n };\n}\n\nfunction erc20(): BalanceConfigBuilder {\n return {\n build: ({ asset, address }) => {\n if (!asset.address) {\n throw new Error(`Asset ${asset.key} has no address`);\n }\n\n return new ContractConfig({\n address: asset.address,\n abi: ERC20_ABI,\n args: [address],\n func: 'balanceOf',\n module: 'Erc20',\n });\n },\n };\n}\n\nfunction native(): BalanceConfigBuilder {\n return {\n build: ({ address }) => {\n return new EvmQueryConfig({\n func: 'getBalance',\n args: [{ address: address as Address }],\n });\n },\n };\n}\nexport function substrate() {\n return {\n assets,\n foreignAssets,\n system,\n tokens,\n };\n}\n\nfunction assets() {\n return {\n account: (): BalanceConfigBuilder => ({\n build: ({ address, asset }) =>\n new SubstrateQueryConfig({\n module: 'assets',\n func: 'account',\n args: [asset.getBalanceAssetId(), address],\n transform: async (\n response: Option<PalletAssetsAssetAccount>,\n ): Promise<bigint> => response.unwrapOrDefault().balance.toBigInt(),\n }),\n }),\n };\n}\n\nfunction foreignAssets() {\n return {\n account: () => ({\n globalConsensus: (): BalanceConfigBuilder => ({\n build: ({ address, asset }) => {\n if (!asset.address) {\n throw new Error(\n 'Asset address is needed to calculate balance with foreignAssets.account function',\n );\n }\n\n const multilocation = {\n parents: 2,\n interior: {\n X2: [\n { GlobalConsensus: { ethereum: { chainId: 1 } } },\n getExtrinsicAccount(asset.address),\n ],\n },\n };\n\n return new SubstrateQueryConfig({\n module: 'foreignAssets',\n func: 'account',\n args: [multilocation, address],\n transform: async (\n response: Option<PalletAssetsAssetAccount>,\n ): Promise<bigint> => response.unwrapOrDefault().balance.toBigInt(),\n });\n },\n }),\n id: (): BalanceConfigBuilder => ({\n build: ({ address, asset }) => {\n return new SubstrateQueryConfig({\n module: 'foreignAssets',\n func: 'account',\n args: [asset.getBalanceAssetId(), address],\n transform: async (\n response: Option<PalletAssetsAssetAccount>,\n ): Promise<bigint> => response.unwrapOrDefault().balance.toBigInt(),\n });\n },\n }),\n }),\n };\n}\n\nfunction system() {\n return {\n account: (): BalanceConfigBuilder => ({\n build: ({ address }) =>\n new SubstrateQueryConfig({\n module: 'system',\n func: 'account',\n args: [address],\n transform: async (\n response: FrameSystemAccountInfo,\n ): Promise<bigint> => calculateSystemAccountBalance(response),\n }),\n }),\n accountEquilibrium: (): BalanceConfigBuilder => ({\n build: ({ address, asset }) =>\n new SubstrateQueryConfig({\n module: 'system',\n func: 'account',\n args: [address],\n transform: async (response): Promise<bigint> => {\n if (response.data.isEmpty) {\n return 0n;\n }\n\n const res = response.data.toJSON() as unknown;\n let balances: EquilibriumSystemBalanceData | undefined;\n\n if (Array.isArray(res)) {\n balances = res;\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n if (Array.isArray((res as any)?.v0?.balance)) {\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n balances = (res as any).v0.balance;\n }\n\n if (!balances) {\n throw new Error(\"Can't get balance from Equilibrium chain\");\n }\n\n const balance = balances.find(\n ([assetId]) => assetId === asset.getBalanceAssetId(),\n );\n\n if (!balance) {\n return 0n;\n }\n\n return BigInt(balance[1].positive);\n },\n }),\n }),\n accountEvmTo32: (): BalanceConfigBuilder => ({\n build: ({ address }) => {\n const substrateAddress = evmToAddress(address);\n\n return new SubstrateQueryConfig({\n module: 'system',\n func: 'account',\n args: [substrateAddress],\n transform: async (\n response: FrameSystemAccountInfo,\n ): Promise<bigint> => calculateSystemAccountBalance(response),\n });\n },\n }),\n };\n}\n\nfunction tokens() {\n return {\n accounts: (): BalanceConfigBuilder => ({\n build: ({ address, asset }) =>\n new SubstrateQueryConfig({\n module: 'tokens',\n func: 'accounts',\n args: [address, asset.getBalanceAssetId()],\n transform: async ({\n free,\n frozen,\n }: TokensPalletAccountData): Promise<bigint> =>\n BigInt(free.sub(frozen).toString()),\n }),\n }),\n };\n}\n\nexport async function calculateSystemAccountBalance(\n response: FrameSystemAccountInfo,\n): Promise<bigint> {\n const balance = response.data as PalletBalancesAccountData &\n PalletBalancesAccountDataOld;\n\n const free = BigInt(balance.free.toString());\n const frozen = balance.miscFrozen ?? balance.frozen;\n const frozenMinusReserved = BigInt(frozen.sub(balance.reserved).toString());\n const locked = frozenMinusReserved < 0n ? 0n : frozenMinusReserved;\n\n return free - locked;\n}\n","import { type Abi, encodeFunctionData } from 'viem';\nimport { BaseConfig, type BaseConfigConstructorParams } from '../BaseConfig';\n\nexport interface ContractConfigConstructorParams\n extends BaseConfigConstructorParams {\n address: string;\n abi: Abi;\n args: unknown[];\n value?: bigint;\n}\n\nexport class ContractConfig extends BaseConfig {\n readonly address: string;\n readonly abi: Abi;\n readonly args: unknown[];\n readonly value?: bigint;\n\n static is(obj: unknown): obj is ContractConfig {\n return obj instanceof ContractConfig;\n }\n\n constructor({\n address,\n abi,\n args,\n value,\n ...other\n }: ContractConfigConstructorParams) {\n super({ ...other });\n\n this.address = address;\n this.abi = abi;\n this.args = args;\n this.value = value;\n }\n\n encodeFunctionData() {\n return encodeFunctionData({\n abi: this.abi,\n functionName: this.func,\n args: this.args,\n });\n }\n}\n","import type { AssetAmount } from '@moonbeam-network/xcm-types';\nimport type { ApiPromise } from '@polkadot/api';\nimport { u8aToHex } from '@polkadot/util';\nimport { decodeAddress } from '@polkadot/util-crypto';\nimport type { BuilderParams } from '../../../builder.interfaces';\nimport { getExtrinsicArgumentVersion } from '../../../extrinsic/ExtrinsicBuilder.utils';\nimport { ContractConfig } from '../../../types';\nimport {\n type AssetAddressFormat,\n type AssetMultilocation,\n type ContractConfigBuilder,\n TransferType,\n} from '../../ContractBuilder.interfaces';\nimport {\n encodeXcmMessageToBytes,\n getAddressGlobalConsensusAssetMultilocation,\n getAssetAddressMultilocation,\n getBeneficiaryMultilocation,\n getDestinationParachainMultilocation,\n getGlobalConsensusAssetMultilocation,\n getGlobalConsensusDestination,\n getPalletInstanceMultilocation,\n} from '../../ContractBuilder.utils';\nimport { XCM_ABI } from './XcmPrecompileAbi';\n\nconst XCM_PRECOMPILE_ADDRESS = '0x000000000000000000000000000000000000081A';\n\nexport function XcmPrecompile() {\n return {\n transferAssetsToPara20: (\n shouldTransferAssetPrecedeFeeAsset = true,\n ): ContractConfigBuilder => ({\n build: ({ destinationAddress, asset, destination, fee }) => {\n const assets = getAssets(\n asset,\n fee,\n shouldTransferAssetPrecedeFeeAsset,\n );\n\n return new ContractConfig({\n address: XCM_PRECOMPILE_ADDRESS,\n abi: XCM_ABI,\n args: [destination.parachainId, destinationAddress, assets, 0],\n func: 'transferAssetsToPara20',\n module: 'Xcm',\n });\n },\n }),\n transferAssetsToPara32: (\n shouldTransferAssetPrecedeFeeAsset = false,\n ): ContractConfigBuilder => ({\n build: ({ destinationAddress, asset, destination, fee }) => {\n const assets = getAssets(\n asset,\n fee,\n shouldTransferAssetPrecedeFeeAsset,\n );\n\n return new ContractConfig({\n address: XCM_PRECOMPILE_ADDRESS,\n abi: XCM_ABI,\n args: [\n destination.parachainId,\n u8aToHex(decodeAddress(destinationAddress)),\n assets,\n 0,\n ],\n func: 'transferAssetsToPara32',\n module: 'Xcm',\n });\n },\n }),\n transferAssetsToRelay: (): ContractConfigBuilder => ({\n build: ({ destinationAddress, asset }) => {\n return new ContractConfig({\n address: XCM_PRECOMPILE_ADDRESS,\n abi: XCM_ABI,\n args: [\n u8aToHex(decodeAddress(destinationAddress)),\n [[asset.address, asset.amount]],\n 0,\n ],\n func: 'transferAssetsToRelay',\n module: 'Xcm',\n });\n },\n }),\n transferAssetsLocation: () => ({\n nativeAsset: (): ContractConfigBuilder => ({\n build: (params) => {\n return buildTransferAssetsLocation({\n ...params,\n assetsMultilocations: [\n getPalletInstanceMultilocation(params.sourceApi, params.asset),\n ],\n });\n },\n }),\n localErc20: (): ContractConfigBuilder => ({\n build: (params) => {\n return buildTransferAssetsLocation({\n ...params,\n assetsMultilocations: [\n getAssetAddressMultilocation(\n params.sourceApi,\n params.asset,\n params.destination,\n ),\n ],\n });\n },\n }),\n foreignAsset: (): ContractConfigBuilder => ({\n build: (params) => {\n return buildTransferAssetsLocation({\n ...params,\n assetsMultilocations: [\n getGlobalConsensusAssetMultilocation(\n params.sourceApi,\n params.asset,\n params.destination,\n ),\n ],\n });\n },\n }),\n foreignErc20: (): ContractConfigBuilder => ({\n build: (params) => {\n return buildTransferAssetsLocation({\n ...params,\n assetsMultilocations: [\n // fee asset\n getGlobalConsensusAssetMultilocation(\n params.sourceApi,\n params.fee,\n params.destination,\n ),\n // transfer asset\n getAddressGlobalConsensusAssetMultilocation(\n params.sourceApi,\n params.asset,\n params.destination,\n ),\n ],\n });\n },\n }),\n }),\n transferAssetsUsingTypeAndThenAddress: (\n shouldTransferAssetPrecedeFeeAsset = false,\n ): ContractConfigBuilder => ({\n build: ({\n destinationAddress,\n asset,\n fee,\n destination,\n destinationApi,\n sourceApi,\n }) => {\n const assets = getAssets(\n asset,\n fee,\n shouldTransferAssetPrecedeFeeAsset,\n );\n\n const xcmMessage = buildXcmMessage(\n assets,\n destinationAddress,\n sourceApi,\n );\n\n const customXcmOnDest = encodeXcmMessageToBytes(\n xcmMessage,\n destinationApi,\n );\n\n const feeIndex = shouldTransferAssetPrecedeFeeAsset ? 1 : 0;\n\n return new ContractConfig({\n address: XCM_PRECOMPILE_ADDRESS,\n abi: XCM_ABI,\n args: [\n getDestinationParachainMultilocation(destination),\n assets,\n TransferType.DestinationReserve,\n feeIndex,\n TransferType.DestinationReserve,\n customXcmOnDest,\n ],\n func: 'transferAssetsUsingTypeAndThenAddress',\n module: 'Xcm',\n });\n },\n }),\n };\n}\n\nfunction getAssets(\n asset: AssetAmount,\n feeAsset: AssetAmount,\n shouldTransferAssetPrecedeFeeAsset: boolean,\n): AssetAddressFormat[] {\n if (feeAsset.isSame(asset)) {\n return [[asset.address, asset.amount]];\n }\n\n return shouldTransferAssetPrecedeFeeAsset\n ? [\n [asset.address, asset.amount],\n [feeAsset.address, feeAsset.amount],\n ]\n : [\n [feeAsset.address, feeAsset.amount],\n [asset.address, asset.amount],\n ];\n}\n\nfunction buildXcmMessage(\n assets: AssetAddressFormat[],\n destinationAddress: string,\n sourceApi: ApiPromise | undefined,\n) {\n const xcmVersion = getExtrinsicArgumentVersion(\n sourceApi?.tx.polkadotXcm?.send || sourceApi?.tx.xcmPallet?.send,\n );\n\n const instruction = {\n DepositAsset: {\n assets: { Wild: { AllCounted: assets.length } },\n beneficiary: {\n parents: 0,\n interior: {\n X1: [\n {\n AccountId32: {\n id: u8aToHex(decodeAddress(destinationAddress)),\n network: null,\n },\n },\n ],\n },\n },\n },\n };\n return {\n [xcmVersion]: [instruction],\n };\n}\n\ninterface BuildTransferAssetsLocationParams extends BuilderParams {\n assetsMultilocations: AssetMultilocation[];\n feeAssetItem?: number;\n}\n\nfunction buildTransferAssetsLocation({\n assetsMultilocations,\n feeAssetItem = 0,\n destinationAddress,\n destination,\n sourceApi,\n}: BuildTransferAssetsLocationParams) {\n return new ContractConfig({\n address: XCM_PRECOMPILE_ADDRESS,\n abi: XCM_ABI,\n args: [\n getGlobalConsensusDestination(sourceApi, destination),\n getBeneficiaryMultilocation(destinationAddress, destination),\n assetsMultilocations,\n feeAssetItem,\n ],\n func: 'transferAssetsLocation',\n module: 'Xcm',\n });\n}\n","import type { HttpTransport, PublicClient } from 'viem';\n\nexport type EvmQueryFunctions = 'getBalance';\nexport type EvmFunctionArgs = Parameters<\n PublicClient<HttpTransport>[EvmQueryFunctions]\n>;\n\nexport interface EvmQueryConfigParams {\n readonly args: EvmFunctionArgs;\n readonly func: EvmQueryFunctions;\n}\n\nexport class EvmQueryConfig {\n readonly args: EvmFunctionArgs;\n readonly func: EvmQueryFunctions;\n\n static is(obj: unknown): obj is EvmQueryConfig {\n return obj instanceof EvmQueryConfig;\n }\n\n constructor({ args, func }: EvmQueryConfigParams) {\n this.args = args;\n this.func = func;\n }\n}\n","import type { SubmittableExtrinsicFunction } from '@polkadot/api/types';\nimport { BaseConfig, type BaseConfigConstructorParams } from '../BaseConfig';\n\nexport interface ExtrinsicConfigConstructorParams\n extends Omit<BaseConfigConstructorParams, 'type'> {\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n getArgs: (func?: SubmittableExtrinsicFunction<'promise'>) => any[];\n}\n\nexport class ExtrinsicConfig extends BaseConfig {\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n getArgs: (func?: SubmittableExtrinsicFunction<'promise'>) => any[];\n\n static is(obj: unknown): obj is ExtrinsicConfig {\n return obj instanceof ExtrinsicConfig;\n }\n\n constructor({ getArgs, ...other }: ExtrinsicConfigConstructorParams) {\n super({ ...other });\n\n this.getArgs = getArgs;\n }\n}\n","import type { ApiPromise } from '@polkadot/api';\n\nexport interface SubstrateCallConfigConstructorParams {\n api: ApiPromise;\n call: () => Promise<bigint>;\n}\n\nexport class SubstrateCallConfig {\n readonly api: ApiPromise;\n\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n readonly call: () => Promise<any>;\n\n static is(obj: unknown): obj is SubstrateCallConfig {\n return obj instanceof SubstrateCallConfig;\n }\n\n constructor({ api, call }: SubstrateCallConfigConstructorParams) {\n this.api = api;\n this.call = call;\n }\n}\n","import type { ConfigBuilder } from '../builder.interfaces';\nimport type { ContractConfig } from '../types/evm/ContractConfig';\n\nexport type ContractConfigBuilder = ConfigBuilder<ContractConfig>;\n\nexport type DestinationMultilocation = [\n /**\n * 0 - if destination is referring to a location in the same chain\n * 1 - if transaction is going through or to a relay chain\n * 2 - if transaction is going to a parachain in another ecosystem\n */\n 0 | 1 | 2,\n (\n | [\n /**\n * example '0x00000007DC'\n * 7DC - parachain id in hex\n * can be found here:\n * - https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-rpc.polkadot.io#/parachains\n * - https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/parachains\n */\n string,\n /**\n * example '0x01%account%00',\n * enum = 01 (AccountId32)\n * networkId = 00 (any)\n */\n string,\n ]\n | [\n /**\n * example '0x01%account%00',\n * enum = 01 (AccountId32)\n * networkId = 00 (any)\n */\n string,\n ]\n /**\n * example 'Here',\n */\n | []\n ),\n];\n\nexport type AssetAddressFormat = (string | bigint | undefined)[];\n\nexport enum TransferType {\n Teleport,\n LocalReserve,\n DestinationReserve,\n}\n\nexport type AssetMultilocation = [[number, string[]], bigint];\n","import {\n type AnyParachain,\n type AssetAmount,\n EvmParachain,\n} from '@moonbeam-network/xcm-types';\nimport type { ApiPromise } from '@polkadot/api';\nimport { u8aToHex } from '@polkadot/util';\nimport { decodeAddress } from '@polkadot/util-crypto';\nimport type { Address } from 'viem';\nimport { getGlobalConsensus } from '../extrinsic/pallets/polkadotXcm/polkadotXcm.util';\nimport type {\n AssetMultilocation,\n DestinationMultilocation,\n} from './ContractBuilder.interfaces';\n\nexport function getPrecompileDestinationInterior(\n destination: AnyParachain,\n address?: string,\n): [Address, Address] | [Address] {\n if (!address) {\n return [encodeParachain(destination.parachainId)];\n }\n const acc = encodeAddress(destination, address);\n\n return destination.parachainId\n ? [encodeParachain(destination.parachainId), acc]\n : [acc];\n}\n\nexport function getBeneficiaryMultilocation(\n address: string,\n destination: AnyParachain,\n): DestinationMultilocation {\n return [0, [encodeAddress(destination, address)]];\n}\n\nexport function getDestinationMultilocation(\n address: string,\n destination: AnyParachain,\n): DestinationMultilocation {\n const interior = getPrecompileDestinationInterior(destination, address);\n return [1, interior];\n}\n\nexport function getDestinationParachainMultilocation(\n destination: AnyParachain,\n): DestinationMultilocation {\n if (destination.isRelay) {\n return [1, []];\n }\n\n return [1, [encodeParachain(destination.parachainId)]];\n}\n\nexport function getGlobalConsensusDestination(\n sourceApi: ApiPromise | undefined,\n destination: AnyParachain,\n) {\n return [\n 2,\n [\n encodeGlobalConsensus(sourceApi, destination),\n encodeParachain(destination.parachainId),\n ],\n ] as const;\n}\n\nexport function getPalletInstanceMultilocation(\n sourceApi: ApiPromise | undefined,\n asset: AssetAmount,\n): AssetMultilocation {\n return [\n [0, [encodePalletInstance(sourceApi, asset.getAssetPalletInstance())]],\n asset.amount,\n ];\n}\n\nexport function getAssetAddressMultilocation(\n sourceApi: ApiPromise | undefined,\n asset: AssetAmount,\n destination: AnyParachain,\n): AssetMultilocation {\n if (!asset.address) {\n throw new Error(`Asset address is required for ${asset.key}`);\n }\n\n return [\n [\n 0,\n [\n encodePalletInstance(sourceApi, asset.getAssetPalletInstance()),\n encodeAddress(destination, asset.address),\n ],\n ],\n asset.amount,\n ];\n}\n\nexport function getGlobalConsensusAssetMultilocation(\n sourceApi: ApiPromise | undefined,\n asset: AssetAmount,\n destination: AnyParachain,\n): AssetMultilocation {\n const assetInDestination = destination.getChainAsset(asset);\n return [\n [\n 2,\n [\n encodeGlobalConsensus(sourceApi, destination),\n encodeParachain(destination.parachainId),\n encodePalletInstance(\n sourceApi,\n assetInDestination.getAssetPalletInstance(),\n ),\n ],\n ],\n asset.amount,\n ];\n}\n\nexport function getAddressGlobalConsensusAssetMultilocation(\n sourceApi: ApiPromise | undefined,\n asset: AssetAmount,\n destination: AnyParachain,\n): AssetMultilocation {\n const assetInDestination = destination.getChainAsset(asset);\n\n if (!assetInDestination.address) {\n throw new Error(`Asset address is required for ${assetInDestination.key}`);\n }\n\n return [\n [\n 2,\n [\n encodeGlobalConsensus(sourceApi, destination),\n encodeParachain(destination.parachainId),\n encodePalletInstance(\n sourceApi,\n assetInDestination.getAssetPalletInstance(),\n ),\n encodeAddress(destination, assetInDestination.address),\n ],\n ],\n asset.amount,\n ];\n}\n\n/**\n * Encodes an XCM message to bytes for use in Solidity precompiles\n */\nexport function encodeXcmMessageToBytes(\n xcmMessage: Record<string, unknown>,\n api: ApiPromise | undefined,\n): Address {\n if (!api) {\n throw new Error('API is required to encode XCM message');\n }\n\n try {\n const versionedXcm = api.createType('XcmVersionedXcm', xcmMessage);\n return versionedXcm.toHex();\n } catch (error) {\n console.error('Failed to encode XCM message:', error);\n throw error;\n }\n}\n\nfunction encodeParachain(paraId: number): Address {\n return `0x00${paraId.toString(16).padStart(8, '0')}`;\n}\n\nfunction encodeGlobalConsensus(\n api: ApiPromise | undefined,\n destination: AnyParachain,\n): Address {\n const globalConsensus = getGlobalConsensus(destination);\n\n return encodeXcmJunction(api, {\n GlobalConsensus: globalConsensus,\n });\n}\n\nfunction encodePalletInstance(\n api: ApiPromise | undefined,\n palletInstance: number,\n): Address {\n return encodeXcmJunction(api, {\n PalletInstance: palletInstance,\n });\n}\n\nfunction encodeXcmJunction(\n api: ApiPromise | undefined,\n junction: object,\n): Address {\n if (!api) {\n throw new Error('API is required to encode XCM junction');\n }\n\n const junctionType = api.createType('XcmV3Junction', junction);\n\n return junctionType.toHex();\n}\n\nfunction encodeAddress(destination: AnyParachain, address: string): Address {\n const accountType = EvmParachain.is(destination) ? '03' : '01';\n return `0x${accountType}${u8aToHex(\n decodeAddress(address),\n -1,\n false,\n )}00` as Address;\n}\n","import { type AnyParachain, Ecosystem } from '@moonbeam-network/xcm-types';\nimport type { SubmittableExtrinsicFunction } from '@polkadot/api/types';\nimport type { BuilderParams } from '../../../builder.interfaces';\nimport type { Parents } from '../../ExtrinsicBuilder.interfaces';\nimport {\n getExtrinsicAccount,\n getExtrinsicArgumentVersion,\n normalizeX1,\n} from '../../ExtrinsicBuilder.utils';\n\nexport interface GetExtrinsicParams extends Omit<BuilderParams, 'asset'> {\n assets: object[];\n func?: SubmittableExtrinsicFunction<'promise'>;\n parents?: Parents;\n feeIndex?: number;\n globalConsensus?: Ecosystem;\n}\n\nexport function getPolkadotXcmExtrinsicArgs({\n assets,\n destinationAddress,\n destination,\n func,\n parents = 1,\n feeIndex = 0,\n}: GetExtrinsicParams) {\n const version = getExtrinsicArgumentVersion(func);\n\n return [\n // dest\n {\n [version]: normalizeX1(version, {\n parents,\n interior: {\n X1: {\n Parachain: destination.parachainId,\n },\n },\n }),\n },\n // beneficiary\n {\n [version]: normalizeX1(version, {\n parents: 0,\n interior: {\n X1: getExtrinsicAccount(destinationAddress),\n },\n }),\n },\n // assets\n {\n [version]: assets,\n },\n // feeAssetItem\n feeIndex,\n // weightLimit\n 'Unlimited',\n ];\n}\n\nfunction isKusamaDestination(destination: AnyParachain) {\n return (\n destination.ecosystem === Ecosystem.Kusama ||\n destination.ecosystem === Ecosystem.MoonsamaRelay\n );\n}\n\nfunction isPolkadotDestination(destination: AnyParachain) {\n return (\n destination.ecosystem === Ecosystem.Polkadot ||\n destination.ecosystem === Ecosystem.MoonlamaRelay\n );\n}\n\nexport function getGlobalConsensus(destination: AnyParachain) {\n if (isKusamaDestination(destination)) {\n return 'Kusama';\n }\n\n if (isPolkadotDestination(destination)) {\n return 'Polkadot';\n }\n\n return {\n ByGenesis: destination.relayGenesisHash,\n };\n}\n\nexport function getEcosystemTransferExtrinsicArgs({\n assets,\n destinationAddress,\n destination,\n func,\n feeIndex = 0,\n}: GetExtrinsicParams) {\n const version = getExtrinsicArgumentVersion(func);\n\n const globalConsensus = getGlobalConsensus(destination);\n\n return [\n // dest\n {\n [version]: normalizeX1(version, {\n parents: 2,\n interior: {\n X2: [\n { GlobalConsensus: globalConsensus },\n {\n Parachain: destination.parachainId,\n },\n ],\n },\n }),\n },\n // beneficiary\n {\n [version]: normalizeX1(version, {\n parents: 0,\n interior: {\n X1: getExtrinsicAccount(destinationAddress),\n },\n }),\n },\n // assets\n {\n [version]: assets,\n },\n // feeAssetItem\n feeIndex,\n // weightLimit\n 'Unlimited',\n ];\n}\n\nexport function shouldFeeAssetPrecedeAsset({\n asset,\n fee,\n}: BuilderParams): boolean {\n const assetIdNumber = Number(asset.getAssetId());\n const feeAssetIdNumber = Number(fee.getAssetId());\n\n if (Number.isNaN(assetIdNumber) || Number.isNaN(feeAssetIdNumber)) {\n return false;\n }\n\n return assetIdNumber > feeAssetIdNumber;\n}\n","export const XCM_ABI = [\n {\n inputs: [\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'dest',\n type: 'tuple',\n },\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'beneficiary',\n type: 'tuple',\n },\n {\n components: [\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'location',\n type: 'tuple',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct XCM.AssetLocationInfo[]',\n name: 'assets',\n type: 'tuple[]',\n },\n {\n internalType: 'uint32',\n name: 'feeAssetItem',\n type: 'uint32',\n },\n ],\n name: 'transferAssetsLocation',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'paraId',\n type: 'uint32',\n },\n {\n internalType: 'address',\n name: 'beneficiary',\n type: 'address',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'asset',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct XCM.AssetAddressInfo[]',\n name: 'assets',\n type: 'tuple[]',\n },\n {\n internalType: 'uint32',\n name: 'feeAssetItem',\n type: 'uint32',\n },\n ],\n name: 'transferAssetsToPara20',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'paraId',\n type: 'uint32',\n },\n {\n internalType: 'bytes32',\n name: 'beneficiary',\n type: 'bytes32',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'asset',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct XCM.AssetAddressInfo[]',\n name: 'assets',\n type: 'tuple[]',\n },\n {\n internalType: 'uint32',\n name: 'feeAssetItem',\n type: 'uint32',\n },\n ],\n name: 'transferAssetsToPara32',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'bytes32',\n name: 'beneficiary',\n type: 'bytes32',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'asset',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct XCM.AssetAddressInfo[]',\n name: 'assets',\n type: 'tuple[]',\n },\n {\n internalType: 'uint32',\n name: 'feeAssetItem',\n type: 'uint32',\n },\n ],\n name: 'transferAssetsToRelay',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'dest',\n type: 'tuple',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'asset',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct XCM.AssetAddressInfo[]',\n name: 'assets',\n type: 'tuple[]',\n },\n {\n internalType: 'enum XCM.TransferType',\n name: 'assetsTransferType',\n type: 'uint8',\n },\n {\n internalType: 'uint8',\n name: 'remoteFeesIdIndex',\n type: 'uint8',\n },\n {\n internalType: 'enum XCM.TransferType',\n name: 'feesTransferType',\n type: 'uint8',\n },\n {\n internalType: 'bytes',\n name: 'customXcmOnDest',\n type: 'bytes',\n },\n ],\n name: 'transferAssetsUsingTypeAndThenAddress',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'dest',\n type: 'tuple',\n },\n {\n components: [\n {\n internalType: 'address',\n name: 'asset',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct XCM.AssetAddressInfo[]',\n name: 'assets',\n type: 'tuple[]',\n },\n {\n internalType: 'uint8',\n name: 'remoteFeesIdIndex',\n type: 'uint8',\n },\n {\n internalType: 'bytes',\n name: 'customXcmOnDest',\n type: 'bytes',\n },\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'remoteReserve',\n type: 'tuple',\n },\n ],\n name: 'transferAssetsUsingTypeAndThenAddress',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'dest',\n type: 'tuple',\n },\n {\n components: [\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'location',\n type: 'tuple',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct XCM.AssetLocationInfo[]',\n name: 'assets',\n type: 'tuple[]',\n },\n {\n internalType: 'enum XCM.TransferType',\n name: 'assetsTransferType',\n type: 'uint8',\n },\n {\n internalType: 'uint8',\n name: 'remoteFeesIdIndex',\n type: 'uint8',\n },\n {\n internalType: 'enum XCM.TransferType',\n name: 'feesTransferType',\n type: 'uint8',\n },\n {\n internalType: 'bytes',\n name: 'customXcmOnDest',\n type: 'bytes',\n },\n ],\n name: 'transferAssetsUsingTypeAndThenLocation',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'dest',\n type: 'tuple',\n },\n {\n components: [\n {\n components: [\n {\n internalType: 'uint8',\n name: 'parents',\n type: 'uint8',\n },\n {\n internalType: 'bytes[]',\n name: 'interior',\n type: 'bytes[]',\n },\n ],\n internalType: 'struct XCM.Location',\n name: 'location',\n type: 'tuple',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct XCM.AssetLocationInfo[]',\n name: 'assets',\n type: 'tuple[]',\n },\n {\n internalType: 'uint8',\n name: 'remoteFeesIdIndex',\n type: 'uint8',\n },\n {\n internalType: 'bytes',\n name: 'customXcmOnDest',\n type: 'byte