diff --git a/web/packages/integrations/moonbeam/.env.example b/web/packages/integrations/moonbeam/.env.example new file mode 100644 index 0000000000..6fc16b3cb7 --- /dev/null +++ b/web/packages/integrations/moonbeam/.env.example @@ -0,0 +1 @@ +PRIVATE_KEY= diff --git a/web/packages/integrations/moonbeam/.gitignore b/web/packages/integrations/moonbeam/.gitignore new file mode 100644 index 0000000000..ce240032d0 --- /dev/null +++ b/web/packages/integrations/moonbeam/.gitignore @@ -0,0 +1,5 @@ +node_modules +dist +tsconfig.tsbuildinfo +build +.env diff --git a/web/packages/integrations/moonbeam/.prettierrc b/web/packages/integrations/moonbeam/.prettierrc new file mode 100644 index 0000000000..b85f6c6e4e --- /dev/null +++ b/web/packages/integrations/moonbeam/.prettierrc @@ -0,0 +1,23 @@ +{ + "overrides": [ + { + "files": "*.sol", + "options": { + "printWidth": 100, + "tabWidth": 4, + "singleQuote": false, + "bracketSpacing": true, + "explicitTypes": "always" + } + }, + { + "files": "*.ts", + "options": { + "semi": false, + "printWidth": 100, + "tabWidth": 4, + "singleQuote": false + } + } + ] +} diff --git a/web/packages/integrations/moonbeam/package.json b/web/packages/integrations/moonbeam/package.json new file mode 100644 index 0000000000..ec62000f5e --- /dev/null +++ b/web/packages/integrations/moonbeam/package.json @@ -0,0 +1,39 @@ +{ + "name": "@snowbridge/moonbeam", + "version": "0.1.27", + "description": "Snowbridge moonbeam integration", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "/~https://github.com/Snowfork/snowbridge.git", + "directory": "web/packages/integration/moonbeam" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "rebuild": "pnpm solc && pnpm typechain && tsc", + "build": "tsc", + "solc": "solcjs --abi precompiles/*.sol -o build", + "typechain": "typechain --target ethers-v6 './build/*.abi' --out-dir src/bindings", + "testTransfer": "npx ts-node src/testTransferWeth.ts start" + }, + "devDependencies": { + "@typechain/ethers-v6": "^0.5.1", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typechain": "^8.3.2", + "typescript": "^5.4.5", + "solc": "^0.8.28", + "prettier": "^2.8.8" + }, + "dependencies": { + "@polkadot/api": "^14.3.1", + "@polkadot/keyring": "^13.2.3", + "@polkadot/types": "^14.3.1", + "@polkadot/util": "^13.2.3", + "@polkadot/util-crypto": "^13.2.3", + "@typechain/ethers-v6": "^0.5.1", + "ethers": "^6.13.5", + "dotenv": "^16.4.5" + } +} diff --git a/web/packages/integrations/moonbeam/precompiles/XcmInterface.sol b/web/packages/integrations/moonbeam/precompiles/XcmInterface.sol new file mode 100644 index 0000000000..0f7ba63e0e --- /dev/null +++ b/web/packages/integrations/moonbeam/precompiles/XcmInterface.sol @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity >=0.8.3; + +/// @author The Moonbeam Team +/// @title XCM precompile Interface +/// @dev The interface that Solidity contracts use to interact with the substrate pallet-xcm. +interface XCM { + // A location is defined by its number of parents and the encoded junctions (interior) + struct Location { + uint8 parents; + bytes[] interior; + } + + // Support for Weights V2 + struct Weight { + uint64 refTime; + uint64 proofSize; + } + + // A way to represent fungible assets in XCM using Location format + struct AssetLocationInfo { + Location location; + uint256 amount; + } + + // A way to represent fungible assets in XCM using address format + struct AssetAddressInfo { + address asset; + uint256 amount; + } + + // The values start at `0` and are represented as `uint8` + enum TransferType { + Teleport, + LocalReserve, + DestinationReserve + } + + /// @dev Function to send assets via XCM using transfer_assets() pallet-xcm extrinsic. + /// @custom:selector 9ea8ada7 + /// @param dest The destination chain. + /// @param beneficiary The actual account that will receive the tokens on dest. + /// @param assets The combination (array) of assets to send in Location format. + /// @param feeAssetItem The index of the asset that will be used to pay for fees. + function transferAssetsLocation( + Location memory dest, + Location memory beneficiary, + AssetLocationInfo[] memory assets, + uint32 feeAssetItem + ) external; + + /// @dev Function to send assets via XCM to a 20 byte-like parachain + /// using transfer_assets() pallet-xcm extrinsic. + /// @custom:selector a0aeb5fe + /// @param paraId The para-id of the destination chain. + /// @param beneficiary The actual account that will receive the tokens on paraId destination. + /// @param assets The combination (array) of assets to send in Address format. + /// @param feeAssetItem The index of the asset that will be used to pay for fees. + function transferAssetsToPara20( + uint32 paraId, + address beneficiary, + AssetAddressInfo[] memory assets, + uint32 feeAssetItem + ) external; + + /// @dev Function to send assets via XCM to a 32 byte-like parachain + /// using transfer_assets() pallet-xcm extrinsic. + /// @custom:selector f23032c3 + /// @param paraId The para-id of the destination chain. + /// @param beneficiary The actual account that will receive the tokens on paraId destination. + /// @param assets The combination (array) of assets to send in Address format. + /// @param feeAssetItem The index of the asset that will be used to pay for fees. + function transferAssetsToPara32( + uint32 paraId, + bytes32 beneficiary, + AssetAddressInfo[] memory assets, + uint32 feeAssetItem + ) external; + + /// @dev Function to send assets via XCM to the relay chain + /// using transfer_assets() pallet-xcm extrinsic. + /// @custom:selector 6521cc2c + /// @param beneficiary The actual account that will receive the tokens on the relay chain. + /// @param assets The combination (array) of assets to send in Address format. + /// @param feeAssetItem The index of the asset that will be used to pay for fees. + function transferAssetsToRelay( + bytes32 beneficiary, + AssetAddressInfo[] memory assets, + uint32 feeAssetItem + ) external; + + /// @dev Function to send assets through transfer_assets_using_type_and_then() pallet-xcm + /// extrinsic. + /// Important: in this selector RemoteReserve type (for either assets or fees) is not allowed. + /// If users want to send assets and fees (in Location format) with a remote reserve, + /// they must use the selector fc19376c. + /// @custom:selector 8425d893 + /// @param dest The destination chain. + /// @param assets The combination (array) of assets to send in Location format. + /// @param assetsTransferType The TransferType corresponding to assets being sent. + /// @param remoteFeesIdIndex The index of the asset (inside assets array) to use as fees. + /// @param feesTransferType The TransferType corresponding to the asset used as fees. + /// @param customXcmOnDest The XCM message to execute on destination chain (SCALE encoded). + function transferAssetsUsingTypeAndThenLocation( + Location memory dest, + AssetLocationInfo[] memory assets, + TransferType assetsTransferType, + uint8 remoteFeesIdIndex, + TransferType feesTransferType, + bytes memory customXcmOnDest + ) external; + + /// @dev Function to send assets through transfer_assets_using_type_and_then() pallet-xcm + /// extrinsic. + /// @custom:selector fc19376c + /// @param dest The destination chain. + /// @param assets The combination (array) of assets to send in Location format. + /// @param remoteFeesIdIndex The index of the asset (inside assets array) to use as fees. + /// @param customXcmOnDest The XCM message to execute on destination chain (SCALE encoded). + /// @param remoteReserve The remote reserve corresponding for assets and fees. They MUST + /// share the same reserve. + function transferAssetsUsingTypeAndThenLocation( + Location memory dest, + AssetLocationInfo[] memory assets, + uint8 remoteFeesIdIndex, + bytes memory customXcmOnDest, + Location memory remoteReserve + ) external; + + /// @dev Function to send assets through transfer_assets_using_type_and_then() pallet-xcm + /// extrinsic. + /// Important: in this selector RemoteReserve type (for either assets or fees) is not allowed. + /// If users want to send assets and fees (in Address format) with a remote reserve, + /// they must use the selector aaecfc62. + /// @custom:selector 998093ee + /// @param dest The destination chain. + /// @param assets The combination (array) of assets to send in Address format. + /// @param assetsTransferType The TransferType corresponding to assets being sent. + /// @param remoteFeesIdIndex The index of the asset (inside assets array) to use as fees. + /// @param feesTransferType The TransferType corresponding to the asset used as fees. + /// @param customXcmOnDest The XCM message to execute on destination chain (SCALE encoded). + function transferAssetsUsingTypeAndThenAddress( + Location memory dest, + AssetAddressInfo[] memory assets, + TransferType assetsTransferType, + uint8 remoteFeesIdIndex, + TransferType feesTransferType, + bytes memory customXcmOnDest + ) external; + + /// @dev Function to send assets through transfer_assets_using_type_and_then() pallet-xcm + /// extrinsic. + /// @custom:selector aaecfc62 + /// @param dest The destination chain. + /// @param assets The combination (array) of assets to send in Address format. + /// @param remoteFeesIdIndex The index of the asset (inside assets array) to use as fees. + /// @param customXcmOnDest The XCM message to execute on destination chain (SCALE encoded). + /// @param remoteReserve The remote reserve corresponding for assets and fees. They MUST + /// share the same reserve. + function transferAssetsUsingTypeAndThenAddress( + Location memory dest, + AssetAddressInfo[] memory assets, + uint8 remoteFeesIdIndex, + bytes memory customXcmOnDest, + Location memory remoteReserve + ) external; +} diff --git a/web/packages/integrations/moonbeam/precompiles/XcmUtil.sol b/web/packages/integrations/moonbeam/precompiles/XcmUtil.sol new file mode 100644 index 0000000000..791525c288 --- /dev/null +++ b/web/packages/integrations/moonbeam/precompiles/XcmUtil.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity >=0.8.3; + +/// @dev The XcmUtils contract's address. +address constant XCM_UTILS_ADDRESS = 0x000000000000000000000000000000000000080C; + +/// @dev The XcmUtils contract's instance. +XcmUtils constant XCM_UTILS_CONTRACT = XcmUtils(XCM_UTILS_ADDRESS); + +/// @author The Moonbeam Team +/// @title Xcm Utils Interface +/// The interface through which solidity contracts will interact with xcm utils pallet +/// @custom:address 0x000000000000000000000000000000000000080C +interface XcmUtils { + // A multilocation is defined by its number of parents and the encoded junctions (interior) + struct Multilocation { + uint8 parents; + bytes[] interior; + } + + /// Get retrieve the account associated to a given MultiLocation + /// @custom:selector 343b3e00 + /// @param multilocation The multilocation that we want to know to which account maps to + /// @return account The account the multilocation maps to in this chain + function multilocationToAddress(Multilocation memory multilocation) + external + view + returns (address account); + + /// Get the weight that a message will consume in our chain + /// @custom:selector 25d54154 + /// @param message scale encoded xcm mversioned xcm message + function weightMessage(bytes memory message) + external + view + returns (uint64 weight); + + /// Get units per second charged for a given multilocation + /// @custom:selector 3f0f65db + /// @param multilocation scale encoded xcm mversioned xcm message + function getUnitsPerSecond(Multilocation memory multilocation) + external + view + returns (uint256 unitsPerSecond); + + /// Execute custom xcm message + /// @dev This function CANNOT be called from a smart contract + /// @custom:selector 34334a02 + /// @param message The versioned message to be executed scale encoded + /// @param maxWeight The maximum weight to be consumed + function xcmExecute(bytes memory message, uint64 maxWeight) external; + + /// Send custom xcm message + /// @custom:selector 98600e64 + /// @param dest The destination chain to which send this message + /// @param message The versioned message to be sent scale-encoded + function xcmSend(Multilocation memory dest, bytes memory message) external; +} diff --git a/web/packages/integrations/moonbeam/src/bindings/Precompiles_XcmInterface_sol_XCM.ts b/web/packages/integrations/moonbeam/src/bindings/Precompiles_XcmInterface_sol_XCM.ts new file mode 100644 index 0000000000..6437b60472 --- /dev/null +++ b/web/packages/integrations/moonbeam/src/bindings/Precompiles_XcmInterface_sol_XCM.ts @@ -0,0 +1,417 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedListener, + TypedContractMethod, +} from "./common"; + +export declare namespace XCM { + export type LocationStruct = { parents: BigNumberish; interior: BytesLike[] }; + + export type LocationStructOutput = [parents: bigint, interior: string[]] & { + parents: bigint; + interior: string[]; + }; + + export type AssetLocationInfoStruct = { + location: XCM.LocationStruct; + amount: BigNumberish; + }; + + export type AssetLocationInfoStructOutput = [ + location: XCM.LocationStructOutput, + amount: bigint + ] & { location: XCM.LocationStructOutput; amount: bigint }; + + export type AssetAddressInfoStruct = { + asset: AddressLike; + amount: BigNumberish; + }; + + export type AssetAddressInfoStructOutput = [asset: string, amount: bigint] & { + asset: string; + amount: bigint; + }; +} + +export interface Precompiles_XcmInterface_sol_XCMInterface extends Interface { + getFunction( + nameOrSignature: + | "transferAssetsLocation" + | "transferAssetsToPara20" + | "transferAssetsToPara32" + | "transferAssetsToRelay" + | "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,uint8,uint8,bytes)" + | "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,bytes,(uint8,bytes[]))" + | "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,uint8,uint8,bytes)" + | "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,bytes,(uint8,bytes[]))" + ): FunctionFragment; + + encodeFunctionData( + functionFragment: "transferAssetsLocation", + values: [ + XCM.LocationStruct, + XCM.LocationStruct, + XCM.AssetLocationInfoStruct[], + BigNumberish + ] + ): string; + encodeFunctionData( + functionFragment: "transferAssetsToPara20", + values: [ + BigNumberish, + AddressLike, + XCM.AssetAddressInfoStruct[], + BigNumberish + ] + ): string; + encodeFunctionData( + functionFragment: "transferAssetsToPara32", + values: [ + BigNumberish, + BytesLike, + XCM.AssetAddressInfoStruct[], + BigNumberish + ] + ): string; + encodeFunctionData( + functionFragment: "transferAssetsToRelay", + values: [BytesLike, XCM.AssetAddressInfoStruct[], BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,uint8,uint8,bytes)", + values: [ + XCM.LocationStruct, + XCM.AssetAddressInfoStruct[], + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike + ] + ): string; + encodeFunctionData( + functionFragment: "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,bytes,(uint8,bytes[]))", + values: [ + XCM.LocationStruct, + XCM.AssetAddressInfoStruct[], + BigNumberish, + BytesLike, + XCM.LocationStruct + ] + ): string; + encodeFunctionData( + functionFragment: "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,uint8,uint8,bytes)", + values: [ + XCM.LocationStruct, + XCM.AssetLocationInfoStruct[], + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike + ] + ): string; + encodeFunctionData( + functionFragment: "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,bytes,(uint8,bytes[]))", + values: [ + XCM.LocationStruct, + XCM.AssetLocationInfoStruct[], + BigNumberish, + BytesLike, + XCM.LocationStruct + ] + ): string; + + decodeFunctionResult( + functionFragment: "transferAssetsLocation", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferAssetsToPara20", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferAssetsToPara32", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferAssetsToRelay", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,uint8,uint8,bytes)", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,bytes,(uint8,bytes[]))", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,uint8,uint8,bytes)", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,bytes,(uint8,bytes[]))", + data: BytesLike + ): Result; +} + +export interface Precompiles_XcmInterface_sol_XCM extends BaseContract { + connect(runner?: ContractRunner | null): Precompiles_XcmInterface_sol_XCM; + waitForDeployment(): Promise; + + interface: Precompiles_XcmInterface_sol_XCMInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + transferAssetsLocation: TypedContractMethod< + [ + dest: XCM.LocationStruct, + beneficiary: XCM.LocationStruct, + assets: XCM.AssetLocationInfoStruct[], + feeAssetItem: BigNumberish + ], + [void], + "nonpayable" + >; + + transferAssetsToPara20: TypedContractMethod< + [ + paraId: BigNumberish, + beneficiary: AddressLike, + assets: XCM.AssetAddressInfoStruct[], + feeAssetItem: BigNumberish + ], + [void], + "nonpayable" + >; + + transferAssetsToPara32: TypedContractMethod< + [ + paraId: BigNumberish, + beneficiary: BytesLike, + assets: XCM.AssetAddressInfoStruct[], + feeAssetItem: BigNumberish + ], + [void], + "nonpayable" + >; + + transferAssetsToRelay: TypedContractMethod< + [ + beneficiary: BytesLike, + assets: XCM.AssetAddressInfoStruct[], + feeAssetItem: BigNumberish + ], + [void], + "nonpayable" + >; + + "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,uint8,uint8,bytes)": TypedContractMethod< + [ + dest: XCM.LocationStruct, + assets: XCM.AssetAddressInfoStruct[], + assetsTransferType: BigNumberish, + remoteFeesIdIndex: BigNumberish, + feesTransferType: BigNumberish, + customXcmOnDest: BytesLike + ], + [void], + "nonpayable" + >; + + "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,bytes,(uint8,bytes[]))": TypedContractMethod< + [ + dest: XCM.LocationStruct, + assets: XCM.AssetAddressInfoStruct[], + remoteFeesIdIndex: BigNumberish, + customXcmOnDest: BytesLike, + remoteReserve: XCM.LocationStruct + ], + [void], + "nonpayable" + >; + + "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,uint8,uint8,bytes)": TypedContractMethod< + [ + dest: XCM.LocationStruct, + assets: XCM.AssetLocationInfoStruct[], + assetsTransferType: BigNumberish, + remoteFeesIdIndex: BigNumberish, + feesTransferType: BigNumberish, + customXcmOnDest: BytesLike + ], + [void], + "nonpayable" + >; + + "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,bytes,(uint8,bytes[]))": TypedContractMethod< + [ + dest: XCM.LocationStruct, + assets: XCM.AssetLocationInfoStruct[], + remoteFeesIdIndex: BigNumberish, + customXcmOnDest: BytesLike, + remoteReserve: XCM.LocationStruct + ], + [void], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "transferAssetsLocation" + ): TypedContractMethod< + [ + dest: XCM.LocationStruct, + beneficiary: XCM.LocationStruct, + assets: XCM.AssetLocationInfoStruct[], + feeAssetItem: BigNumberish + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "transferAssetsToPara20" + ): TypedContractMethod< + [ + paraId: BigNumberish, + beneficiary: AddressLike, + assets: XCM.AssetAddressInfoStruct[], + feeAssetItem: BigNumberish + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "transferAssetsToPara32" + ): TypedContractMethod< + [ + paraId: BigNumberish, + beneficiary: BytesLike, + assets: XCM.AssetAddressInfoStruct[], + feeAssetItem: BigNumberish + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "transferAssetsToRelay" + ): TypedContractMethod< + [ + beneficiary: BytesLike, + assets: XCM.AssetAddressInfoStruct[], + feeAssetItem: BigNumberish + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,uint8,uint8,bytes)" + ): TypedContractMethod< + [ + dest: XCM.LocationStruct, + assets: XCM.AssetAddressInfoStruct[], + assetsTransferType: BigNumberish, + remoteFeesIdIndex: BigNumberish, + feesTransferType: BigNumberish, + customXcmOnDest: BytesLike + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,bytes,(uint8,bytes[]))" + ): TypedContractMethod< + [ + dest: XCM.LocationStruct, + assets: XCM.AssetAddressInfoStruct[], + remoteFeesIdIndex: BigNumberish, + customXcmOnDest: BytesLike, + remoteReserve: XCM.LocationStruct + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,uint8,uint8,bytes)" + ): TypedContractMethod< + [ + dest: XCM.LocationStruct, + assets: XCM.AssetLocationInfoStruct[], + assetsTransferType: BigNumberish, + remoteFeesIdIndex: BigNumberish, + feesTransferType: BigNumberish, + customXcmOnDest: BytesLike + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "transferAssetsUsingTypeAndThenLocation((uint8,bytes[]),((uint8,bytes[]),uint256)[],uint8,bytes,(uint8,bytes[]))" + ): TypedContractMethod< + [ + dest: XCM.LocationStruct, + assets: XCM.AssetLocationInfoStruct[], + remoteFeesIdIndex: BigNumberish, + customXcmOnDest: BytesLike, + remoteReserve: XCM.LocationStruct + ], + [void], + "nonpayable" + >; + + filters: {}; +} diff --git a/web/packages/integrations/moonbeam/src/bindings/Precompiles_XcmUtil_sol_XcmUtils.ts b/web/packages/integrations/moonbeam/src/bindings/Precompiles_XcmUtil_sol_XcmUtils.ts new file mode 100644 index 0000000000..c6cf5e0bff --- /dev/null +++ b/web/packages/integrations/moonbeam/src/bindings/Precompiles_XcmUtil_sol_XcmUtils.ts @@ -0,0 +1,188 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedListener, + TypedContractMethod, +} from "./common"; + +export declare namespace XcmUtils { + export type MultilocationStruct = { + parents: BigNumberish; + interior: BytesLike[]; + }; + + export type MultilocationStructOutput = [ + parents: bigint, + interior: string[] + ] & { parents: bigint; interior: string[] }; +} + +export interface Precompiles_XcmUtil_sol_XcmUtilsInterface extends Interface { + getFunction( + nameOrSignature: + | "getUnitsPerSecond" + | "multilocationToAddress" + | "weightMessage" + | "xcmExecute" + | "xcmSend" + ): FunctionFragment; + + encodeFunctionData( + functionFragment: "getUnitsPerSecond", + values: [XcmUtils.MultilocationStruct] + ): string; + encodeFunctionData( + functionFragment: "multilocationToAddress", + values: [XcmUtils.MultilocationStruct] + ): string; + encodeFunctionData( + functionFragment: "weightMessage", + values: [BytesLike] + ): string; + encodeFunctionData( + functionFragment: "xcmExecute", + values: [BytesLike, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "xcmSend", + values: [XcmUtils.MultilocationStruct, BytesLike] + ): string; + + decodeFunctionResult( + functionFragment: "getUnitsPerSecond", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "multilocationToAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "weightMessage", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "xcmExecute", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "xcmSend", data: BytesLike): Result; +} + +export interface Precompiles_XcmUtil_sol_XcmUtils extends BaseContract { + connect(runner?: ContractRunner | null): Precompiles_XcmUtil_sol_XcmUtils; + waitForDeployment(): Promise; + + interface: Precompiles_XcmUtil_sol_XcmUtilsInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + getUnitsPerSecond: TypedContractMethod< + [multilocation: XcmUtils.MultilocationStruct], + [bigint], + "view" + >; + + multilocationToAddress: TypedContractMethod< + [multilocation: XcmUtils.MultilocationStruct], + [string], + "view" + >; + + weightMessage: TypedContractMethod<[message: BytesLike], [bigint], "view">; + + xcmExecute: TypedContractMethod< + [message: BytesLike, maxWeight: BigNumberish], + [void], + "nonpayable" + >; + + xcmSend: TypedContractMethod< + [dest: XcmUtils.MultilocationStruct, message: BytesLike], + [void], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "getUnitsPerSecond" + ): TypedContractMethod< + [multilocation: XcmUtils.MultilocationStruct], + [bigint], + "view" + >; + getFunction( + nameOrSignature: "multilocationToAddress" + ): TypedContractMethod< + [multilocation: XcmUtils.MultilocationStruct], + [string], + "view" + >; + getFunction( + nameOrSignature: "weightMessage" + ): TypedContractMethod<[message: BytesLike], [bigint], "view">; + getFunction( + nameOrSignature: "xcmExecute" + ): TypedContractMethod< + [message: BytesLike, maxWeight: BigNumberish], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "xcmSend" + ): TypedContractMethod< + [dest: XcmUtils.MultilocationStruct, message: BytesLike], + [void], + "nonpayable" + >; + + filters: {}; +} diff --git a/web/packages/integrations/moonbeam/src/bindings/common.ts b/web/packages/integrations/moonbeam/src/bindings/common.ts new file mode 100644 index 0000000000..56b5f21e9c --- /dev/null +++ b/web/packages/integrations/moonbeam/src/bindings/common.ts @@ -0,0 +1,131 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + FunctionFragment, + Typed, + EventFragment, + ContractTransaction, + ContractTransactionResponse, + DeferredTopicFilter, + EventLog, + TransactionRequest, + LogDescription, +} from "ethers"; + +export interface TypedDeferredTopicFilter<_TCEvent extends TypedContractEvent> + extends DeferredTopicFilter {} + +export interface TypedContractEvent< + InputTuple extends Array = any, + OutputTuple extends Array = any, + OutputObject = any +> { + (...args: Partial): TypedDeferredTopicFilter< + TypedContractEvent + >; + name: string; + fragment: EventFragment; + getFragment(...args: Partial): EventFragment; +} + +type __TypechainAOutputTuple = T extends TypedContractEvent< + infer _U, + infer W +> + ? W + : never; +type __TypechainOutputObject = T extends TypedContractEvent< + infer _U, + infer _W, + infer V +> + ? V + : never; + +export interface TypedEventLog + extends Omit { + args: __TypechainAOutputTuple & __TypechainOutputObject; +} + +export interface TypedLogDescription + extends Omit { + args: __TypechainAOutputTuple & __TypechainOutputObject; +} + +export type TypedListener = ( + ...listenerArg: [ + ...__TypechainAOutputTuple, + TypedEventLog, + ...undefined[] + ] +) => void; + +export type MinEthersFactory = { + deploy(...a: ARGS[]): Promise; +}; + +export type GetContractTypeFromFactory = F extends MinEthersFactory< + infer C, + any +> + ? C + : never; +export type GetARGsTypeFromFactory = F extends MinEthersFactory + ? Parameters + : never; + +export type StateMutability = "nonpayable" | "payable" | "view"; + +export type BaseOverrides = Omit; +export type NonPayableOverrides = Omit< + BaseOverrides, + "value" | "blockTag" | "enableCcipRead" +>; +export type PayableOverrides = Omit< + BaseOverrides, + "blockTag" | "enableCcipRead" +>; +export type ViewOverrides = Omit; +export type Overrides = S extends "nonpayable" + ? NonPayableOverrides + : S extends "payable" + ? PayableOverrides + : ViewOverrides; + +export type PostfixOverrides, S extends StateMutability> = + | A + | [...A, Overrides]; +export type ContractMethodArgs< + A extends Array, + S extends StateMutability +> = PostfixOverrides<{ [I in keyof A]-?: A[I] | Typed }, S>; + +export type DefaultReturnType = R extends Array ? R[0] : R; + +// export interface ContractMethod = Array, R = any, D extends R | ContractTransactionResponse = R | ContractTransactionResponse> { +export interface TypedContractMethod< + A extends Array = Array, + R = any, + S extends StateMutability = "payable" +> { + (...args: ContractMethodArgs): S extends "view" + ? Promise> + : Promise; + + name: string; + + fragment: FunctionFragment; + + getFragment(...args: ContractMethodArgs): FunctionFragment; + + populateTransaction( + ...args: ContractMethodArgs + ): Promise; + staticCall( + ...args: ContractMethodArgs + ): Promise>; + send(...args: ContractMethodArgs): Promise; + estimateGas(...args: ContractMethodArgs): Promise; + staticCallResult(...args: ContractMethodArgs): Promise; +} diff --git a/web/packages/integrations/moonbeam/src/bindings/factories/Precompiles_XcmInterface_sol_XCM__factory.ts b/web/packages/integrations/moonbeam/src/bindings/factories/Precompiles_XcmInterface_sol_XCM__factory.ts new file mode 100644 index 0000000000..9f8ba7aca7 --- /dev/null +++ b/web/packages/integrations/moonbeam/src/bindings/factories/Precompiles_XcmInterface_sol_XCM__factory.ts @@ -0,0 +1,506 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + Precompiles_XcmInterface_sol_XCM, + Precompiles_XcmInterface_sol_XCMInterface, +} from "../Precompiles_XcmInterface_sol_XCM"; + +const _abi = [ + { + inputs: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "dest", + type: "tuple", + }, + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "beneficiary", + type: "tuple", + }, + { + components: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "location", + type: "tuple", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct XCM.AssetLocationInfo[]", + name: "assets", + type: "tuple[]", + }, + { + internalType: "uint32", + name: "feeAssetItem", + type: "uint32", + }, + ], + name: "transferAssetsLocation", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint32", + name: "paraId", + type: "uint32", + }, + { + internalType: "address", + name: "beneficiary", + type: "address", + }, + { + components: [ + { + internalType: "address", + name: "asset", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct XCM.AssetAddressInfo[]", + name: "assets", + type: "tuple[]", + }, + { + internalType: "uint32", + name: "feeAssetItem", + type: "uint32", + }, + ], + name: "transferAssetsToPara20", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint32", + name: "paraId", + type: "uint32", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + { + components: [ + { + internalType: "address", + name: "asset", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct XCM.AssetAddressInfo[]", + name: "assets", + type: "tuple[]", + }, + { + internalType: "uint32", + name: "feeAssetItem", + type: "uint32", + }, + ], + name: "transferAssetsToPara32", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + { + components: [ + { + internalType: "address", + name: "asset", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct XCM.AssetAddressInfo[]", + name: "assets", + type: "tuple[]", + }, + { + internalType: "uint32", + name: "feeAssetItem", + type: "uint32", + }, + ], + name: "transferAssetsToRelay", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "dest", + type: "tuple", + }, + { + components: [ + { + internalType: "address", + name: "asset", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct XCM.AssetAddressInfo[]", + name: "assets", + type: "tuple[]", + }, + { + internalType: "enum XCM.TransferType", + name: "assetsTransferType", + type: "uint8", + }, + { + internalType: "uint8", + name: "remoteFeesIdIndex", + type: "uint8", + }, + { + internalType: "enum XCM.TransferType", + name: "feesTransferType", + type: "uint8", + }, + { + internalType: "bytes", + name: "customXcmOnDest", + type: "bytes", + }, + ], + name: "transferAssetsUsingTypeAndThenAddress", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "dest", + type: "tuple", + }, + { + components: [ + { + internalType: "address", + name: "asset", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct XCM.AssetAddressInfo[]", + name: "assets", + type: "tuple[]", + }, + { + internalType: "uint8", + name: "remoteFeesIdIndex", + type: "uint8", + }, + { + internalType: "bytes", + name: "customXcmOnDest", + type: "bytes", + }, + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "remoteReserve", + type: "tuple", + }, + ], + name: "transferAssetsUsingTypeAndThenAddress", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "dest", + type: "tuple", + }, + { + components: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "location", + type: "tuple", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct XCM.AssetLocationInfo[]", + name: "assets", + type: "tuple[]", + }, + { + internalType: "enum XCM.TransferType", + name: "assetsTransferType", + type: "uint8", + }, + { + internalType: "uint8", + name: "remoteFeesIdIndex", + type: "uint8", + }, + { + internalType: "enum XCM.TransferType", + name: "feesTransferType", + type: "uint8", + }, + { + internalType: "bytes", + name: "customXcmOnDest", + type: "bytes", + }, + ], + name: "transferAssetsUsingTypeAndThenLocation", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "dest", + type: "tuple", + }, + { + components: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "location", + type: "tuple", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct XCM.AssetLocationInfo[]", + name: "assets", + type: "tuple[]", + }, + { + internalType: "uint8", + name: "remoteFeesIdIndex", + type: "uint8", + }, + { + internalType: "bytes", + name: "customXcmOnDest", + type: "bytes", + }, + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XCM.Location", + name: "remoteReserve", + type: "tuple", + }, + ], + name: "transferAssetsUsingTypeAndThenLocation", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class Precompiles_XcmInterface_sol_XCM__factory { + static readonly abi = _abi; + static createInterface(): Precompiles_XcmInterface_sol_XCMInterface { + return new Interface(_abi) as Precompiles_XcmInterface_sol_XCMInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): Precompiles_XcmInterface_sol_XCM { + return new Contract( + address, + _abi, + runner + ) as unknown as Precompiles_XcmInterface_sol_XCM; + } +} diff --git a/web/packages/integrations/moonbeam/src/bindings/factories/Precompiles_XcmUtil_sol_XcmUtils__factory.ts b/web/packages/integrations/moonbeam/src/bindings/factories/Precompiles_XcmUtil_sol_XcmUtils__factory.ts new file mode 100644 index 0000000000..b89945c48c --- /dev/null +++ b/web/packages/integrations/moonbeam/src/bindings/factories/Precompiles_XcmUtil_sol_XcmUtils__factory.ts @@ -0,0 +1,158 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + Precompiles_XcmUtil_sol_XcmUtils, + Precompiles_XcmUtil_sol_XcmUtilsInterface, +} from "../Precompiles_XcmUtil_sol_XcmUtils"; + +const _abi = [ + { + inputs: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XcmUtils.Multilocation", + name: "multilocation", + type: "tuple", + }, + ], + name: "getUnitsPerSecond", + outputs: [ + { + internalType: "uint256", + name: "unitsPerSecond", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XcmUtils.Multilocation", + name: "multilocation", + type: "tuple", + }, + ], + name: "multilocationToAddress", + outputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "message", + type: "bytes", + }, + ], + name: "weightMessage", + outputs: [ + { + internalType: "uint64", + name: "weight", + type: "uint64", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "message", + type: "bytes", + }, + { + internalType: "uint64", + name: "maxWeight", + type: "uint64", + }, + ], + name: "xcmExecute", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint8", + name: "parents", + type: "uint8", + }, + { + internalType: "bytes[]", + name: "interior", + type: "bytes[]", + }, + ], + internalType: "struct XcmUtils.Multilocation", + name: "dest", + type: "tuple", + }, + { + internalType: "bytes", + name: "message", + type: "bytes", + }, + ], + name: "xcmSend", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class Precompiles_XcmUtil_sol_XcmUtils__factory { + static readonly abi = _abi; + static createInterface(): Precompiles_XcmUtil_sol_XcmUtilsInterface { + return new Interface(_abi) as Precompiles_XcmUtil_sol_XcmUtilsInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): Precompiles_XcmUtil_sol_XcmUtils { + return new Contract( + address, + _abi, + runner + ) as unknown as Precompiles_XcmUtil_sol_XcmUtils; + } +} diff --git a/web/packages/integrations/moonbeam/src/bindings/factories/index.ts b/web/packages/integrations/moonbeam/src/bindings/factories/index.ts new file mode 100644 index 0000000000..619a3019e6 --- /dev/null +++ b/web/packages/integrations/moonbeam/src/bindings/factories/index.ts @@ -0,0 +1,5 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { Precompiles_XcmInterface_sol_XCM__factory } from "./Precompiles_XcmInterface_sol_XCM__factory"; +export { Precompiles_XcmUtil_sol_XcmUtils__factory } from "./Precompiles_XcmUtil_sol_XcmUtils__factory"; diff --git a/web/packages/integrations/moonbeam/src/bindings/index.ts b/web/packages/integrations/moonbeam/src/bindings/index.ts new file mode 100644 index 0000000000..47d1448e60 --- /dev/null +++ b/web/packages/integrations/moonbeam/src/bindings/index.ts @@ -0,0 +1,8 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { Precompiles_XcmInterface_sol_XCM, XCM } from "./Precompiles_XcmInterface_sol_XCM" +export type { Precompiles_XcmUtil_sol_XcmUtils } from "./Precompiles_XcmUtil_sol_XcmUtils" +export * as factories from "./factories" +export { Precompiles_XcmInterface_sol_XCM__factory } from "./factories/Precompiles_XcmInterface_sol_XCM__factory" +export { Precompiles_XcmUtil_sol_XcmUtils__factory } from "./factories/Precompiles_XcmUtil_sol_XcmUtils__factory" diff --git a/web/packages/integrations/moonbeam/src/index.ts b/web/packages/integrations/moonbeam/src/index.ts new file mode 100644 index 0000000000..d020093646 --- /dev/null +++ b/web/packages/integrations/moonbeam/src/index.ts @@ -0,0 +1,190 @@ +import { ApiPromise } from "@polkadot/api" +import { blake2AsHex, xxhashAsHex } from "@polkadot/util-crypto" +import { BigNumberish, BytesLike, Wallet } from "ethers" +import { Precompiles_XcmInterface_sol_XCM__factory, XCM } from "./bindings" +import { BN, numberToHex } from "@polkadot/util" +import { Codec } from "@polkadot/types/types" + +// /~https://github.com/moonbeam-foundation/moonbeam/blob/b2b1bde7ced13aad4bd2928effc415c521fd48cb/runtime/moonbeam/src/precompiles.rs#L281 +const xcmInterfacePrecompile = "0x000000000000000000000000000000000000081A" +const ETH_CHAIN_ID = process.env["ETH_CHAIN_ID"] || 1 +const TokenPairs = [ + { + id: "WETH", + address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + xc20Address: "0xfFffFFFF86829AFE1521AD2296719DF3ACE8DED7", + }, + { + id: "WBTC", + address: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", + xc20Address: "0xfFffFFFf1B4Bb1ac5749F73D866FfC91a3432c47", + }, + { + id: "wstETH", + address: "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0", + xc20Address: "0xFfFFFfFF5D5DEB44BF7278DEE5381BEB24CB6573", + }, +] + +export const executeTransfer = async ( + signer: Wallet, + api: ApiPromise, + assetHubApi: ApiPromise, + xc20TokenAddress: string, + amount: BigNumberish, + beneficiary: string +) => { + let erc20tokenAddress = getERC20TokenAddress(xc20TokenAddress) + if (!erc20tokenAddress) { + throw new Error("token not registed") + } + const xcmInterface = Precompiles_XcmInterface_sol_XCM__factory.connect( + xcmInterfacePrecompile, + signer + ) + + const BRIDGE_LOCATION = { + parents: 2, + interior: { + X1: [{ GlobalConsensus: { Ethereum: { chain_id: ETH_CHAIN_ID } } }], + }, + } + const ERC20_TOKEN_LOCATION = { + parents: 2, + interior: { + X2: [ + { GlobalConsensus: { Ethereum: { chain_id: ETH_CHAIN_ID } } }, + { AccountKey20: { key: erc20tokenAddress } }, + ], + }, + } + const ERC20_TOKEN_LOCATION_REANCHORED = { + parents: 0, + interior: { X1: [{ AccountKey20: { key: erc20tokenAddress } }] }, + } + + // Reference https://moonbeam.subscan.io/extrinsic/8501143-6 + const customXcm = [ + // Initiate the bridged transfer + { + initiateReserveWithdraw: { + assets: { + Wild: { + AllOf: { id: ERC20_TOKEN_LOCATION, fun: "Fungible" }, + }, + }, + reserve: BRIDGE_LOCATION, + xcm: [ + { + buyExecution: { + fees: { + id: ERC20_TOKEN_LOCATION_REANCHORED, // CAUTION: Must use reanchored locations. + fun: { + Fungible: "1", // Offering 1 unit as fee, but it is returned to the destination address. + }, + }, + weight_limit: "Unlimited", + }, + }, + { + depositAsset: { + assets: { + Wild: { + AllCounted: 1, + }, + }, + beneficiary: { + parents: 0, + interior: { x1: [{ AccountKey20: { key: beneficiary } }] }, + }, + }, + }, + { + setTopic: + "0x0000000000000000000000000000000000000000000000000000000000000000", + }, + ], + }, + }, + { + setTopic: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, + ] + // Update messageId in setTopic for remote tracing + const xcmHash = assetHubApi.createType("Xcm", customXcm) + const sender = await signer.getAddress() + const [parachainId, accountNextId] = await Promise.all([ + api.query.parachainInfo.parachainId(), + api.rpc.system.accountNextIndex(sender), + ]) + const entropy = new Uint8Array([ + ...parachainId.toU8a(), + ...accountNextId.toU8a(), + ...xcmHash.toU8a(), + ]) + const messageId = blake2AsHex(entropy) + customXcm[0].initiateReserveWithdraw!.xcm[2].setTopic = messageId + customXcm[1].setTopic = messageId + const xcmOnDest = assetHubApi.createType("XcmVersionedXcm", { + V4: customXcm, + }) + let customXcmOnDest: BytesLike = xcmOnDest.toHex() + + let token: XCM.AssetAddressInfoStruct = { + asset: xc20TokenAddress, + amount, + } + // Fee always in xcDOT + const transfer_bridge_fee: bigint = await getSendFee(assetHubApi) + const transfer_assethub_execution_fee = 3500000000n + const transfer_fee = (transfer_bridge_fee + transfer_assethub_execution_fee).toString() + let fee: XCM.AssetAddressInfoStruct = { + asset: "0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080", + amount: transfer_fee, + } + + // This represents (1,X1(Parachain(1000))) + const paraIdInHex = numberToHex(1000, 32) + const parachain_enum_selector = "0x00" + let dest: XCM.LocationStruct = { + parents: 1, + interior: [parachain_enum_selector + paraIdInHex.slice(2)], + } + let assets: XCM.AssetAddressInfoStruct[] = [fee, token] + // DestinationReserve for the asset + let assetTransferType: BigNumberish = 2n + // Fee as first asset + let remoteFeesIdIndex: BigNumberish = 0n + // DestinationReserve for the fee + let feesTransferType: BigNumberish = 2n + + /* Execute the custom XCM message */ + const tx = await xcmInterface[ + "transferAssetsUsingTypeAndThenAddress((uint8,bytes[]),(address,uint256)[],uint8,uint8,uint8,bytes)" + ](dest, assets, assetTransferType, remoteFeesIdIndex, feesTransferType, customXcmOnDest) + await tx.wait() + console.log(`Transaction receipt: ${tx.hash}`) +} + +const getSendFee = async ( + assetHub: ApiPromise, + options = { + defaultFee: 65_000_000_000, //6.5 DOT by default + } +): Promise => { + // Fees stored in 0x5fbc5c7ba58845ad1f1a9a7c5bc12fad + const feeStorageKey = xxhashAsHex(":BridgeHubEthereumBaseFee:", 128, true) + const feeStorageItem = await assetHub.rpc.state.getStorage(feeStorageKey) + const leFee = new BN((feeStorageItem as Codec).toHex().replace("0x", ""), "hex", "le") + return leFee.eqn(0) ? BigInt(options.defaultFee) : BigInt(leFee.toString()) +} + +// Todo: From on-chain storage assetManager.assetIdType +const getERC20TokenAddress = (xc20TokenAddress: string): string => { + for (let entry of TokenPairs) { + if (entry.xc20Address.toLowerCase() == xc20TokenAddress.toLowerCase()) { + return entry.address + } + } + return "" +} diff --git a/web/packages/integrations/moonbeam/src/testTransfer.ts b/web/packages/integrations/moonbeam/src/testTransfer.ts new file mode 100644 index 0000000000..1dbb71481e --- /dev/null +++ b/web/packages/integrations/moonbeam/src/testTransfer.ts @@ -0,0 +1,36 @@ +import "dotenv/config" +import { executeTransfer } from "./index" +import { ethers } from "ethers" +import { WsProvider, ApiPromise } from "@polkadot/api" + +// XC20 address referenced from the list in https://docs.moonbeam.network/builders/interoperability/xcm/xc20/overview/ +const xc20TokenAddress = "0xfFffFFFF86829AFE1521AD2296719DF3ACE8DED7".toLowerCase() + +// beneficiary +const beneficiary = process.env["BENEFICIARY"] || "0x302F0B71B8aD3CF6dD90aDb668E49b2168d652fd" + +// Private key of the ethereum signer +const privateKey = process.env["PRIVATE_KEY"] || "INSERT_YOUR_PRIVATE_KEY" + +const ethereumProviderURL = process.env["MOONBEAM_URL"] || "https://rpc.api.moonbeam.network" +const ASSETHUB_WS_URL = process.env["ASSETHUB_WS_URL"] || "wss://asset-hub-polkadot-rpc.dwellir.com" +const MOONBEAM_WS_URL = process.env["MOONBEAM_WS_URL"] || "wss://moonbeam-rpc.n.dwellir.com" + +const run = async () => { + const provider = new ethers.JsonRpcProvider(ethereumProviderURL) + const signer = new ethers.Wallet(privateKey, provider) + const api = await ApiPromise.create({ provider: new WsProvider(MOONBEAM_WS_URL) }) + const assetHubApi = await ApiPromise.create({ + provider: new WsProvider(ASSETHUB_WS_URL), + }) + // 0.001 WETH + const amount = 1000000000000000 + await executeTransfer(signer, api, assetHubApi, xc20TokenAddress, amount, beneficiary) +} + +run() + .then(() => process.exit(0)) + .catch((error) => { + console.error("Error:", error) + process.exit(1) + }) diff --git a/web/packages/integrations/moonbeam/tsconfig.json b/web/packages/integrations/moonbeam/tsconfig.json new file mode 100644 index 0000000000..f888dc1677 --- /dev/null +++ b/web/packages/integrations/moonbeam/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "composite": true, + "target": "es2021", + "module": "commonjs", + "strict": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "outDir": "dist", + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationMap": true, + "baseUrl": ".", + "rootDir": "src", + "noEmitOnError": true, + "skipLibCheck": true, + "allowJs": true, + "lib": ["es6", "esnext.bigint"] + }, + "ts-node": { + "require": ["tsconfig-paths/register"] + }, + "exclude": ["node_modules", "dist"], + "include": ["src/**/*.ts"], + "references": [] +} diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index de34a2bfb7..4a21ac5718 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: devDependencies: '@remix-project/remixd': specifier: ^0.6.14 - version: 0.6.36(typescript@5.5.4)(zod@3.23.8) + version: 0.6.36(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@22.7.5)(typescript@5.5.4) @@ -104,6 +104,54 @@ importers: specifier: ^5.4.5 version: 5.5.4 + packages/contracts: {} + + packages/integrations/moonbeam: + dependencies: + '@polkadot/api': + specifier: ^14.3.1 + version: 14.3.1 + '@polkadot/keyring': + specifier: ^13.2.3 + version: 13.3.1(@polkadot/util-crypto@13.3.1(@polkadot/util@13.3.1))(@polkadot/util@13.3.1) + '@polkadot/types': + specifier: ^14.3.1 + version: 14.3.1 + '@polkadot/util': + specifier: ^13.2.3 + version: 13.3.1 + '@polkadot/util-crypto': + specifier: ^13.2.3 + version: 13.3.1(@polkadot/util@13.3.1) + '@typechain/ethers-v6': + specifier: ^0.5.1 + version: 0.5.1(ethers@6.13.5)(typechain@8.3.2(typescript@5.5.4))(typescript@5.5.4) + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + ethers: + specifier: ^6.13.5 + version: 6.13.5 + devDependencies: + prettier: + specifier: ^2.8.8 + version: 2.8.8 + solc: + specifier: ^0.8.28 + version: 0.8.28 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@22.7.5)(typescript@5.5.4) + tsconfig-paths: + specifier: ^4.2.0 + version: 4.2.0 + typechain: + specifier: ^8.3.2 + version: 8.3.2(typescript@5.5.4) + typescript: + specifier: ^5.4.5 + version: 5.5.4 + packages/operations: dependencies: '@aws-sdk/client-cloudwatch': @@ -1681,6 +1729,10 @@ packages: resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} engines: {node: '>= 6'} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + commander@9.5.0: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} @@ -1840,6 +1892,9 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -3209,6 +3264,11 @@ packages: engines: {node: '>=8.0.0'} hasBin: true + solc@0.8.28: + resolution: {integrity: sha512-AFCiJ+b4RosyyNhnfdVH4ZR1+TxiL91iluPjw0EJslIu4LXGM9NYqi2z5y8TqochC4tcH9QsHfwWhOIC9jPDKA==} + engines: {node: '>=10.0.0'} + hasBin: true + sonic-boom@4.0.1: resolution: {integrity: sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==} @@ -5167,7 +5227,7 @@ snapshots: '@protobufjs/utf8@1.1.0': {} - '@remix-project/remix-lib@0.5.63(typescript@5.5.4)(zod@3.23.8)': + '@remix-project/remix-lib@0.5.63(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8)': dependencies: '@ethereumjs/util': 9.1.0 async: 2.6.4 @@ -5179,7 +5239,7 @@ snapshots: rlp: 3.0.0 solc: 0.7.6 string-similarity: 4.0.4 - web3: 4.11.1(typescript@5.5.4)(zod@3.23.8) + web3: 4.11.1(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) web3-validator: 2.0.6 transitivePeerDependencies: - bufferutil @@ -5189,13 +5249,13 @@ snapshots: - utf-8-validate - zod - '@remix-project/remix-solidity@0.5.42(typescript@5.5.4)(zod@3.23.8)': + '@remix-project/remix-solidity@0.5.42(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8)': dependencies: '@ethereumjs/block': 5.3.0 '@ethereumjs/tx': 5.4.0 '@ethereumjs/util': 9.1.0 '@ethereumjs/vm': 8.1.0 - '@remix-project/remix-lib': 0.5.63(typescript@5.5.4)(zod@3.23.8) + '@remix-project/remix-lib': 0.5.63(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) async: 2.6.4 eslint-scope: 5.1.1 ethers: 5.7.2 @@ -5204,7 +5264,7 @@ snapshots: semver: 6.3.1 solc: 0.7.6 string-similarity: 4.0.4 - web3: 4.11.1(typescript@5.5.4)(zod@3.23.8) + web3: 4.11.1(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) webworkify-webpack: 2.1.5 transitivePeerDependencies: - bufferutil @@ -5215,9 +5275,9 @@ snapshots: - utf-8-validate - zod - '@remix-project/remixd@0.6.36(typescript@5.5.4)(zod@3.23.8)': + '@remix-project/remixd@0.6.36(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8)': dependencies: - '@remix-project/remix-solidity': 0.5.42(typescript@5.5.4)(zod@3.23.8) + '@remix-project/remix-solidity': 0.5.42(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) '@remixproject/plugin': 0.3.33 '@remixproject/plugin-api': 0.3.33 '@remixproject/plugin-utils': 0.3.33 @@ -6234,6 +6294,8 @@ snapshots: commander@5.1.0: {} + commander@8.3.0: {} + commander@9.5.0: {} component-emitter@1.3.1: {} @@ -6258,9 +6320,9 @@ snapshots: create-require@1.1.1: {} - cross-fetch@4.0.0: + cross-fetch@4.0.0(encoding@0.1.13): dependencies: - node-fetch: 2.7.0 + node-fetch: 2.7.0(encoding@0.1.13) transitivePeerDependencies: - encoding @@ -6379,6 +6441,11 @@ snapshots: emoji-regex@8.0.0: {} + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -7446,9 +7513,11 @@ snapshots: node-domexception@1.0.0: {} - node-fetch@2.7.0: + node-fetch@2.7.0(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 node-fetch@3.3.2: dependencies: @@ -7898,6 +7967,18 @@ snapshots: transitivePeerDependencies: - debug + solc@0.8.28: + dependencies: + command-exists: 1.2.9 + commander: 8.3.0 + follow-redirects: 1.15.6 + js-sha3: 0.8.0 + memorystream: 0.3.1 + semver: 5.7.2 + tmp: 0.0.33 + transitivePeerDependencies: + - debug + sonic-boom@4.0.1: dependencies: atomic-sleep: 1.0.0 @@ -8239,12 +8320,12 @@ snapshots: web-streams-polyfill@3.3.3: {} - web3-core@4.5.0: + web3-core@4.5.0(encoding@0.1.13): dependencies: web3-errors: 1.2.1 web3-eth-accounts: 4.1.3 web3-eth-iban: 4.0.7 - web3-providers-http: 4.1.0 + web3-providers-http: 4.1.0(encoding@0.1.13) web3-providers-ws: 4.0.8 web3-types: 1.7.0 web3-utils: 4.3.1 @@ -8281,12 +8362,12 @@ snapshots: web3-utils: 4.3.1 web3-validator: 2.0.6 - web3-eth-contract@4.6.0(typescript@5.5.4)(zod@3.23.8): + web3-eth-contract@4.6.0(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8): dependencies: '@ethereumjs/rlp': 5.0.2 - web3-core: 4.5.0 + web3-core: 4.5.0(encoding@0.1.13) web3-errors: 1.2.1 - web3-eth: 4.8.2(typescript@5.5.4)(zod@3.23.8) + web3-eth: 4.8.2(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) web3-eth-abi: 4.2.3(typescript@5.5.4)(zod@3.23.8) web3-types: 1.7.0 web3-utils: 4.3.1 @@ -8298,14 +8379,14 @@ snapshots: - utf-8-validate - zod - web3-eth-ens@4.4.0(typescript@5.5.4)(zod@3.23.8): + web3-eth-ens@4.4.0(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8): dependencies: '@adraffy/ens-normalize': 1.10.1 - web3-core: 4.5.0 + web3-core: 4.5.0(encoding@0.1.13) web3-errors: 1.2.1 - web3-eth: 4.8.2(typescript@5.5.4)(zod@3.23.8) - web3-eth-contract: 4.6.0(typescript@5.5.4)(zod@3.23.8) - web3-net: 4.1.0 + web3-eth: 4.8.2(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) + web3-eth-contract: 4.6.0(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) + web3-net: 4.1.0(encoding@0.1.13) web3-types: 1.7.0 web3-utils: 4.3.1 web3-validator: 2.0.6 @@ -8323,11 +8404,11 @@ snapshots: web3-utils: 4.3.1 web3-validator: 2.0.6 - web3-eth-personal@4.0.8(typescript@5.5.4)(zod@3.23.8): + web3-eth-personal@4.0.8(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8): dependencies: - web3-core: 4.5.0 - web3-eth: 4.8.2(typescript@5.5.4)(zod@3.23.8) - web3-rpc-methods: 1.3.0 + web3-core: 4.5.0(encoding@0.1.13) + web3-eth: 4.8.2(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) + web3-rpc-methods: 1.3.0(encoding@0.1.13) web3-types: 1.7.0 web3-utils: 4.3.1 web3-validator: 2.0.6 @@ -8338,16 +8419,16 @@ snapshots: - utf-8-validate - zod - web3-eth@4.8.2(typescript@5.5.4)(zod@3.23.8): + web3-eth@4.8.2(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8): dependencies: setimmediate: 1.0.5 - web3-core: 4.5.0 + web3-core: 4.5.0(encoding@0.1.13) web3-errors: 1.2.1 web3-eth-abi: 4.2.3(typescript@5.5.4)(zod@3.23.8) web3-eth-accounts: 4.1.3 - web3-net: 4.1.0 + web3-net: 4.1.0(encoding@0.1.13) web3-providers-ws: 4.0.8 - web3-rpc-methods: 1.3.0 + web3-rpc-methods: 1.3.0(encoding@0.1.13) web3-types: 1.7.0 web3-utils: 4.3.1 web3-validator: 2.0.6 @@ -8358,10 +8439,10 @@ snapshots: - utf-8-validate - zod - web3-net@4.1.0: + web3-net@4.1.0(encoding@0.1.13): dependencies: - web3-core: 4.5.0 - web3-rpc-methods: 1.3.0 + web3-core: 4.5.0(encoding@0.1.13) + web3-rpc-methods: 1.3.0(encoding@0.1.13) web3-types: 1.7.0 web3-utils: 4.3.1 transitivePeerDependencies: @@ -8369,9 +8450,9 @@ snapshots: - encoding - utf-8-validate - web3-providers-http@4.1.0: + web3-providers-http@4.1.0(encoding@0.1.13): dependencies: - cross-fetch: 4.0.0 + cross-fetch: 4.0.0(encoding@0.1.13) web3-errors: 1.2.1 web3-types: 1.7.0 web3-utils: 4.3.1 @@ -8397,9 +8478,9 @@ snapshots: - bufferutil - utf-8-validate - web3-rpc-methods@1.3.0: + web3-rpc-methods@1.3.0(encoding@0.1.13): dependencies: - web3-core: 4.5.0 + web3-core: 4.5.0(encoding@0.1.13) web3-types: 1.7.0 web3-validator: 2.0.6 transitivePeerDependencies: @@ -8407,10 +8488,10 @@ snapshots: - encoding - utf-8-validate - web3-rpc-providers@1.0.0-rc.1: + web3-rpc-providers@1.0.0-rc.1(encoding@0.1.13): dependencies: web3-errors: 1.2.1 - web3-providers-http: 4.1.0 + web3-providers-http: 4.1.0(encoding@0.1.13) web3-providers-ws: 4.0.8 web3-types: 1.7.0 web3-utils: 4.3.1 @@ -8449,22 +8530,22 @@ snapshots: web3-types: 1.7.0 zod: 3.23.8 - web3@4.11.1(typescript@5.5.4)(zod@3.23.8): + web3@4.11.1(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8): dependencies: - web3-core: 4.5.0 + web3-core: 4.5.0(encoding@0.1.13) web3-errors: 1.2.1 - web3-eth: 4.8.2(typescript@5.5.4)(zod@3.23.8) + web3-eth: 4.8.2(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) web3-eth-abi: 4.2.3(typescript@5.5.4)(zod@3.23.8) web3-eth-accounts: 4.1.3 - web3-eth-contract: 4.6.0(typescript@5.5.4)(zod@3.23.8) - web3-eth-ens: 4.4.0(typescript@5.5.4)(zod@3.23.8) + web3-eth-contract: 4.6.0(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) + web3-eth-ens: 4.4.0(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) web3-eth-iban: 4.0.7 - web3-eth-personal: 4.0.8(typescript@5.5.4)(zod@3.23.8) - web3-net: 4.1.0 - web3-providers-http: 4.1.0 + web3-eth-personal: 4.0.8(encoding@0.1.13)(typescript@5.5.4)(zod@3.23.8) + web3-net: 4.1.0(encoding@0.1.13) + web3-providers-http: 4.1.0(encoding@0.1.13) web3-providers-ws: 4.0.8 - web3-rpc-methods: 1.3.0 - web3-rpc-providers: 1.0.0-rc.1 + web3-rpc-methods: 1.3.0(encoding@0.1.13) + web3-rpc-providers: 1.0.0-rc.1(encoding@0.1.13) web3-types: 1.7.0 web3-utils: 4.3.1 web3-validator: 2.0.6 diff --git a/web/pnpm-workspace.yaml b/web/pnpm-workspace.yaml index 5dba90ce5d..88546fa96a 100644 --- a/web/pnpm-workspace.yaml +++ b/web/pnpm-workspace.yaml @@ -5,3 +5,4 @@ packages: - "packages/contract-types" - "packages/test-helpers" - "packages/operations" + - "packages/integrations/moonbeam"