@moonbeam-network/xcm-builder
Version:
Moonbeam XCM builder
1 lines • 242 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/contracts/XcmPrecompile/XcmPrecompileAbi.ts","../src/contract/contracts/Xtokens/Xtokens.ts","../src/builder.utils.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.util.ts","../src/extrinsic/pallets/polkadotXcm/polkadotXcm.ts","../src/extrinsic/pallets/xTokens/xTokens.utils.ts","../src/extrinsic/pallets/xTokens/xTokens.ts","../src/extrinsic/pallets/xTransfer/xTransfer.ts","../src/extrinsic/pallets/xcmPallet/xcmPallet.ts","../src/extrinsic/ExtrinsicBuilder.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/mrl/providers/wormhole/contract/Batch/Batch.ts","../src/mrl/providers/wormhole/extrinsic/polkadotXcm/polkadotXcm.ts","../src/mrl/providers/wormhole/contract/Batch/abi/peaq/PeaqBatchContractAbi.ts","../src/mrl/providers/wormhole/contract/Batch/abi/peaq/PeaqXcmUtilsContractAbi.ts","../src/mrl/providers/wormhole/contract/Batch/abi/peaq/PeaqXtokensContractAbi.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/wormhole.ts","../src/mrl/providers/wormhole/wormhole/WormholeConfig.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 './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\nexport interface QueryConfigConstructorParams\n extends BaseConfigConstructorParams {\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 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 ...other\n }: QueryConfigConstructorParams) {\n super({ ...other });\n\n this.args = args;\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: (): 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 };\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 // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n args: any[];\n}\n\nexport class ContractConfig extends BaseConfig {\n readonly address: string;\n\n readonly abi: Abi;\n\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n readonly args: any[];\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 ...other\n }: ContractConfigConstructorParams) {\n super({ ...other });\n\n this.address = address;\n this.abi = abi;\n this.args = args;\n }\n\n encodeFunctionData() {\n return encodeFunctionData({\n abi: this.abi,\n functionName: this.func,\n args: this.args,\n });\n }\n}\n","import { u8aToHex } from '@polkadot/util';\nimport { decodeAddress } from '@polkadot/util-crypto';\nimport { ContractConfig } from '../../../types';\nimport type { ContractConfigBuilder } from '../../ContractBuilder.interfaces';\nimport { XCM_ABI } from './XcmPrecompileAbi';\n\nconst XCM_PRECOMPILE_ADDRESS = '0x000000000000000000000000000000000000081A';\n\nexport function XcmPrecompile() {\n return {\n transferAssetsToPara20: (): ContractConfigBuilder => ({\n build: ({ destinationAddress, asset, destination }) => {\n return new ContractConfig({\n address: XCM_PRECOMPILE_ADDRESS,\n abi: XCM_ABI,\n args: [\n destination.parachainId,\n destinationAddress,\n [[asset.address, asset.amount]],\n 0,\n ],\n func: 'transferAssetsToPara20',\n module: 'Xcm',\n });\n },\n }),\n transferAssetsToPara32: (): ContractConfigBuilder => ({\n build: ({ destinationAddress, asset, destination }) => {\n return new ContractConfig({\n address: XCM_PRECOMPILE_ADDRESS,\n abi: XCM_ABI,\n args: [\n destination.parachainId,\n u8aToHex(decodeAddress(destinationAddress)),\n [[asset.address, asset.amount]],\n 0,\n ],\n func: 'transferAssetsToPara32',\n module: 'Xcm',\n });\n },\n }),\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","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: '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: 'transferAssetsUsingTypeAndThenLocation',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const;\n","import type { AnyParachain } from '@moonbeam-network/xcm-types';\nimport { formatAssetIdToERC20 } from '@moonbeam-network/xcm-utils';\nimport { u8aToHex } from '@polkadot/util';\nimport { decodeAddress, evmToAddress } from '@polkadot/util-crypto';\nimport { getPrecompileDestinationInterior } from '../../../builder.utils';\nimport { ContractConfig } from '../../../types/evm/ContractConfig';\nimport type { ContractConfigBuilder } from '../../ContractBuilder.interfaces';\nimport { XTOKENS_ABI } from './XtokensABI';\n\nconst U_64_MAX = 18446744073709551615n;\nconst XTOKENS_CONTRACT_ADDRESS = '0x0000000000000000000000000000000000000804';\n\nexport function Xtokens() {\n return {\n transfer: (weight = U_64_MAX): ContractConfigBuilder => ({\n build: ({ destinationAddress, asset, destination }) =>\n new ContractConfig({\n address: XTOKENS_CONTRACT_ADDRESS,\n abi: XTOKENS_ABI,\n args: [\n asset.address\n ? formatAssetIdToERC20(asset.address)\n : asset.getAssetId(),\n asset.amount,\n getDestinationMultilocation(destinationAddress, destination),\n weight,\n ],\n func: 'transfer',\n module: 'Xtokens',\n }),\n }),\n transferMultiCurrencies: (\n shouldTransferAssetPrecedeFeeAsset = true,\n weight = U_64_MAX,\n ): ContractConfigBuilder => ({\n build: ({ asset, destination, destinationAddress, fee }) => {\n const transferAsset = [\n asset.address\n ? formatAssetIdToERC20(asset.address)\n : asset.getAssetId(),\n asset.amount,\n ];\n\n const feeAsset = [\n fee.address ? formatAssetIdToERC20(fee.address) : fee.getAssetId(),\n fee.amount,\n ];\n\n const assets = shouldTransferAssetPrecedeFeeAsset\n ? [transferAsset, feeAsset]\n : [feeAsset, transferAsset];\n const feeAssetIndex = shouldTransferAssetPrecedeFeeAsset ? 1 : 0;\n return new ContractConfig({\n address: XTOKENS_CONTRACT_ADDRESS,\n abi: XTOKENS_ABI,\n args: [\n assets,\n feeAssetIndex,\n getDestinationMultilocation(destinationAddress, destination),\n weight,\n ],\n func: 'transferMultiCurrencies',\n module: 'Xtokens',\n });\n },\n }),\n transferWithEvmTo32: (weight = U_64_MAX): ContractConfigBuilder => ({\n build: ({ destinationAddress, asset, destination }) => {\n const multilocation =\n getDestinationMultilocationForPrecompileDestination(\n destinationAddress,\n destination,\n );\n\n return new ContractConfig({\n address: XTOKENS_CONTRACT_ADDRESS,\n abi: XTOKENS_ABI,\n args: [\n asset.address\n ? formatAssetIdToERC20(asset.address)\n : asset.getAssetId(),\n asset.amount,\n multilocation,\n weight,\n ],\n func: 'transfer',\n module: 'Xtokens',\n });\n },\n }),\n };\n}\n\ntype DestinationMultilocation = [\n /**\n * 1 - if transaction is going through a relay chain\n */\n 1,\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];\n\nfunction getDestinationMultilocationForPrecompileDestination(\n address: string,\n destination: AnyParachain,\n): DestinationMultilocation {\n /* \n 01: AccountId32\n 03: AccountKey20\n https://docs.moonbeam.network/builders/interoperability/xcm/xc20/xtokens/#building-the-precompile-multilocation\n */\n const accountType = '01';\n const substrateAddress = evmToAddress(address);\n const acc = `0x${accountType}${u8aToHex(\n decodeAddress(substrateAddress),\n -1,\n false,\n )}00`;\n\n return [\n 1,\n destination.parachainId\n ? [`0x0000000${destination.parachainId.toString(16)}`, acc]\n : [acc],\n ];\n}\n\nfunction getDestinationMultilocation(\n address: string,\n destination: AnyParachain,\n): DestinationMultilocation {\n const interior = getPrecompileDestinationInterior(destination, address);\n return [1, interior];\n}\n","import { type AnyParachain, EvmParachain } from '@moonbeam-network/xcm-types';\nimport { u8aToHex } from '@polkadot/util';\nimport { decodeAddress } from '@polkadot/util-crypto';\nimport type { Address } from 'viem';\n\nexport function getPrecompileDestinationInterior(\n destination: AnyParachain,\n address?: string,\n): [Address, Address] | [Address] {\n if (!address) {\n return [`0x0000000${destination.parachainId.toString(16)}`];\n }\n\n /* \n 01: AccountId32\n 03: AccountKey20\n https://docs.moonbeam.network/builders/interoperability/xcm/xc20/xtokens/#building-the-precompile-multilocation\n */\n const accountType = EvmParachain.is(destination) ? '03' : '01';\n const acc = `0x${accountType}${u8aToHex(\n decodeAddress(address),\n -1,\n false,\n )}00` as Address;\n\n return destination.parachainId\n ? [`0x0000000${destination.parachainId.toString(16)}`, acc]\n : [acc];\n}\n","export const XTOKENS_ABI = [\n {\n inputs: [\n {\n internalType: 'address',\n name: 'currencyAddress',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\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 Xtokens.Multilocation',\n name: 'destination',\n type: 'tuple',\n },\n {\n internalType: 'uint64',\n name: 'weight',\n type: 'uint64',\n },\n ],\n name: 'transfer',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n components: [\n {\n internalType: 'address',\n name: 'currencyAddress',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n internalType: 'struct Xtokens.Currency[]',\n name: 'currencies',\n type: 'tuple[]',\n },\n {\n internalType: 'uint32',\n name: 'feeItem',\n type: 'uint32',\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 Xtokens.Multilocation',\n name: 'destination',\n type: 'tuple',\n },\n {\n internalType: 'uint64',\n name: 'weight',\n type: 'uint64',\n },\n ],\n name: 'transferMultiCurrencies',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const;\n","import { XcmPrecompile } from './contracts/XcmPrecompile';\nimport { Xtokens } from './contracts/Xtokens';\n\nexport function ContractBuilder() {\n return {\n Xtokens,\n XcmPrecompile,\n };\n}\n","export const ERC20_ABI = [\n {\n constant: true,\n inputs: [],\n name: 'name',\n outputs: [\n {\n name: '',\n type: 'string',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n name: '_spender',\n type: 'address',\n },\n {\n name: '_value',\n type: 'uint256',\n },\n ],\n name: 'approve',\n outputs: [\n {\n name: '',\n type: 'bool',\n },\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'totalSupply',\n outputs: [\n {\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 name: '_from',\n type: 'address',\n },\n {\n name: '_to',\n type: 'address',\n },\n {\n name: '_value',\n type: 'uint256',\n },\n ],\n name: 'transferFrom',\n outputs: [\n {\n name: '',\n type: 'bool',\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 name: '',\n type: 'uint8',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [\n {\n name: '_owner',\n type: 'address',\n },\n ],\n name: 'balanceOf',\n outputs: [\n {\n name: 'balance',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'symbol',\n outputs: [\n {\n name: '',\n type: 'string',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n name: '_to',\n type: 'address',\n },\n {\n name: '_value',\n type: 'uint256',\n },\n ],\n name: 'transfer',\n outputs: [\n {\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 name: '_owner',\n type: 'address',\n },\n {\n name: '_spender',\n type: 'address',\n },\n ],\n name: 'allowance',\n outputs: [\n {\n name: '',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n payable: true,\n stateMutability: 'payable',\n type: 'fallback',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n name: 'owner',\n type: 'address',\n },\n {\n indexed: true,\n name: 'spender',\n type: 'address',\n },\n {\n indexed: false,\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 name: 'from',\n type: 'address',\n },\n {\n indexed: true,\n name: 'to',\n type: 'address',\n },\n {\n indexed: false,\n name: 'value',\n type: 'uint256',\n },\n ],\n name: 'Transfer',\n type: 'event',\n },\n] as const;\n","import { ExtrinsicConfig } from '../../../types/substrate/ExtrinsicConfig';\nimport type { ExtrinsicConfigBuilder } from '../../ExtrinsicBuilder.interfaces';\nimport { getExtrinsicAccount } from '../../ExtrinsicBuilder.utils';\n\nexport enum EqBalancesFee {\n SovereignAccWillPay = 'SovereignAccWillPay',\n TargetChainAccWillPay = 'TargetChainAccWillPay',\n ThisAccWillPay = 'ThisAccWillPay',\n}\n\nconst pallet = 'eqBalances';\n\nexport function eqBalances() {\n return {\n xcmTransfer: (): ExtrinsicConfigBuilder => ({\n build: ({ destinationAddress, asset, destination }) =>\n new ExtrinsicConfig({\n module: pallet,\n func: 'xcmTransfer',\n getArgs: () => [\n asset.getAssetId(),\n asset.amount,\n {\n parents: 1,\n interior: {\n X2: [\n {\n Parachain: destination.parachainId,\n },\n getExtrinsicAccount(destinationAddress),\n ],\n },\n },\n EqBalancesFee.ThisAccWillPay,\n ],\n }),\n }),\n transferXcm: (): ExtrinsicConfigBuilder => ({\n build: ({ destinationAddress: address, asset, destination, fee }) =>\n new ExtrinsicConfig({\n module: pallet,\n func: 'transferXcm',\n getArgs: () => {\n const amountWithoutFee =\n asset.amount - fee.amount > 0n ? asset.amount - fee.amount : 0n;\n\n return [\n [\n asset.getAssetId(),\n asset.isSame(fee) ? amountWithoutFee : asset.amount,\n ],\n [fee.getAssetId(), fee.amount],\n {\n parents: 1,\n interior: {\n X2: [\n {\n Parachain: destination.parachainId,\n },\n getExtrinsicAccount(address),\n ],\n },\n },\n ];\n },\n }),\n }),\n };\n}\n","import 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 BuilderParams {\n // biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this\n asset: any;\n func?: SubmittableExtrinsicFunction<'promise'>;\n parents?: Parents;\n feeIndex?: number;\n}\n\nexport function getPolkadotXcmExtrinsicArgs({\n asset,\n destinationAddress,\n destination,\n func,\n parents = 1,\n feeIndex = 0,\n}: GetExtrinsicParams) {\n const version = getExtrinsicArgumentVersion(func);\n\n return [\n {\n [version]: normalizeX1(version, {\n parents,\n interior: {\n X1: {\n Parachain: destination.parachainId,\n },\n },\n }),\n },\n {\n [version]: normalizeX1(version, {\n parents: 0,\n interior: {\n X1: getExtrinsicAccount(destinationAddress),\n },\n }),\n },\n {\n [version]: asset,\n },\n feeIndex,\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","import { ExtrinsicConfig } from '../../../types/substrate/ExtrinsicConfig';\nimport type { ExtrinsicConfigBuilder } from '../../ExtrinsicBuilder.interfaces';\nimport {\n getExtrinsicAccount,\n getExtrinsicArgumentVersion,\n normalizeConcrete,\n normalizeX1,\n} from '../../ExtrinsicBuilder.utils';\nimport {\n getPolkadotXcmExtrinsicArgs,\n shouldFeeAssetPrecedeAsset,\n} from './polkadotXcm.util';\n\nconst pallet = 'polkadotXcm';\n\nexport function polkadotXcm() {\n return {\n limitedReserveTransferAssets: () => {\n const func = 'limitedReserveTransferAssets';\n\n return {\n here: (): ExtrinsicConfigBuilder => ({\n build: (params) =>\n new ExtrinsicConfig({\n module: pallet,\n func,\n getArgs: (extrinsicFunction) => {\n const version = getExtrinsicArgumentVersion(extrinsicFunction);\n return getPolkadotXcmExtrinsicArgs({\n ...params,\n func: extrinsicFunction,\n asset: [\n {\n id: normalizeConcrete(version, {\n parents: 0,\n interior: 'Here',\n }),\n fun: {\n Fungible: params.asset.amount,\n },\n },\n ],\n });\n },\n }),\n }),\n X1: (): ExtrinsicConfigBuilder => ({\n build: (params) =>\n new ExtrinsicConfig({\n module: pallet,\n func,\n getArgs: (extrinsicFunction) => {\n const version = getExtrinsicArgumentVersion(extrinsicFunction);\n\n return getPolkadotXcmExtrinsicArgs({\n ...params,\n func: extrinsicFunction,\n asset: [\n {\n id: normalizeConcrete(\n version,\n normalizeX1(version, {\n parents: 0,\n interior: {\n X1: {\n