From 1ece9b3bb747d5e39c36bdc14b34a9e7760abdc5 Mon Sep 17 00:00:00 2001 From: bee344 Date: Mon, 8 Jan 2024 20:21:31 -0300 Subject: [PATCH 01/25] added e2e tests --- .gitignore | 1 + e2e-tests/balance.ts | 98 +++++++++++++++++ e2e-tests/consts.ts | 17 +++ e2e-tests/executor.ts | 156 ++++++++++++++++++++++++++++ e2e-tests/logger.ts | 1 + e2e-tests/tests.sh | 18 ++++ e2e-tests/tests/assets.ts | 72 +++++++++++++ e2e-tests/tests/foreignAssets.ts | 49 +++++++++ e2e-tests/tests/index.ts | 133 ++++++++++++++++++++++++ e2e-tests/tests/liquidPools.ts | 73 +++++++++++++ e2e-tests/tests/local.ts | 101 ++++++++++++++++++ e2e-tests/tsconfig.json | 9 ++ e2e-tests/verification.ts | 20 ++++ e2e-tests/zombienet.sh | 14 +++ package.json | 7 ++ scripts/consts.ts | 1 + scripts/testNetworkForeignAssets.ts | 12 +-- scripts/testNetworkLiquidAssets.ts | 8 +- scripts/testNetworkSetup.ts | 2 +- zombienet/medium-network.toml | 30 ++++-- 20 files changed, 807 insertions(+), 15 deletions(-) create mode 100644 e2e-tests/balance.ts create mode 100644 e2e-tests/consts.ts create mode 100644 e2e-tests/executor.ts create mode 100644 e2e-tests/logger.ts create mode 100755 e2e-tests/tests.sh create mode 100644 e2e-tests/tests/assets.ts create mode 100644 e2e-tests/tests/foreignAssets.ts create mode 100644 e2e-tests/tests/index.ts create mode 100644 e2e-tests/tests/liquidPools.ts create mode 100644 e2e-tests/tests/local.ts create mode 100644 e2e-tests/tsconfig.json create mode 100644 e2e-tests/verification.ts create mode 100755 e2e-tests/zombienet.sh diff --git a/.gitignore b/.gitignore index 9184f2eb..45d0833f 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ zombienet-macos zombienet-linux-arm64 zombienet-linux-x64 zombienet.log +zombienet/bin/* # Binaries /bin/* diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts new file mode 100644 index 00000000..f61824c5 --- /dev/null +++ b/e2e-tests/balance.ts @@ -0,0 +1,98 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +import { ApiPromise } from '@polkadot/api'; +import type { FrameSystemAccountInfo, PalletAssetsAssetAccount } from '@polkadot/types/lookup'; +import type { Option } from '@polkadot/types-codec'; +export interface IBalance { + initial: [string, number][]; + final: [string, number][]; +} + +export const balanceTracker = async ( + api: ApiPromise, + test: string, + address: string, + assetIds: string[], + balance?: IBalance +): Promise => { + let balances: IBalance = { initial: [], final: [] }; + let accountInfo: FrameSystemAccountInfo | Option; + switch (test) { + case '--foreign-assets': + if (!balance) { + for (const assetId of assetIds) { + accountInfo = (await api.query.foreignAssets.account(assetId, address)) as Option; + balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + } + } else { + balances = balance; + for (const assetId of assetIds) { + accountInfo = (await api.query.foreignAssets.account(assetId, address)) as Option; + balances.final.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + } + } + return balances; + case '--liquidity-assets': + if (!balance) { + for (const assetId of assetIds) { + accountInfo = await api.query.poolAssets.account(assetId, address); + balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + } + } else { + balances = balance; + for (const assetId of assetIds) { + accountInfo = await api.query.poolAssets.account(assetId, address); + balances.final.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + } + } + return balances; + case '--local': + if (!balance) { + accountInfo = await api.query.system.account(address); + balances.initial.push(['0', accountInfo.data.free.toBn().toNumber()]); + } else { + balances = balance; + accountInfo = await api.query.system.account(address); + balances.final.push(['0', accountInfo.data.free.toBn().toNumber()]); + } + return balances; + case '--assets': + if (!balance) { + for (const assetId of assetIds) { + accountInfo = await api.query.assets.account(assetId, address); + if (accountInfo.valueOf() == null) { + balances.initial.push([assetId, 0]); + } else { + balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + } + } + } else { + balances = balance; + for (const assetId of assetIds) { + accountInfo = await api.query.assets.account(assetId, address); + balances.final.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + + } + } + return balances; + default: + if (!balance) { + for (const assetId of assetIds) { + accountInfo = await api.query.system.account(address); + if (accountInfo) { + balances.initial.push([assetId, accountInfo.data.free.toBn().toNumber()]); + } else { + balances.initial.push([assetId, 0]); + + } + } + } else { + balances = balance; + for (const assetId of assetIds) { + accountInfo = await api.query.system.account(address); + balances.final.push([assetId, accountInfo.data.free.toBn().toNumber()]); + } + } + return balances; + } +}; diff --git a/e2e-tests/consts.ts b/e2e-tests/consts.ts new file mode 100644 index 00000000..4424070e --- /dev/null +++ b/e2e-tests/consts.ts @@ -0,0 +1,17 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; +export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; +export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; +export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; + +export const BOB_ROC_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; +export const FERDE_ROC_ADDR = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; +export const BOB_KAH_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; +export const FERDE_KAH_ADDR = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; + +export const ASSET_ID = 1; + +export const MOONRIVER_ADDR = '5Eg2fnt8QeGtg4mcc5ELxPx6qxP2FSEWHbbYXENZ17ormkGP'; +export const TRAPPIST_ADDR = '5Eg2fntDDP4P8TjqRg3Jq89y5boE26JUMM3D7VU3bCAp76nc'; +export const ASSET_HUB_ADDR = '5Eg2fntNprdN3FgH4sfEaaZhYtddZQSQUqvYJ1f2mLtinVhV'; diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts new file mode 100644 index 00000000..0d3545fb --- /dev/null +++ b/e2e-tests/executor.ts @@ -0,0 +1,156 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +import { ApiPromise, WsProvider } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +// import { KeyringPair } from '@polkadot/keyring/types'; +import { cryptoWaitReady } from '@polkadot/util-crypto'; + +import { constructApiPromise } from '../src'; +import { balanceTracker, IBalance } from './balance'; +import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; +import { assetTests, foreignAssetsTests, IndividualTest, liquidPoolsTests, localTests, tests } from './tests'; +import { verification } from './verification'; +import { delay } from '../scripts/util' + +const executor = async (testCase: string) => { + let originWsUrl = ''; + let destWsUrl = ''; + + let testData: IndividualTest[] = []; + + await cryptoWaitReady(); + + const keyring = new Keyring({ type: 'sr25519' }); + + switch (testCase) { + case '--foreign-assets': + testData = tests.foreignAssets; + break; + case '--liquidity-assets': + testData = tests.liquidPools; + break; + case '--local': + testData = tests.local; + break; + case '--assets': + testData = tests.assets; + break; + } + + let n: { [K: string]: Function } = {}; + + switch (testCase) { + case '--foreign-assets': + n = foreignAssetsTests; + break; + case '--liquidity-assets': + n = liquidPoolsTests; + break; + case '--local': + n = localTests; + break; + case '--assets': + n = assetTests; + break; + } + console.log(n) + + let originChainId = ''; + let destChainId = ''; + let originAddr = ''; + let destAddr = ''; + let assetIds: string[] = []; + let amounts: string[] = []; + let opts: object = {}; + + for (const t of testData) { + + originChainId = t.args[0]; + destChainId = t.args[1]; + originAddr = t.args[2]; + destAddr = t.args[3]; + assetIds = t.args[4].slice(1, -1).split(','); + amounts = t.args[5].slice(1, -1).split(','); + opts = JSON.parse(t.args[6]); + + switch (originChainId) { + case '0': + originWsUrl = ROCOCO_ALICE_WS_URL; + break; + case '1000': + originWsUrl = KUSAMA_ASSET_HUB_WS_URL; + break; + case '2500': + originWsUrl = TRAPPIST_WS_URL; + break; + case '2600': + originWsUrl = MOONRIVER_WS_URL; + break; + } + + if (originChainId == destChainId) { + destWsUrl = originWsUrl; + } else { + switch (destChainId) { + case '0': + destWsUrl = ROCOCO_ALICE_WS_URL; + break; + case '1000': + destWsUrl = KUSAMA_ASSET_HUB_WS_URL; + break; + case '2500': + destWsUrl = TRAPPIST_WS_URL; + break; + case '2600': + destWsUrl = MOONRIVER_WS_URL; + break; + } + } + const { api, specName, safeXcmVersion } = await constructApiPromise(originWsUrl); + + await api.isReady; + + const originApi = api; + const destinationApi = + originChainId == destChainId + ? originApi + : await ApiPromise.create({ + provider: new WsProvider(destWsUrl), + noInitWarn: true, + }); + + await destinationApi.isReady; + let destInitialBalance: IBalance = await balanceTracker(destinationApi, testCase, destAddr, assetIds); + const originKeyring = keyring.addFromUri(originAddr); + + //eslint-disable-next-line @typescript-eslint/no-unsafe-call + await n[t.test](originKeyring, destChainId, destAddr, assetIds, amounts, opts, api, specName, safeXcmVersion); + + await delay(24000); + + let destFinalBalance: IBalance = await balanceTracker( + destinationApi, + testCase, + destAddr, + assetIds, + destInitialBalance + ); + + const correctlyReceived = verification(assetIds, amounts, destFinalBalance); + + for (let i = 0; i < assetIds.length; i++) { + if (correctlyReceived[i][1]) { + console.log('all good'); + } else { + console.log('badd'); + } + } + + await delay(12000); + + originApi.disconnect(); + destinationApi.disconnect(); + } + +}; + +executor(process.argv[2]).finally(() => process.exit()); diff --git a/e2e-tests/logger.ts b/e2e-tests/logger.ts new file mode 100644 index 00000000..c9193b86 --- /dev/null +++ b/e2e-tests/logger.ts @@ -0,0 +1 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. diff --git a/e2e-tests/tests.sh b/e2e-tests/tests.sh new file mode 100755 index 00000000..489aee7b --- /dev/null +++ b/e2e-tests/tests.sh @@ -0,0 +1,18 @@ +#!/bin/sh +test=$1 +yarn run build:e2e && +if [ $test = '--assets' ]; then + script=post +elif [ $test = '--local' ]; then + script=post +elif [ $test = '--liquidity-assets' ]; then + script=liquidity-assets +elif [ $test = '--foreign-assets' ]; then + script=foreign-assets +fi + +yarn run start:zombienet-$script-script + +sleep 24 + +node ./e2e-tests/build/e2e-tests/executor.js $test diff --git a/e2e-tests/tests/assets.ts b/e2e-tests/tests/assets.ts new file mode 100644 index 00000000..8759e9fc --- /dev/null +++ b/e2e-tests/tests/assets.ts @@ -0,0 +1,72 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +import { ApiPromise } from '@polkadot/api'; +import { KeyringPair } from '@polkadot/keyring/types'; + +import { AssetTransferApi } from '../../src'; +import { TxResult } from '../../src/types'; + +const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { + const injectedRegistry = { + rococo: { + '2500': { + tokens: ['HOP'], + assetsInfo: {}, + foreignAssetsInfo: {}, + specName: 'trappist-rococo', + poolPairsInfo: {}, + }, + }, + }; + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { + injectedRegistry, + }); + + return assetApi; +}; + +const createLocalSystemAssetsTransferTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransfer: TxResult<'submittable'>; + try { + localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + await localTransfer.tx.signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +const createPayFeesTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransfer: TxResult<'submittable'>; + try { + localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + await localTransfer.tx.signAndSend(origin) + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; +export const assetTests: { [K: string]: Function } = { createLocalSystemAssetsTransferTransaction, createPayFeesTransaction }; diff --git a/e2e-tests/tests/foreignAssets.ts b/e2e-tests/tests/foreignAssets.ts new file mode 100644 index 00000000..133aeb75 --- /dev/null +++ b/e2e-tests/tests/foreignAssets.ts @@ -0,0 +1,49 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +import { ApiPromise } from '@polkadot/api'; +import { KeyringPair } from '@polkadot/keyring/types'; + +import { AssetTransferApi } from '../../src'; +import { TxResult } from '../../src/types'; + +const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { + const injectedRegistry = { + kusama: { + '3000': { + tokens: ['HOP'], + assetsInfo: {}, + foreignAssetsInfo: {}, + specName: 'trappist', + poolPairsInfo: {}, + }, + }, + }; + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { + injectedRegistry, + }); + + return assetApi; +}; + +const createTransferTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransfer: TxResult<'submittable'>; + try { + localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + await localTransfer.tx.signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; +export const foreignAssetsTests: { [K: string]: Function } = { createTransferTransaction }; diff --git a/e2e-tests/tests/index.ts b/e2e-tests/tests/index.ts new file mode 100644 index 00000000..8a010038 --- /dev/null +++ b/e2e-tests/tests/index.ts @@ -0,0 +1,133 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +export { assetTests } from './assets'; +export { foreignAssetsTests } from './foreignAssets'; +export { liquidPoolsTests } from './liquidPools'; +export { localTests } from './local'; +import { BOB_KAH_ADDR, BOB_ROC_ADDR, FERDE_KAH_ADDR } from '../consts'; + +export interface IndividualTest { + test: string; + args: string[]; + verification: string[]; +} + +export interface TestGroups { + foreignAssets: IndividualTest[]; + liquidPools: IndividualTest[]; + assets: IndividualTest[]; + local: IndividualTest[]; +} + +export const tests: TestGroups = { + foreignAssets: [ + { + // This will declare the call to use + test: 'createTransferTransactionCall', + // This will be all the args for the above call + args: [ + '2500', + '1000', + '//Alice', + BOB_KAH_ADDR, + '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "2500" }, { "GeneralIndex": "0" }]}}]', + '[200000000000]', + '{ "format": "submittable", "xcmVersion": 3 }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['', ''], + }, + ], + liquidPools: [ + { + // This will declare the call to use + test: 'createLocalTransferTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Alice', + BOB_KAH_ADDR, + '[0]', + '[2000]', + '{ "format": "submittable", "transferLiquidToken": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[0]', '[2000]'], + }, + { + // This will declare the call to use + test: 'createPayFeesTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Alice', + BOB_KAH_ADDR, + '[0]', + '[30000]', + '{ "format": "submittable", "transferLiquidToken": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[0]', '[30000]'], + }, + ], + local: [ + { + // This will declare the call to use + test: 'createSystemLocalTransferTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Alice', + BOB_KAH_ADDR, + '[]', + '[10000000000000]', + '{ "format": "submittable", "keepAlive": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[0]', '[10000000000000]'], + } + ], + assets: [ + { + // This will declare the call to use + test: 'createLocalSystemAssetsTransferTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Alice', + BOB_ROC_ADDR, + '[1]', + '[3000000000000]', + '{ "format": "submittable", "keepAlive": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[1]', '[30000]'], + }, + { + // This will declare the call to use + test: 'createPayFeesTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Bob', + FERDE_KAH_ADDR, + '[1]', + '[200000000000]', + '{ "format": "submittable", "keepAlive": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[1]', '[2000]'], + }, + ], +}; diff --git a/e2e-tests/tests/liquidPools.ts b/e2e-tests/tests/liquidPools.ts new file mode 100644 index 00000000..74b69e23 --- /dev/null +++ b/e2e-tests/tests/liquidPools.ts @@ -0,0 +1,73 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +import { ApiPromise } from '@polkadot/api'; +import { KeyringPair } from '@polkadot/keyring/types'; + +import { AssetTransferApi } from '../../src'; +import { TxResult } from '../../src/types'; + +const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { + const injectedRegistry = { + kusama: { + '3000': { + tokens: ['HOP'], + assetsInfo: {}, + foreignAssetsInfo: {}, + specName: 'trappist', + poolPairsInfo: {}, + }, + }, + }; + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { + injectedRegistry, + }); + + return assetApi; +}; + +const createLocalTransferTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'submittable'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + await localTransferInfo.tx.signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +const createPayFeesTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'submittable'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + await localTransferInfo.tx.signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +export const liquidPoolsTests: { [K: string]: Function } = { createLocalTransferTransaction, createPayFeesTransaction }; diff --git a/e2e-tests/tests/local.ts b/e2e-tests/tests/local.ts new file mode 100644 index 00000000..78689811 --- /dev/null +++ b/e2e-tests/tests/local.ts @@ -0,0 +1,101 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +import { ApiPromise } from '@polkadot/api'; +import { KeyringPair } from '@polkadot/keyring/types'; + +import { AssetTransferApi } from '../../src'; +import { TxResult } from '../../src/types'; + +const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { + const injectedRegistry = { + kusama: { + '3000': { + tokens: ['HOP'], + assetsInfo: {}, + foreignAssetsInfo: {}, + specName: 'trappist', + poolPairsInfo: {}, + }, + }, + }; + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { + injectedRegistry, + }); + + return assetApi; +}; + +const createSystemLocalTransferTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'submittable'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + await localTransferInfo.tx.signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +const createRelayLocalTransferTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'submittable'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + await localTransferInfo.tx.signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +const createRelayToSystemTransferTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'submittable'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + await localTransferInfo.tx.signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +export const localTests: { [K: string]: Function } = { + createSystemLocalTransferTransaction, + createRelayLocalTransferTransaction, + createRelayToSystemTransferTransaction, +}; diff --git a/e2e-tests/tsconfig.json b/e2e-tests/tsconfig.json new file mode 100644 index 00000000..b3d794f0 --- /dev/null +++ b/e2e-tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@substrate/dev/config/tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "suppressImplicitAnyIndexErrors": true, + "resolveJsonModule": true, + }, +} diff --git a/e2e-tests/verification.ts b/e2e-tests/verification.ts new file mode 100644 index 00000000..c58a47c8 --- /dev/null +++ b/e2e-tests/verification.ts @@ -0,0 +1,20 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +import { IBalance } from 'balance'; + +export const verification = (assetIds: string[], amounts: string[], destBalance: IBalance) => { + const destInitialBalance: [string, number][] = destBalance.initial; + const destFinalBalance: [string, number][] = destBalance.final; + const correctlyReceived: [string, boolean][] = []; + console.log(destInitialBalance) + console.log(destFinalBalance) + + let check: boolean = true; + for (let i = 0; i < assetIds.length; i++) { + check = + destInitialBalance[i][1] + Number(amounts[i]) == + destFinalBalance[i][1]; + correctlyReceived.push([destInitialBalance[i][0], check]); + } + + return correctlyReceived; +}; diff --git a/e2e-tests/zombienet.sh b/e2e-tests/zombienet.sh new file mode 100755 index 00000000..0bcb857c --- /dev/null +++ b/e2e-tests/zombienet.sh @@ -0,0 +1,14 @@ +#!/bin/sh +if [ $(uname) = 'Darwin' ]; then + os='zombienet-macOS' +elif [ $(uname) = 'Linux' ]; then + if [ $(uname -m) = 'x86_64' ]; then + os='zombienet-linux-x64' + elif [ $(uname -m) = 'arm64' ]; then + os='zombienet-linux-arm64' + fi +fi + +sed -i 's="./zombienet/zombienet": .*"="./zombienet/zombienet": "'$os' -p native spawn ./zombienet/medium-network.toml"=' package.json + +yarn run zombienet \ No newline at end of file diff --git a/package.json b/package.json index 5ddd00e7..349a0e17 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,17 @@ "build": "substrate-exec-rimraf ./lib && substrate-exec-tsc", "build:scripts": "substrate-exec-rimraf scripts/build/ && substrate-exec-tsc --project scripts/tsconfig.json", "build:examples": "substrate-exec-rimraf examples/build/ && substrate-exec-tsc --project examples/tsconfig.json", + "build:e2e": "substrate-exec-rimraf e2e-tests/build/ && substrate-exec-tsc --project e2e-tests/tsconfig.json", "start": "node ./lib/index.js", "start:zombienet-post-script": "yarn build:scripts && node ./scripts/build/testNetworkSetup.js", "start:zombienet-foreign-assets-script": "yarn build:scripts && node ./scripts/build/testNetworkForeignAssets.js", "start:zombienet-liquidity-assets-script": "yarn build:scripts && node ./scripts/build/testNetworkLiquidAssets.js", + "zombienet": "./zombienet/zombienet-linux-x64 -p native spawn ./zombienet/medium-network.toml", + "e2e:zombienet": "./e2e-tests/zombienet.sh", + "e2e:assets": "./e2e-tests/tests.sh --assets", + "e2e:local": "./e2e-tests/tests.sh --local", + "e2e:liquidity-assets": "./e2e-tests/tests.sh --liquidity-assets", + "e2e:foreign-assets": "./e2e-tests/tests.sh --foreign-assets", "lint": "substrate-dev-run-lint", "lint:fix": "substrate-dev-run-lint --fix", "test": "NODE_ENV=test substrate-exec-jest --detectOpenHandles", diff --git a/scripts/consts.ts b/scripts/consts.ts index fac167a5..1a3e85ab 100644 --- a/scripts/consts.ts +++ b/scripts/consts.ts @@ -3,3 +3,4 @@ export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; +export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts index 79667e1e..c1be1d4a 100644 --- a/scripts/testNetworkForeignAssets.ts +++ b/scripts/testNetworkForeignAssets.ts @@ -13,7 +13,7 @@ const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { parents: 1, interior: { X1: { - parachain: 1836, + parachain: 3000, }, }, }; @@ -35,14 +35,14 @@ const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { parents: 1, interior: { X1: { - parachain: 1836, + parachain: 3000, }, }, }; const createTx = assetHubApi.tx.foreignAssets.create( trappistMultiLocation, - '5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', // Sibling 1836 -> ParaId + '5Eg2fntDDP4P8TjqRg3Jq89y5boE26JUMM3D7VU3bCAp76nc', // Sibling 1836 -> ParaId '100000000000' ); @@ -58,7 +58,7 @@ const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { // Double encode the call - const xcmDoubleEncoded = trappistApi.createType('StagingXcmDoubleEncoded', { + const xcmDoubleEncoded = trappistApi.createType('XcmDoubleEncoded', { encoded: call, }); @@ -210,8 +210,8 @@ const main = async () => { logWithDate(chalk.magenta('Sending funds to Trappist Sibling on Kusama AssetHub')); - await kusamaAssetHubApi.tx.balances - .transferKeepAlive('5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', 10000000000000) + await kusamaAssetHubApi.tx.balances // ParaID 3000 + .transferKeepAlive('5Eg2fntDDP4P8TjqRg3Jq89y5boE26JUMM3D7VU3bCAp76nc', 10000000000000) .signAndSend(bob); const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo(kusamaAssetHubApi, trappistApi); diff --git a/scripts/testNetworkLiquidAssets.ts b/scripts/testNetworkLiquidAssets.ts index bab1f2ff..8d87374c 100644 --- a/scripts/testNetworkLiquidAssets.ts +++ b/scripts/testNetworkLiquidAssets.ts @@ -80,8 +80,12 @@ const main = async () => { const hrmpChannelCalls = []; - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1000), Number(1836))); - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1836), Number(1000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1000), Number(3000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1000), Number(4000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(3000), Number(1000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(3000), Number(4000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(4000), Number(1000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(4000), Number(3000))); await relayApi.tx.sudo.sudo(relayApi.tx.utility.batchAll(hrmpChannelCalls)).signAndSend(alice); diff --git a/scripts/testNetworkSetup.ts b/scripts/testNetworkSetup.ts index 06d49cf6..d6789aac 100644 --- a/scripts/testNetworkSetup.ts +++ b/scripts/testNetworkSetup.ts @@ -123,7 +123,7 @@ const main = async () => { assetInfo.assetSymbol, assetInfo.assetDecimals ), - kusamaAssetHubApi.tx.assets.mint(assetInfo.assetId, alice.address, 1000 * 120000000), + kusamaAssetHubApi.tx.assets.mint(assetInfo.assetId, alice.address, 100000 * 120000000), ]; const batch = kusamaAssetHubApi.tx.utility.batchAll(txs); diff --git a/zombienet/medium-network.toml b/zombienet/medium-network.toml index c5cdc83f..492c3614 100644 --- a/zombienet/medium-network.toml +++ b/zombienet/medium-network.toml @@ -1,5 +1,5 @@ [relaychain] -default_command = "./bin/polkadot" +default_command = "./zombienet/bin/polkadot" default_args = [ "-lparachain=debug" ] chain = "rococo-local" @@ -32,34 +32,52 @@ cumulus_based = true [[parachains.collators]] name = "statemine-collator01" - command = "./bin/polkadot-parachain" + command = "./zombienet/bin/polkadot-parachain" args = ["--log=xcm=trace,pallet-assets=trace"] ws_port = 9910 [[parachains.collators]] name = "statemine-collator02" - command = "./bin/polkadot-parachain" + command = "./zombienet/bin/polkadot-parachain" ws_port = 9911 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains]] -id = 1836 +id = 2500 add_to_genesis = true cumulus_based = true chain = "trappist-local" [[parachains.collators]] name = "trappist-collator01" - command = "./bin/trappist-node" + command = "./zombienet/bin/trappist-node" ws_port = 9920 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains.collators]] name = "trappist-collator02" - command = "./bin/trappist-node" + command = "./zombienet/bin/trappist-node" ws_port = 9921 args = ["--log=xcm=trace,pallet-assets=trace"] +[[parachains]] +id = 2600 +add_to_genesis = true +cumulus_based = true +chain = "moonriver-local" + + [[parachains.collators]] + name = "moonriver-collator01" + command = "./zombienet/bin/moonbeam" + ws_port = 9930 + args = ["--log=xcm=trace,pallet-assets=trace"] + + [[parachains.collators]] + name = "moonriver-collator02" + command = "./zombienet/bin/moonbeam" + ws_port = 9931 + args = ["--log=xcm=trace,pallet-assets=trace"] + [types.Header] number = "u64" parent_hash = "Hash" From 96df8ae33c9f7a895244dec7c63086f88ee2ad78 Mon Sep 17 00:00:00 2001 From: bee344 Date: Mon, 8 Jan 2024 20:27:16 -0300 Subject: [PATCH 02/25] removed injected registry --- e2e-tests/balance.ts | 2 - e2e-tests/executor.ts | 22 ++- e2e-tests/tests/assets.ts | 22 +-- e2e-tests/tests/foreignAssets.ts | 15 +- e2e-tests/tests/index.ts | 234 +++++++++++++++---------------- e2e-tests/tests/liquidPools.ts | 15 +- e2e-tests/tests/local.ts | 15 +- e2e-tests/verification.ts | 10 +- 8 files changed, 140 insertions(+), 195 deletions(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index f61824c5..1762eafd 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -71,7 +71,6 @@ export const balanceTracker = async ( for (const assetId of assetIds) { accountInfo = await api.query.assets.account(assetId, address); balances.final.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); - } } return balances; @@ -83,7 +82,6 @@ export const balanceTracker = async ( balances.initial.push([assetId, accountInfo.data.free.toBn().toNumber()]); } else { balances.initial.push([assetId, 0]); - } } } else { diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index 0d3545fb..5e78673a 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -4,12 +4,12 @@ import { Keyring } from '@polkadot/keyring'; // import { KeyringPair } from '@polkadot/keyring/types'; import { cryptoWaitReady } from '@polkadot/util-crypto'; +import { delay } from '../scripts/util'; import { constructApiPromise } from '../src'; import { balanceTracker, IBalance } from './balance'; import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; import { assetTests, foreignAssetsTests, IndividualTest, liquidPoolsTests, localTests, tests } from './tests'; import { verification } from './verification'; -import { delay } from '../scripts/util' const executor = async (testCase: string) => { let originWsUrl = ''; @@ -52,7 +52,7 @@ const executor = async (testCase: string) => { n = assetTests; break; } - console.log(n) + console.log(n); let originChainId = ''; let destChainId = ''; @@ -63,14 +63,13 @@ const executor = async (testCase: string) => { let opts: object = {}; for (const t of testData) { - originChainId = t.args[0]; destChainId = t.args[1]; originAddr = t.args[2]; destAddr = t.args[3]; assetIds = t.args[4].slice(1, -1).split(','); amounts = t.args[5].slice(1, -1).split(','); - opts = JSON.parse(t.args[6]); + opts = JSON.parse(t.args[6]) as object; switch (originChainId) { case '0': @@ -114,12 +113,12 @@ const executor = async (testCase: string) => { originChainId == destChainId ? originApi : await ApiPromise.create({ - provider: new WsProvider(destWsUrl), - noInitWarn: true, - }); + provider: new WsProvider(destWsUrl), + noInitWarn: true, + }); await destinationApi.isReady; - let destInitialBalance: IBalance = await balanceTracker(destinationApi, testCase, destAddr, assetIds); + const destInitialBalance: IBalance = await balanceTracker(destinationApi, testCase, destAddr, assetIds); const originKeyring = keyring.addFromUri(originAddr); //eslint-disable-next-line @typescript-eslint/no-unsafe-call @@ -127,7 +126,7 @@ const executor = async (testCase: string) => { await delay(24000); - let destFinalBalance: IBalance = await balanceTracker( + const destFinalBalance: IBalance = await balanceTracker( destinationApi, testCase, destAddr, @@ -147,10 +146,9 @@ const executor = async (testCase: string) => { await delay(12000); - originApi.disconnect(); - destinationApi.disconnect(); + await originApi.disconnect(); + await destinationApi.disconnect(); } - }; executor(process.argv[2]).finally(() => process.exit()); diff --git a/e2e-tests/tests/assets.ts b/e2e-tests/tests/assets.ts index 8759e9fc..7f2298ff 100644 --- a/e2e-tests/tests/assets.ts +++ b/e2e-tests/tests/assets.ts @@ -6,20 +6,7 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const injectedRegistry = { - rococo: { - '2500': { - tokens: ['HOP'], - assetsInfo: {}, - foreignAssetsInfo: {}, - specName: 'trappist-rococo', - poolPairsInfo: {}, - }, - }, - }; - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { - injectedRegistry, - }); + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion); return assetApi; }; @@ -63,10 +50,13 @@ const createPayFeesTransaction = async ( let localTransfer: TxResult<'submittable'>; try { localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - await localTransfer.tx.signAndSend(origin) + await localTransfer.tx.signAndSend(origin); } catch (e) { console.error(e); throw Error(e as string); } }; -export const assetTests: { [K: string]: Function } = { createLocalSystemAssetsTransferTransaction, createPayFeesTransaction }; +export const assetTests: { [K: string]: Function } = { + createLocalSystemAssetsTransferTransaction, + createPayFeesTransaction, +}; diff --git a/e2e-tests/tests/foreignAssets.ts b/e2e-tests/tests/foreignAssets.ts index 133aeb75..cf2783f8 100644 --- a/e2e-tests/tests/foreignAssets.ts +++ b/e2e-tests/tests/foreignAssets.ts @@ -6,20 +6,7 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const injectedRegistry = { - kusama: { - '3000': { - tokens: ['HOP'], - assetsInfo: {}, - foreignAssetsInfo: {}, - specName: 'trappist', - poolPairsInfo: {}, - }, - }, - }; - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { - injectedRegistry, - }); + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion); return assetApi; }; diff --git a/e2e-tests/tests/index.ts b/e2e-tests/tests/index.ts index 8a010038..5f7dafd3 100644 --- a/e2e-tests/tests/index.ts +++ b/e2e-tests/tests/index.ts @@ -7,127 +7,127 @@ export { localTests } from './local'; import { BOB_KAH_ADDR, BOB_ROC_ADDR, FERDE_KAH_ADDR } from '../consts'; export interface IndividualTest { - test: string; - args: string[]; - verification: string[]; + test: string; + args: string[]; + verification: string[]; } export interface TestGroups { - foreignAssets: IndividualTest[]; - liquidPools: IndividualTest[]; - assets: IndividualTest[]; - local: IndividualTest[]; + foreignAssets: IndividualTest[]; + liquidPools: IndividualTest[]; + assets: IndividualTest[]; + local: IndividualTest[]; } export const tests: TestGroups = { - foreignAssets: [ - { - // This will declare the call to use - test: 'createTransferTransactionCall', - // This will be all the args for the above call - args: [ - '2500', - '1000', - '//Alice', - BOB_KAH_ADDR, - '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "2500" }, { "GeneralIndex": "0" }]}}]', - '[200000000000]', - '{ "format": "submittable", "xcmVersion": 3 }', - ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['', ''], - }, - ], - liquidPools: [ - { - // This will declare the call to use - test: 'createLocalTransferTransaction', - // This will be all the args for the above call - args: [ - '1000', - '1000', - '//Alice', - BOB_KAH_ADDR, - '[0]', - '[2000]', - '{ "format": "submittable", "transferLiquidToken": true }', - ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[0]', '[2000]'], - }, - { - // This will declare the call to use - test: 'createPayFeesTransaction', - // This will be all the args for the above call - args: [ - '1000', - '1000', - '//Alice', - BOB_KAH_ADDR, - '[0]', - '[30000]', - '{ "format": "submittable", "transferLiquidToken": true }', - ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[0]', '[30000]'], - }, - ], - local: [ - { - // This will declare the call to use - test: 'createSystemLocalTransferTransaction', - // This will be all the args for the above call - args: [ - '1000', - '1000', - '//Alice', - BOB_KAH_ADDR, - '[]', - '[10000000000000]', - '{ "format": "submittable", "keepAlive": true }', - ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[0]', '[10000000000000]'], - } - ], - assets: [ - { - // This will declare the call to use - test: 'createLocalSystemAssetsTransferTransaction', - // This will be all the args for the above call - args: [ - '1000', - '1000', - '//Alice', - BOB_ROC_ADDR, - '[1]', - '[3000000000000]', - '{ "format": "submittable", "keepAlive": true }', - ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[1]', '[30000]'], - }, - { - // This will declare the call to use - test: 'createPayFeesTransaction', - // This will be all the args for the above call - args: [ - '1000', - '1000', - '//Bob', - FERDE_KAH_ADDR, - '[1]', - '[200000000000]', - '{ "format": "submittable", "keepAlive": true }', - ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[1]', '[2000]'], - }, - ], + foreignAssets: [ + { + // This will declare the call to use + test: 'createTransferTransactionCall', + // This will be all the args for the above call + args: [ + '2500', + '1000', + '//Alice', + BOB_KAH_ADDR, + '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "2500" }, { "GeneralIndex": "0" }]}}]', + '[200000000000]', + '{ "format": "submittable", "xcmVersion": 3 }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['', ''], + }, + ], + liquidPools: [ + { + // This will declare the call to use + test: 'createLocalTransferTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Alice', + BOB_KAH_ADDR, + '[0]', + '[2000]', + '{ "format": "submittable", "transferLiquidToken": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[0]', '[2000]'], + }, + { + // This will declare the call to use + test: 'createPayFeesTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Alice', + BOB_KAH_ADDR, + '[0]', + '[30000]', + '{ "format": "submittable", "transferLiquidToken": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[0]', '[30000]'], + }, + ], + local: [ + { + // This will declare the call to use + test: 'createSystemLocalTransferTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Alice', + BOB_KAH_ADDR, + '[]', + '[10000000000000]', + '{ "format": "submittable", "keepAlive": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[0]', '[10000000000000]'], + }, + ], + assets: [ + { + // This will declare the call to use + test: 'createLocalSystemAssetsTransferTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Alice', + BOB_ROC_ADDR, + '[1]', + '[3000000000000]', + '{ "format": "submittable", "keepAlive": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[1]', '[30000]'], + }, + { + // This will declare the call to use + test: 'createPayFeesTransaction', + // This will be all the args for the above call + args: [ + '1000', + '1000', + '//Bob', + FERDE_KAH_ADDR, + '[1]', + '[200000000000]', + '{ "format": "submittable", "keepAlive": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[1]', '[2000]'], + }, + ], }; diff --git a/e2e-tests/tests/liquidPools.ts b/e2e-tests/tests/liquidPools.ts index 74b69e23..d4c71703 100644 --- a/e2e-tests/tests/liquidPools.ts +++ b/e2e-tests/tests/liquidPools.ts @@ -6,20 +6,7 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const injectedRegistry = { - kusama: { - '3000': { - tokens: ['HOP'], - assetsInfo: {}, - foreignAssetsInfo: {}, - specName: 'trappist', - poolPairsInfo: {}, - }, - }, - }; - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { - injectedRegistry, - }); + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion); return assetApi; }; diff --git a/e2e-tests/tests/local.ts b/e2e-tests/tests/local.ts index 78689811..86c557a0 100644 --- a/e2e-tests/tests/local.ts +++ b/e2e-tests/tests/local.ts @@ -7,20 +7,7 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const injectedRegistry = { - kusama: { - '3000': { - tokens: ['HOP'], - assetsInfo: {}, - foreignAssetsInfo: {}, - specName: 'trappist', - poolPairsInfo: {}, - }, - }, - }; - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { - injectedRegistry, - }); + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion); return assetApi; }; diff --git a/e2e-tests/verification.ts b/e2e-tests/verification.ts index c58a47c8..f1e6a6b3 100644 --- a/e2e-tests/verification.ts +++ b/e2e-tests/verification.ts @@ -5,14 +5,12 @@ export const verification = (assetIds: string[], amounts: string[], destBalance: const destInitialBalance: [string, number][] = destBalance.initial; const destFinalBalance: [string, number][] = destBalance.final; const correctlyReceived: [string, boolean][] = []; - console.log(destInitialBalance) - console.log(destFinalBalance) + console.log(destInitialBalance); + console.log(destFinalBalance); - let check: boolean = true; + let check = true; for (let i = 0; i < assetIds.length; i++) { - check = - destInitialBalance[i][1] + Number(amounts[i]) == - destFinalBalance[i][1]; + check = destInitialBalance[i][1] + Number(amounts[i]) == destFinalBalance[i][1]; correctlyReceived.push([destInitialBalance[i][0], check]); } From a053088eede607fe234fcb4e20dbdcc6e28ab16f Mon Sep 17 00:00:00 2001 From: bee344 Date: Tue, 9 Jan 2024 11:38:46 -0300 Subject: [PATCH 03/25] linting --- e2e-tests/balance.ts | 2 +- e2e-tests/executor.ts | 6 ++++-- e2e-tests/tests/assets.ts | 4 ++-- e2e-tests/tests/foreignAssets.ts | 2 +- e2e-tests/tests/liquidPools.ts | 4 ++-- e2e-tests/tests/local.ts | 6 +++--- e2e-tests/verification.ts | 2 +- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index 1762eafd..2705f24d 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -13,7 +13,7 @@ export const balanceTracker = async ( test: string, address: string, assetIds: string[], - balance?: IBalance + balance?: IBalance, ): Promise => { let balances: IBalance = { initial: [], final: [] }; let accountInfo: FrameSystemAccountInfo | Option; diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index 5e78673a..a58356a5 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -131,7 +131,7 @@ const executor = async (testCase: string) => { testCase, destAddr, assetIds, - destInitialBalance + destInitialBalance, ); const correctlyReceived = verification(assetIds, amounts, destFinalBalance); @@ -151,4 +151,6 @@ const executor = async (testCase: string) => { } }; -executor(process.argv[2]).finally(() => process.exit()); +executor(process.argv[2]) + .catch((err) => console.error(err)) + .finally(() => process.exit()); diff --git a/e2e-tests/tests/assets.ts b/e2e-tests/tests/assets.ts index 7f2298ff..36614b0a 100644 --- a/e2e-tests/tests/assets.ts +++ b/e2e-tests/tests/assets.ts @@ -20,7 +20,7 @@ const createLocalSystemAssetsTransferTransaction = async ( opts: object, api: ApiPromise, specName: string, - safeXcmVersion: number + safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); @@ -43,7 +43,7 @@ const createPayFeesTransaction = async ( opts: object, api: ApiPromise, specName: string, - safeXcmVersion: number + safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); diff --git a/e2e-tests/tests/foreignAssets.ts b/e2e-tests/tests/foreignAssets.ts index cf2783f8..7663c841 100644 --- a/e2e-tests/tests/foreignAssets.ts +++ b/e2e-tests/tests/foreignAssets.ts @@ -20,7 +20,7 @@ const createTransferTransaction = async ( opts: object, api: ApiPromise, specName: string, - safeXcmVersion: number + safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); diff --git a/e2e-tests/tests/liquidPools.ts b/e2e-tests/tests/liquidPools.ts index d4c71703..39ade811 100644 --- a/e2e-tests/tests/liquidPools.ts +++ b/e2e-tests/tests/liquidPools.ts @@ -20,7 +20,7 @@ const createLocalTransferTransaction = async ( opts: object, api: ApiPromise, specName: string, - safeXcmVersion: number + safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); @@ -43,7 +43,7 @@ const createPayFeesTransaction = async ( opts: object, api: ApiPromise, specName: string, - safeXcmVersion: number + safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); diff --git a/e2e-tests/tests/local.ts b/e2e-tests/tests/local.ts index 86c557a0..12d1ecd3 100644 --- a/e2e-tests/tests/local.ts +++ b/e2e-tests/tests/local.ts @@ -21,7 +21,7 @@ const createSystemLocalTransferTransaction = async ( opts: object, api: ApiPromise, specName: string, - safeXcmVersion: number + safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); @@ -44,7 +44,7 @@ const createRelayLocalTransferTransaction = async ( opts: object, api: ApiPromise, specName: string, - safeXcmVersion: number + safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); @@ -67,7 +67,7 @@ const createRelayToSystemTransferTransaction = async ( opts: object, api: ApiPromise, specName: string, - safeXcmVersion: number + safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); diff --git a/e2e-tests/verification.ts b/e2e-tests/verification.ts index f1e6a6b3..2e1470e1 100644 --- a/e2e-tests/verification.ts +++ b/e2e-tests/verification.ts @@ -1,5 +1,5 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import { IBalance } from 'balance'; +import { IBalance } from './balance'; export const verification = (assetIds: string[], amounts: string[], destBalance: IBalance) => { const destInitialBalance: [string, number][] = destBalance.initial; From caf5037b097add9ac49e69649358ddcaa6997828 Mon Sep 17 00:00:00 2001 From: bee344 Date: Tue, 9 Jan 2024 17:36:47 -0300 Subject: [PATCH 04/25] added rococo --- e2e-tests/balance.ts | 4 ++-- e2e-tests/executor.ts | 13 ++++++----- e2e-tests/tests.sh | 2 +- e2e-tests/tests/index.ts | 42 +++++++++++++++++++++++++++++++---- e2e-tests/tests/local.ts | 18 ++++++++++++++- e2e-tests/tsconfig.json | 1 + src/registry/Registry.ts | 1 + zombienet/medium-network.toml | 14 ++++++------ 8 files changed, 75 insertions(+), 20 deletions(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index 2705f24d..b6a41bc8 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -49,11 +49,11 @@ export const balanceTracker = async ( case '--local': if (!balance) { accountInfo = await api.query.system.account(address); - balances.initial.push(['0', accountInfo.data.free.toBn().toNumber()]); + balances.initial.push(['0', Number(accountInfo.data.free)]); } else { balances = balance; accountInfo = await api.query.system.account(address); - balances.final.push(['0', accountInfo.data.free.toBn().toNumber()]); + balances.final.push(['0', Number(accountInfo.data.free)]); } return balances; case '--assets': diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index a58356a5..3c3c1cf7 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -16,6 +16,7 @@ const executor = async (testCase: string) => { let destWsUrl = ''; let testData: IndividualTest[] = []; + console.log(testCase) await cryptoWaitReady(); @@ -78,10 +79,10 @@ const executor = async (testCase: string) => { case '1000': originWsUrl = KUSAMA_ASSET_HUB_WS_URL; break; - case '2500': + case '1836': originWsUrl = TRAPPIST_WS_URL; break; - case '2600': + case '4000': originWsUrl = MOONRIVER_WS_URL; break; } @@ -96,16 +97,18 @@ const executor = async (testCase: string) => { case '1000': destWsUrl = KUSAMA_ASSET_HUB_WS_URL; break; - case '2500': + case '1836': destWsUrl = TRAPPIST_WS_URL; break; - case '2600': + case '4000': destWsUrl = MOONRIVER_WS_URL; break; } } const { api, specName, safeXcmVersion } = await constructApiPromise(originWsUrl); + let sanitizedSpecName = originChainId === '1836' ? 'asset-hub-rococo' : specName; + console.log(sanitizedSpecName) await api.isReady; const originApi = api; @@ -122,7 +125,7 @@ const executor = async (testCase: string) => { const originKeyring = keyring.addFromUri(originAddr); //eslint-disable-next-line @typescript-eslint/no-unsafe-call - await n[t.test](originKeyring, destChainId, destAddr, assetIds, amounts, opts, api, specName, safeXcmVersion); + await n[t.test](originKeyring, destChainId, destAddr, assetIds, amounts, opts, api, sanitizedSpecName, safeXcmVersion); await delay(24000); diff --git a/e2e-tests/tests.sh b/e2e-tests/tests.sh index 489aee7b..d53cd824 100755 --- a/e2e-tests/tests.sh +++ b/e2e-tests/tests.sh @@ -1,6 +1,6 @@ #!/bin/sh test=$1 -yarn run build:e2e && +yarn run build:e2e if [ $test = '--assets' ]; then script=post elif [ $test = '--local' ]; then diff --git a/e2e-tests/tests/index.ts b/e2e-tests/tests/index.ts index 5f7dafd3..accbbb6b 100644 --- a/e2e-tests/tests/index.ts +++ b/e2e-tests/tests/index.ts @@ -26,7 +26,7 @@ export const tests: TestGroups = { test: 'createTransferTransactionCall', // This will be all the args for the above call args: [ - '2500', + '1836', '1000', '//Alice', BOB_KAH_ADDR, @@ -76,17 +76,51 @@ export const tests: TestGroups = { }, ], local: [ + // { + // // This will declare the call to use + // test: 'createSystemLocalTransferTransaction', + // // This will be all the args for the above call + // args: [ + // '1000', + // '1000', + // '//Alice', + // BOB_KAH_ADDR, + // '[]', + // '[10000000000000]', + // '{ "format": "submittable", "keepAlive": true }', + // ], + // // This will be a tuple that will allow us to verify if the xcm message + // // succesfully went through on the other end + // verification: ['[0]', '[10000000000000]'], + // }, + // { + // // This will declare the call to use + // test: 'createSystemLocalTransferTransaction', + // // This will be all the args for the above call + // args: [ + // '1836', + // '1836', + // '//Alice', + // BOB_KAH_ADDR, + // '[]', + // '[100000000000000000]', + // '{ "format": "submittable", "keepAlive": true }', + // ], + // // This will be a tuple that will allow us to verify if the xcm message + // // succesfully went through on the other end + // verification: ['[0]', '[10000000000000]'], + // }, { // This will declare the call to use test: 'createSystemLocalTransferTransaction', // This will be all the args for the above call args: [ - '1000', - '1000', + '0', + '0', '//Alice', BOB_KAH_ADDR, '[]', - '[10000000000000]', + '[100000000000000000]', '{ "format": "submittable", "keepAlive": true }', ], // This will be a tuple that will allow us to verify if the xcm message diff --git a/e2e-tests/tests/local.ts b/e2e-tests/tests/local.ts index 12d1ecd3..d504206b 100644 --- a/e2e-tests/tests/local.ts +++ b/e2e-tests/tests/local.ts @@ -7,7 +7,22 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion); + + const injectedRegistry = { + kusama: { + '1836': { + tokens: ['ROC'], + assetsInfo: {}, + foreignAssetsInfo: {}, + specName: 'asset-hub-rococo', + poolPairsInfo: {}, + }, + }, + }; + + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, + { injectedRegistry }); + return assetApi; }; @@ -28,6 +43,7 @@ const createSystemLocalTransferTransaction = async ( let localTransferInfo: TxResult<'submittable'>; try { localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + console.log(localTransferInfo.direction) await localTransferInfo.tx.signAndSend(origin); } catch (e) { console.error(e); diff --git a/e2e-tests/tsconfig.json b/e2e-tests/tsconfig.json index b3d794f0..928e51d6 100644 --- a/e2e-tests/tsconfig.json +++ b/e2e-tests/tsconfig.json @@ -4,6 +4,7 @@ "baseUrl": ".", "outDir": "build", "suppressImplicitAnyIndexErrors": true, + "ignoreDeprecations": "5.0", "resolveJsonModule": true, }, } diff --git a/src/registry/Registry.ts b/src/registry/Registry.ts index fe0a2df7..5471080c 100644 --- a/src/registry/Registry.ts +++ b/src/registry/Registry.ts @@ -6,6 +6,7 @@ import { ASSET_HUB_CHAIN_ID, KUSAMA_ASSET_HUB_SPEC_NAMES, POLKADOT_ASSET_HUB_SPEC_NAMES, + ROCOCO_ASSET_HUB_SPEC_NAME, WESTEND_ASSET_HUB_SPEC_NAMES, } from '../consts'; import type { AssetTransferApiOpts } from '../types'; diff --git a/zombienet/medium-network.toml b/zombienet/medium-network.toml index 492c3614..66d76990 100644 --- a/zombienet/medium-network.toml +++ b/zombienet/medium-network.toml @@ -43,25 +43,25 @@ cumulus_based = true args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains]] -id = 2500 +id = 1836 add_to_genesis = true cumulus_based = true -chain = "trappist-local" +chain = "asset-hub-rococo-local" [[parachains.collators]] - name = "trappist-collator01" - command = "./zombienet/bin/trappist-node" + name = "rockmine-collator01" + command = "./zombienet/bin/polkadot-parachain" ws_port = 9920 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains.collators]] - name = "trappist-collator02" - command = "./zombienet/bin/trappist-node" + name = "rockmine-collator02" + command = "./zombienet/bin/polkadot-parachain" ws_port = 9921 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains]] -id = 2600 +id = 4000 add_to_genesis = true cumulus_based = true chain = "moonriver-local" From 0206365b41a50e5195272b4d3c6f3b177719f237 Mon Sep 17 00:00:00 2001 From: bee344 Date: Tue, 9 Jan 2024 17:56:59 -0300 Subject: [PATCH 05/25] added rococo asset hub to registry --- src/registry/Registry.ts | 3 ++- src/registry/findRelayChain.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/registry/Registry.ts b/src/registry/Registry.ts index 5471080c..f0f1cda2 100644 --- a/src/registry/Registry.ts +++ b/src/registry/Registry.ts @@ -251,7 +251,8 @@ export class Registry { if ( POLKADOT_ASSET_HUB_SPEC_NAMES.includes(specName.toLowerCase()) || KUSAMA_ASSET_HUB_SPEC_NAMES.includes(specName.toLowerCase()) || - WESTEND_ASSET_HUB_SPEC_NAMES.includes(specName.toLowerCase()) + WESTEND_ASSET_HUB_SPEC_NAMES.includes(specName.toLowerCase()) || + ROCOCO_ASSET_HUB_SPEC_NAME.includes(specName.toLocaleLowerCase()) ) { this.specNameToIdCache.set(specName, '1000'); return '1000'; diff --git a/src/registry/findRelayChain.ts b/src/registry/findRelayChain.ts index d683ebab..b6a9df83 100644 --- a/src/registry/findRelayChain.ts +++ b/src/registry/findRelayChain.ts @@ -29,7 +29,7 @@ export const findRelayChain = (specName: string, registry: ChainInfoRegistry): R return 'westend'; const rococoChains = Object.keys(registry.rococo).map((val) => registry.rococo[val].specName); - if (rococoChains.includes(specName.toLowerCase()) || ROCOCO_ASSET_HUB_SPEC_NAME) { + if (rococoChains.includes(specName.toLowerCase()) || ROCOCO_ASSET_HUB_SPEC_NAME.includes(specName.toLowerCase())) { return 'rococo'; } From bb2caa8ada9a9b672a1891cb24bf857ad551b49f Mon Sep 17 00:00:00 2001 From: bee344 Date: Tue, 9 Jan 2024 18:18:09 -0300 Subject: [PATCH 06/25] removed .toLocaleLowerCase --- src/registry/Registry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registry/Registry.ts b/src/registry/Registry.ts index f0f1cda2..729e558a 100644 --- a/src/registry/Registry.ts +++ b/src/registry/Registry.ts @@ -252,7 +252,7 @@ export class Registry { POLKADOT_ASSET_HUB_SPEC_NAMES.includes(specName.toLowerCase()) || KUSAMA_ASSET_HUB_SPEC_NAMES.includes(specName.toLowerCase()) || WESTEND_ASSET_HUB_SPEC_NAMES.includes(specName.toLowerCase()) || - ROCOCO_ASSET_HUB_SPEC_NAME.includes(specName.toLocaleLowerCase()) + ROCOCO_ASSET_HUB_SPEC_NAME.includes(specName.toLowerCase()) ) { this.specNameToIdCache.set(specName, '1000'); return '1000'; From ac661577468ca9b1d1cc704258210180ba7e14d6 Mon Sep 17 00:00:00 2001 From: bee344 Date: Wed, 10 Jan 2024 14:28:33 -0300 Subject: [PATCH 07/25] upload for testing --- e2e-tests/consts.ts | 2 +- e2e-tests/executor.ts | 12 ++-- e2e-tests/tests/assets.ts | 16 ++++- e2e-tests/tests/foreignAssets.ts | 16 ++++- e2e-tests/tests/index.ts | 94 ++++++++++++++--------------- e2e-tests/tests/liquidPools.ts | 44 ++++++++++++-- e2e-tests/tests/local.ts | 55 +---------------- scripts/consts.ts | 2 +- scripts/testNetworkForeignAssets.ts | 58 +++++++++--------- scripts/testNetworkLiquidAssets.ts | 8 +-- src/AssetTransferApi.ts | 7 +++ 11 files changed, 169 insertions(+), 145 deletions(-) diff --git a/e2e-tests/consts.ts b/e2e-tests/consts.ts index 4424070e..805188ff 100644 --- a/e2e-tests/consts.ts +++ b/e2e-tests/consts.ts @@ -2,7 +2,7 @@ export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; -export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; +export const ROCOCO_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9921'; export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; export const BOB_ROC_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index 3c3c1cf7..95b1f54e 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -7,7 +7,7 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import { delay } from '../scripts/util'; import { constructApiPromise } from '../src'; import { balanceTracker, IBalance } from './balance'; -import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; +import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, ROCOCO_ASSET_HUB_WS_URL } from './consts'; import { assetTests, foreignAssetsTests, IndividualTest, liquidPoolsTests, localTests, tests } from './tests'; import { verification } from './verification'; @@ -70,7 +70,10 @@ const executor = async (testCase: string) => { destAddr = t.args[3]; assetIds = t.args[4].slice(1, -1).split(','); amounts = t.args[5].slice(1, -1).split(','); - opts = JSON.parse(t.args[6]) as object; + opts = JSON.parse(t.args[6], (key, value) => { + return key === "paysWithFeeOrigin" ? JSON.stringify(value) : value; + }) as object; + switch (originChainId) { case '0': @@ -80,7 +83,7 @@ const executor = async (testCase: string) => { originWsUrl = KUSAMA_ASSET_HUB_WS_URL; break; case '1836': - originWsUrl = TRAPPIST_WS_URL; + originWsUrl = ROCOCO_ASSET_HUB_WS_URL; break; case '4000': originWsUrl = MOONRIVER_WS_URL; @@ -98,7 +101,7 @@ const executor = async (testCase: string) => { destWsUrl = KUSAMA_ASSET_HUB_WS_URL; break; case '1836': - destWsUrl = TRAPPIST_WS_URL; + destWsUrl = ROCOCO_ASSET_HUB_WS_URL; break; case '4000': destWsUrl = MOONRIVER_WS_URL; @@ -108,7 +111,6 @@ const executor = async (testCase: string) => { const { api, specName, safeXcmVersion } = await constructApiPromise(originWsUrl); let sanitizedSpecName = originChainId === '1836' ? 'asset-hub-rococo' : specName; - console.log(sanitizedSpecName) await api.isReady; const originApi = api; diff --git a/e2e-tests/tests/assets.ts b/e2e-tests/tests/assets.ts index 36614b0a..baa0b557 100644 --- a/e2e-tests/tests/assets.ts +++ b/e2e-tests/tests/assets.ts @@ -6,7 +6,21 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion); + const injectedRegistry = { + rococo: { + '1836': { + tokens: ['ROC'], + assetsInfo: {}, + foreignAssetsInfo: {}, + specName: 'asset-hub-rococo', + poolPairsInfo: {}, + }, + }, + }; + + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, + { injectedRegistry }); + return assetApi; }; diff --git a/e2e-tests/tests/foreignAssets.ts b/e2e-tests/tests/foreignAssets.ts index 7663c841..988255d7 100644 --- a/e2e-tests/tests/foreignAssets.ts +++ b/e2e-tests/tests/foreignAssets.ts @@ -6,7 +6,21 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion); + const injectedRegistry = { + rococo: { + '1836': { + tokens: ['ROC'], + assetsInfo: {}, + foreignAssetsInfo: {}, + specName: 'asset-hub-rococo', + poolPairsInfo: {}, + }, + }, + }; + + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, + { injectedRegistry }); + return assetApi; }; diff --git a/e2e-tests/tests/index.ts b/e2e-tests/tests/index.ts index accbbb6b..1203bfe4 100644 --- a/e2e-tests/tests/index.ts +++ b/e2e-tests/tests/index.ts @@ -30,7 +30,7 @@ export const tests: TestGroups = { '1000', '//Alice', BOB_KAH_ADDR, - '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "2500" }, { "GeneralIndex": "0" }]}}]', + '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "1836" }, { "GeneralIndex": "0" }]}}]', '[200000000000]', '{ "format": "submittable", "xcmVersion": 3 }', ], @@ -40,9 +40,26 @@ export const tests: TestGroups = { }, ], liquidPools: [ + // { + // // This will declare the call to use + // test: 'createLocalTransferTransaction', + // // This will be all the args for the above call + // args: [ + // '1000', + // '1000', + // '//Alice', + // BOB_KAH_ADDR, + // '[0]', + // '[2000]', + // '{ "format": "submittable", "transferLiquidToken": true }', + // ], + // // This will be a tuple that will allow us to verify if the xcm message + // // succesfully went through on the other end + // verification: ['[0]', '[2000]'], + // }, { // This will declare the call to use - test: 'createLocalTransferTransaction', + test: 'createPayFeesTransaction', // This will be all the args for the above call args: [ '1000', @@ -50,69 +67,52 @@ export const tests: TestGroups = { '//Alice', BOB_KAH_ADDR, '[0]', - '[2000]', - '{ "format": "submittable", "transferLiquidToken": true }', + '[30000]', + '{ "format": "payload", "xcmVersion": 3, "transferLiquidToken": true, "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}}, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }', ], // This will be a tuple that will allow us to verify if the xcm message // succesfully went through on the other end - verification: ['[0]', '[2000]'], + verification: ['[0]', '[30000]'], }, + ], + local: [ { // This will declare the call to use - test: 'createPayFeesTransaction', + test: 'createLocalTransferTransaction', // This will be all the args for the above call args: [ '1000', '1000', '//Alice', BOB_KAH_ADDR, - '[0]', - '[30000]', - '{ "format": "submittable", "transferLiquidToken": true }', + '[]', + '[10000000000000]', + '{ "format": "submittable", "keepAlive": true }', ], // This will be a tuple that will allow us to verify if the xcm message // succesfully went through on the other end - verification: ['[0]', '[30000]'], + verification: ['[0]', '[10000000000000]'], + }, + { + // This will declare the call to use + test: 'createLocalTransferTransaction', + // This will be all the args for the above call + args: [ + '1836', + '1836', + '//Alice', + BOB_KAH_ADDR, + '[]', + '[100000000000000000]', + '{ "format": "submittable", "keepAlive": true }', + ], + // This will be a tuple that will allow us to verify if the xcm message + // succesfully went through on the other end + verification: ['[0]', '[10000000000000]'], }, - ], - local: [ - // { - // // This will declare the call to use - // test: 'createSystemLocalTransferTransaction', - // // This will be all the args for the above call - // args: [ - // '1000', - // '1000', - // '//Alice', - // BOB_KAH_ADDR, - // '[]', - // '[10000000000000]', - // '{ "format": "submittable", "keepAlive": true }', - // ], - // // This will be a tuple that will allow us to verify if the xcm message - // // succesfully went through on the other end - // verification: ['[0]', '[10000000000000]'], - // }, - // { - // // This will declare the call to use - // test: 'createSystemLocalTransferTransaction', - // // This will be all the args for the above call - // args: [ - // '1836', - // '1836', - // '//Alice', - // BOB_KAH_ADDR, - // '[]', - // '[100000000000000000]', - // '{ "format": "submittable", "keepAlive": true }', - // ], - // // This will be a tuple that will allow us to verify if the xcm message - // // succesfully went through on the other end - // verification: ['[0]', '[10000000000000]'], - // }, { // This will declare the call to use - test: 'createSystemLocalTransferTransaction', + test: 'createLocalTransferTransaction', // This will be all the args for the above call args: [ '0', diff --git a/e2e-tests/tests/liquidPools.ts b/e2e-tests/tests/liquidPools.ts index 39ade811..54eb06ab 100644 --- a/e2e-tests/tests/liquidPools.ts +++ b/e2e-tests/tests/liquidPools.ts @@ -6,7 +6,21 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion); + const injectedRegistry = { + rococo: { + '1836': { + tokens: ['ROC'], + assetsInfo: {}, + foreignAssetsInfo: {}, + specName: 'asset-hub-rococo', + poolPairsInfo: {}, + }, + }, + }; + + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, + { injectedRegistry }); + return assetApi; }; @@ -40,17 +54,39 @@ const createPayFeesTransaction = async ( destAddr: string, assetIds: string[], amounts: string[], - opts: object, + opts: {}, api: ApiPromise, specName: string, safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); - let localTransferInfo: TxResult<'submittable'>; + let localTransferInfo: TxResult<'payload'>; try { localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - await localTransferInfo.tx.signAndSend(origin); + const signature = api.registry + .createType('ExtrinsicPayload', localTransferInfo, { + version: 4, + }) + .sign(origin).signature as unknown as `0x${string}`; + + const extrinsic = api.registry.createType( + 'Extrinsic', + { method: localTransferInfo.method }, + { version: 4 } + ); + + let sender: string; + if (opts["sendersAddr"] === undefined) { + sender = '' + } else { + sender = opts["sendersAddr"]; + } + + const signed = extrinsic.addSignature(sender, signature, localTransferInfo as unknown as `0x${string}`).toHex() + + await api.rpc.author.submitExtrinsic(signed) + } catch (e) { console.error(e); throw Error(e as string); diff --git a/e2e-tests/tests/local.ts b/e2e-tests/tests/local.ts index d504206b..4d1f9222 100644 --- a/e2e-tests/tests/local.ts +++ b/e2e-tests/tests/local.ts @@ -9,7 +9,7 @@ import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { const injectedRegistry = { - kusama: { + rococo: { '1836': { tokens: ['ROC'], assetsInfo: {}, @@ -27,54 +27,7 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe return assetApi; }; -const createSystemLocalTransferTransaction = async ( - origin: KeyringPair, - destChainId: string, - destAddr: string, - assetIds: string[], - amounts: string[], - opts: object, - api: ApiPromise, - specName: string, - safeXcmVersion: number, -) => { - const assetApi = createAssetApi(api, specName, safeXcmVersion); - - let localTransferInfo: TxResult<'submittable'>; - try { - localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - console.log(localTransferInfo.direction) - await localTransferInfo.tx.signAndSend(origin); - } catch (e) { - console.error(e); - throw Error(e as string); - } -}; - -const createRelayLocalTransferTransaction = async ( - origin: KeyringPair, - destChainId: string, - destAddr: string, - assetIds: string[], - amounts: string[], - opts: object, - api: ApiPromise, - specName: string, - safeXcmVersion: number, -) => { - const assetApi = createAssetApi(api, specName, safeXcmVersion); - - let localTransferInfo: TxResult<'submittable'>; - try { - localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - await localTransferInfo.tx.signAndSend(origin); - } catch (e) { - console.error(e); - throw Error(e as string); - } -}; - -const createRelayToSystemTransferTransaction = async ( +const createLocalTransferTransaction = async ( origin: KeyringPair, destChainId: string, destAddr: string, @@ -98,7 +51,5 @@ const createRelayToSystemTransferTransaction = async ( }; export const localTests: { [K: string]: Function } = { - createSystemLocalTransferTransaction, - createRelayLocalTransferTransaction, - createRelayToSystemTransferTransaction, + createLocalTransferTransaction, }; diff --git a/scripts/consts.ts b/scripts/consts.ts index 1a3e85ab..721f697b 100644 --- a/scripts/consts.ts +++ b/scripts/consts.ts @@ -2,5 +2,5 @@ export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; -export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; +export const ROCOCO_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9921'; export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts index 86cefa98..7e06af6f 100644 --- a/scripts/testNetworkForeignAssets.ts +++ b/scripts/testNetworkForeignAssets.ts @@ -5,20 +5,20 @@ import { Keyring } from '@polkadot/keyring'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; -import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; +import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL, ROCOCO_ASSET_HUB_WS_URL } from './consts'; import { awaitBlockProduction, awaitEpochChange, delay, logWithDate } from './util'; const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { - const trappistMultiLocation = { + const rockmineMultilocatino = { parents: 1, interior: { X1: { - parachain: 3000, + parachain: 1836, }, }, }; - const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata(trappistMultiLocation, 'Trappist Hop', 'Hop', 12); + const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata(rockmineMultilocatino, 'Asset Hub Rococo Hop', 'Hop', 12); const hexCall = assetHubApi.registry .createType('Call', { @@ -31,7 +31,7 @@ const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { }; const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { - const trappistMultiLocation = { + const rockmineMultilocatino = { parents: 1, interior: { X1: { @@ -41,7 +41,7 @@ const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { }; const createTx = assetHubApi.tx.foreignAssets.create( - trappistMultiLocation, + rockmineMultilocatino, '5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', // Sibling 1836 -> ParaId '100000000000', ); @@ -56,13 +56,13 @@ const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { return hexCall; }; -const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { +const sudoCallWrapper = (rockmineApi: ApiPromise, call: `0x${string}`) => { // Double encode the call - const xcmDoubleEncoded = trappistApi.createType('XcmDoubleEncoded', { + const xcmDoubleEncoded = rockmineApi.createType('XcmDoubleEncoded', { encoded: call, }); - const xcmOriginType = trappistApi.createType('XcmOriginKind', 'Xcm'); + const xcmOriginType = rockmineApi.createType('XcmOriginKind', 'Xcm'); const xcmDestMultiLocation = { V3: { parents: 1, @@ -140,8 +140,8 @@ const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { }, ], }; - const xcmMsg = trappistApi.tx.polkadotXcm.send(xcmDestMultiLocation, xcmMessage); - const xcmCall = trappistApi.createType('Call', { + const xcmMsg = rockmineApi.tx.polkadotXcm.send(xcmDestMultiLocation, xcmMessage); + const xcmCall = rockmineApi.createType('Call', { callIndex: xcmMsg.callIndex, args: xcmMsg.args, }); @@ -149,14 +149,14 @@ const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { return xcmCall; }; -const createForeignAssetViaSudo = (assetHubApi: ApiPromise, trappistApi: ApiPromise) => { +const createForeignAssetViaSudo = (assetHubApi: ApiPromise, rockmineApi: ApiPromise) => { const foreignAssetCreateCall = fAssetCreateCall(assetHubApi); - return sudoCallWrapper(trappistApi, foreignAssetCreateCall); + return sudoCallWrapper(rockmineApi, foreignAssetCreateCall); }; -const setMetadataForeignAssetViaSudo = (assetHubApi: ApiPromise, trappistApi: ApiPromise) => { +const setMetadataForeignAssetViaSudo = (assetHubApi: ApiPromise, rockmineApi: ApiPromise) => { const setMetadataCall = fAssetSetMetadataCall(assetHubApi); - return sudoCallWrapper(trappistApi, setMetadataCall); + return sudoCallWrapper(rockmineApi, setMetadataCall); }; const openHrmpChannels = (api: ApiPromise, sender: number, receiver: number) => { @@ -179,13 +179,13 @@ const main = async () => { await kusamaAssetHubApi.isReady; logWithDate(chalk.green('Created a connection to Kusama AssetHub')); - const trappistApi = await ApiPromise.create({ - provider: new WsProvider(TRAPPIST_WS_URL), + const rockmineApi = await ApiPromise.create({ + provider: new WsProvider(ROCOCO_ASSET_HUB_WS_URL), noInitWarn: true, }); - await trappistApi.isReady; - logWithDate(chalk.green('Created a connection to Trappist')); + await rockmineApi.isReady; + logWithDate(chalk.green('Created a connection to Rococo Asset Hub')); const relayApi = await ApiPromise.create({ provider: new WsProvider(ROCOCO_ALICE_WS_URL), @@ -208,23 +208,23 @@ const main = async () => { await awaitEpochChange(relayApi); logWithDate(chalk.magenta('HRMP channels open')); - logWithDate(chalk.magenta('Sending funds to Trappist Sibling on Kusama AssetHub')); + logWithDate(chalk.magenta('Sending funds to Rococo Asset Hub Sibling on Kusama AssetHub')); - await kusamaAssetHubApi.tx.balances // ParaID 3000 - .transferKeepAlive('5Eg2fntDDP4P8TjqRg3Jq89y5boE26JUMM3D7VU3bCAp76nc', 10000000000000) + await kusamaAssetHubApi.tx.balances + .transferKeepAlive('5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', 10000000000000) .signAndSend(bob); - const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo(kusamaAssetHubApi, trappistApi); + const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo(kusamaAssetHubApi, rockmineApi); logWithDate('Sending Sudo XCM message from relay chain to execute create foreign asset call on Kusama AssetHub'); - await trappistApi.tx.sudo.sudo(foreignAssetsCreateSudoXcmCall).signAndSend(alice); + await rockmineApi.tx.sudo.sudo(foreignAssetsCreateSudoXcmCall).signAndSend(alice); await delay(24000); - const foreignAssetsSetMetadataSudoXcmCall = setMetadataForeignAssetViaSudo(kusamaAssetHubApi, trappistApi); + const foreignAssetsSetMetadataSudoXcmCall = setMetadataForeignAssetViaSudo(kusamaAssetHubApi, rockmineApi); logWithDate('Sending Sudo XCM message from relay chain to execute setMetadata call on Kusama AssetHub'); - await trappistApi.tx.sudo.sudo(foreignAssetsSetMetadataSudoXcmCall).signAndSend(alice); + await rockmineApi.tx.sudo.sudo(foreignAssetsSetMetadataSudoXcmCall).signAndSend(alice); await delay(24000); @@ -232,13 +232,13 @@ const main = async () => { logWithDate(chalk.blue('Polkadot-js successfully disconnected from asset-hub')); }); - await trappistApi.disconnect().then(() => { - logWithDate(chalk.blue('Polkadot-js successfully disconnected from trappist')); + await rockmineApi.disconnect().then(() => { + logWithDate(chalk.blue('Polkadot-js successfully disconnected from Rococo Asset Hub')); }); }; // eslint-disable-next-line @typescript-eslint/no-floating-promises -awaitBlockProduction(TRAPPIST_WS_URL).then(async () => { +awaitBlockProduction(ROCOCO_ASSET_HUB_WS_URL).then(async () => { await main() .catch(console.error) .finally(() => process.exit()); diff --git a/scripts/testNetworkLiquidAssets.ts b/scripts/testNetworkLiquidAssets.ts index fbb69a16..970fc48a 100644 --- a/scripts/testNetworkLiquidAssets.ts +++ b/scripts/testNetworkLiquidAssets.ts @@ -80,12 +80,12 @@ const main = async () => { const hrmpChannelCalls = []; - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1000), Number(3000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1000), Number(1836))); hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1000), Number(4000))); - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(3000), Number(1000))); - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(3000), Number(4000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1836), Number(1000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1836), Number(4000))); hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(4000), Number(1000))); - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(4000), Number(3000))); + hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(4000), Number(1836))); await relayApi.tx.sudo.sudo(relayApi.tx.utility.batchAll(hrmpChannelCalls)).signAndSend(alice); diff --git a/src/AssetTransferApi.ts b/src/AssetTransferApi.ts index 93277339..4c17ed47 100644 --- a/src/AssetTransferApi.ts +++ b/src/AssetTransferApi.ts @@ -889,6 +889,7 @@ export class AssetTransferApi { try { feeAsset = sanitizeKeys(JSON.parse(paysWithFeeOrigin)) as UnionXcmMultiLocation; + console.log(feeAsset) } catch (err: unknown) { throw new BaseError( `paysWithFeeOrigin value must be a valid MultiLocation. Received: ${paysWithFeeOrigin}`, @@ -900,15 +901,21 @@ export class AssetTransferApi { try { for (const poolPairsData of await this._api.query.assetConversion.pools.entries()) { const poolStorageKeyData = poolPairsData[0]; + console.log('poolAssetDataStr ' + poolStorageKeyData); + // remove any commas from multilocation key values e.g. Parachain: 2,125 -> Parachain: 2125 const poolAssetDataStr = JSON.stringify(poolStorageKeyData).replace(/(\d),/g, '$1'); + console.log('poolAssetDataStr ' + poolAssetDataStr); const palletAssetConversionNativeOrAssetIdData = sanitizeKeys( JSON.parse(poolAssetDataStr), ) as UnionXcmMultiLocation[]; + const firstLpToken = palletAssetConversionNativeOrAssetIdData[0]; + console.log('first ' + firstLpToken) const secondLpToken = palletAssetConversionNativeOrAssetIdData[1]; + console.log('second ' + secondLpToken) if ( JSON.stringify(firstLpToken) == JSON.stringify(feeAsset) || From e0ea727b79792b8f93e272580b8bc45f07c2dd20 Mon Sep 17 00:00:00 2001 From: bee344 Date: Thu, 11 Jan 2024 11:14:47 -0300 Subject: [PATCH 08/25] failing to decode poolAssets --- e2e-tests/balance.ts | 21 +++++++++++++++++---- e2e-tests/tests/index.ts | 4 ++-- e2e-tests/tests/liquidPools.ts | 34 +++++++++++++++++++--------------- src/AssetTransferApi.ts | 26 +++++++++++--------------- 4 files changed, 49 insertions(+), 36 deletions(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index b6a41bc8..56a73664 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -22,7 +22,11 @@ export const balanceTracker = async ( if (!balance) { for (const assetId of assetIds) { accountInfo = (await api.query.foreignAssets.account(assetId, address)) as Option; - balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + if (accountInfo.valueOf() === null) { + balances.initial.push([assetId, 0]); + } else { + balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + } } } else { balances = balance; @@ -36,7 +40,12 @@ export const balanceTracker = async ( if (!balance) { for (const assetId of assetIds) { accountInfo = await api.query.poolAssets.account(assetId, address); - balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + console.log(accountInfo.value.toHuman()) + if (accountInfo.isNone) { + balances.initial.push([assetId, 0]); + } else { + balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); + } } } else { balances = balance; @@ -49,7 +58,11 @@ export const balanceTracker = async ( case '--local': if (!balance) { accountInfo = await api.query.system.account(address); - balances.initial.push(['0', Number(accountInfo.data.free)]); + if (accountInfo === null) { + balances.initial.push(['0', 0]); + } else { + balances.initial.push(['0', Number(accountInfo.data.free)]); + } } else { balances = balance; accountInfo = await api.query.system.account(address); @@ -60,7 +73,7 @@ export const balanceTracker = async ( if (!balance) { for (const assetId of assetIds) { accountInfo = await api.query.assets.account(assetId, address); - if (accountInfo.valueOf() == null) { + if (accountInfo === null) { balances.initial.push([assetId, 0]); } else { balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); diff --git a/e2e-tests/tests/index.ts b/e2e-tests/tests/index.ts index 1203bfe4..a16bf42f 100644 --- a/e2e-tests/tests/index.ts +++ b/e2e-tests/tests/index.ts @@ -64,8 +64,8 @@ export const tests: TestGroups = { args: [ '1000', '1000', - '//Alice', - BOB_KAH_ADDR, + '//Bob', + FERDE_KAH_ADDR, '[0]', '[30000]', '{ "format": "payload", "xcmVersion": 3, "transferLiquidToken": true, "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}}, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }', diff --git a/e2e-tests/tests/liquidPools.ts b/e2e-tests/tests/liquidPools.ts index 54eb06ab..f662d6ec 100644 --- a/e2e-tests/tests/liquidPools.ts +++ b/e2e-tests/tests/liquidPools.ts @@ -63,19 +63,6 @@ const createPayFeesTransaction = async ( let localTransferInfo: TxResult<'payload'>; try { - localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - const signature = api.registry - .createType('ExtrinsicPayload', localTransferInfo, { - version: 4, - }) - .sign(origin).signature as unknown as `0x${string}`; - - const extrinsic = api.registry.createType( - 'Extrinsic', - { method: localTransferInfo.method }, - { version: 4 } - ); - let sender: string; if (opts["sendersAddr"] === undefined) { sender = '' @@ -83,9 +70,26 @@ const createPayFeesTransaction = async ( sender = opts["sendersAddr"]; } - const signed = extrinsic.addSignature(sender, signature, localTransferInfo as unknown as `0x${string}`).toHex() + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + console.log(localTransferInfo.tx) + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: 4, + }) + + const message = payload.toU8a({ method: true }); + + const signat = origin.sign(message, { withType: true }); + + const extrinsic = api.createType( + 'Extrinsic', + { method: localTransferInfo.method }, + { version: 4 } + ).addSignature(sender, signat, localTransferInfo.tx); + + const tx = extrinsic.toHex() - await api.rpc.author.submitExtrinsic(signed) + await api.rpc.author.submitExtrinsic(tx); } catch (e) { console.error(e); diff --git a/src/AssetTransferApi.ts b/src/AssetTransferApi.ts index 4c17ed47..3005eeb9 100644 --- a/src/AssetTransferApi.ts +++ b/src/AssetTransferApi.ts @@ -889,7 +889,6 @@ export class AssetTransferApi { try { feeAsset = sanitizeKeys(JSON.parse(paysWithFeeOrigin)) as UnionXcmMultiLocation; - console.log(feeAsset) } catch (err: unknown) { throw new BaseError( `paysWithFeeOrigin value must be a valid MultiLocation. Received: ${paysWithFeeOrigin}`, @@ -899,23 +898,20 @@ export class AssetTransferApi { if (this._api.query.assetConversion !== undefined) { try { - for (const poolPairsData of await this._api.query.assetConversion.pools.entries()) { - const poolStorageKeyData = poolPairsData[0]; - console.log('poolAssetDataStr ' + poolStorageKeyData); - + for (const poolPairsData of await this._api.query.assetConversion.pools.keys()) { + const poolStorageKeyData = poolPairsData.toHuman(); // remove any commas from multilocation key values e.g. Parachain: 2,125 -> Parachain: 2125 const poolAssetDataStr = JSON.stringify(poolStorageKeyData).replace(/(\d),/g, '$1'); - console.log('poolAssetDataStr ' + poolAssetDataStr); - const palletAssetConversionNativeOrAssetIdData = sanitizeKeys( - JSON.parse(poolAssetDataStr), - ) as UnionXcmMultiLocation[]; - - - const firstLpToken = palletAssetConversionNativeOrAssetIdData[0]; - console.log('first ' + firstLpToken) - const secondLpToken = palletAssetConversionNativeOrAssetIdData[1]; - console.log('second ' + secondLpToken) + const firstLpTokenSlice = poolAssetDataStr.slice(2, -2).slice(0, poolAssetDataStr.indexOf('},{"p') -1); + const secondLpTokenSlice = poolAssetDataStr.slice(2, -2).slice(poolAssetDataStr.indexOf('},{"p')); + + const firstLpToken = sanitizeKeys( + JSON.parse(firstLpTokenSlice), + ) as UnionXcmMultiLocation; + const secondLpToken = sanitizeKeys( + JSON.parse(secondLpTokenSlice), + ) as UnionXcmMultiLocation; if ( JSON.stringify(firstLpToken) == JSON.stringify(feeAsset) || From 7f41851498ef9526fc02bd138a20f2344758659e Mon Sep 17 00:00:00 2001 From: bee344 Date: Thu, 11 Jan 2024 20:08:11 -0300 Subject: [PATCH 09/25] linting --- e2e-tests/balance.ts | 2 +- e2e-tests/consts.ts | 8 ++-- e2e-tests/executor.ts | 18 ++++---- e2e-tests/tests/assets.ts | 4 +- e2e-tests/tests/foreignAssets.ts | 4 +- e2e-tests/tests/index.ts | 65 +++++++++++------------------ e2e-tests/tests/liquidPools.ts | 35 ++++------------ e2e-tests/tests/local.ts | 5 +-- scripts/testNetworkForeignAssets.ts | 7 +++- src/AssetTransferApi.ts | 22 ++++------ zombienet/medium-network.toml | 6 +-- 11 files changed, 64 insertions(+), 112 deletions(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index 56a73664..0a707d61 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -40,7 +40,7 @@ export const balanceTracker = async ( if (!balance) { for (const assetId of assetIds) { accountInfo = await api.query.poolAssets.account(assetId, address); - console.log(accountInfo.value.toHuman()) + console.log(accountInfo.value.toHuman()); if (accountInfo.isNone) { balances.initial.push([assetId, 0]); } else { diff --git a/e2e-tests/consts.ts b/e2e-tests/consts.ts index 805188ff..a5b0e510 100644 --- a/e2e-tests/consts.ts +++ b/e2e-tests/consts.ts @@ -2,13 +2,11 @@ export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; -export const ROCOCO_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9921'; +export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; -export const BOB_ROC_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; -export const FERDE_ROC_ADDR = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; -export const BOB_KAH_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; -export const FERDE_KAH_ADDR = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; +export const BOB_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; +export const FERDE_ADDR = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; export const ASSET_ID = 1; diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index 95b1f54e..694a9b1a 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -7,7 +7,7 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import { delay } from '../scripts/util'; import { constructApiPromise } from '../src'; import { balanceTracker, IBalance } from './balance'; -import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, ROCOCO_ASSET_HUB_WS_URL } from './consts'; +import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; import { assetTests, foreignAssetsTests, IndividualTest, liquidPoolsTests, localTests, tests } from './tests'; import { verification } from './verification'; @@ -16,7 +16,7 @@ const executor = async (testCase: string) => { let destWsUrl = ''; let testData: IndividualTest[] = []; - console.log(testCase) + console.log(testCase); await cryptoWaitReady(); @@ -70,10 +70,9 @@ const executor = async (testCase: string) => { destAddr = t.args[3]; assetIds = t.args[4].slice(1, -1).split(','); amounts = t.args[5].slice(1, -1).split(','); - opts = JSON.parse(t.args[6], (key, value) => { - return key === "paysWithFeeOrigin" ? JSON.stringify(value) : value; - }) as object; - + opts = JSON.parse(t.args[6], (key: string, value: string) => { + return key === 'paysWithFeeOrigin' ? JSON.stringify(value) : value; + }) as object; switch (originChainId) { case '0': @@ -83,7 +82,7 @@ const executor = async (testCase: string) => { originWsUrl = KUSAMA_ASSET_HUB_WS_URL; break; case '1836': - originWsUrl = ROCOCO_ASSET_HUB_WS_URL; + originWsUrl = TRAPPIST_WS_URL; break; case '4000': originWsUrl = MOONRIVER_WS_URL; @@ -101,7 +100,7 @@ const executor = async (testCase: string) => { destWsUrl = KUSAMA_ASSET_HUB_WS_URL; break; case '1836': - destWsUrl = ROCOCO_ASSET_HUB_WS_URL; + destWsUrl = TRAPPIST_WS_URL; break; case '4000': destWsUrl = MOONRIVER_WS_URL; @@ -110,7 +109,6 @@ const executor = async (testCase: string) => { } const { api, specName, safeXcmVersion } = await constructApiPromise(originWsUrl); - let sanitizedSpecName = originChainId === '1836' ? 'asset-hub-rococo' : specName; await api.isReady; const originApi = api; @@ -127,7 +125,7 @@ const executor = async (testCase: string) => { const originKeyring = keyring.addFromUri(originAddr); //eslint-disable-next-line @typescript-eslint/no-unsafe-call - await n[t.test](originKeyring, destChainId, destAddr, assetIds, amounts, opts, api, sanitizedSpecName, safeXcmVersion); + await n[t.test](originKeyring, destChainId, destAddr, assetIds, amounts, opts, api, specName, safeXcmVersion); await delay(24000); diff --git a/e2e-tests/tests/assets.ts b/e2e-tests/tests/assets.ts index baa0b557..998f73f9 100644 --- a/e2e-tests/tests/assets.ts +++ b/e2e-tests/tests/assets.ts @@ -18,9 +18,7 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe }, }; - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, - { injectedRegistry }); - + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { injectedRegistry }); return assetApi; }; diff --git a/e2e-tests/tests/foreignAssets.ts b/e2e-tests/tests/foreignAssets.ts index 988255d7..849bf089 100644 --- a/e2e-tests/tests/foreignAssets.ts +++ b/e2e-tests/tests/foreignAssets.ts @@ -18,9 +18,7 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe }, }; - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, - { injectedRegistry }); - + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { injectedRegistry }); return assetApi; }; diff --git a/e2e-tests/tests/index.ts b/e2e-tests/tests/index.ts index a16bf42f..2e2eacf1 100644 --- a/e2e-tests/tests/index.ts +++ b/e2e-tests/tests/index.ts @@ -4,7 +4,7 @@ export { assetTests } from './assets'; export { foreignAssetsTests } from './foreignAssets'; export { liquidPoolsTests } from './liquidPools'; export { localTests } from './local'; -import { BOB_KAH_ADDR, BOB_ROC_ADDR, FERDE_KAH_ADDR } from '../consts'; +import { BOB_ADDR, FERDE_ADDR } from '../consts'; export interface IndividualTest { test: string; @@ -29,7 +29,7 @@ export const tests: TestGroups = { '1836', '1000', '//Alice', - BOB_KAH_ADDR, + BOB_ADDR, '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "1836" }, { "GeneralIndex": "0" }]}}]', '[200000000000]', '{ "format": "submittable", "xcmVersion": 3 }', @@ -40,70 +40,53 @@ export const tests: TestGroups = { }, ], liquidPools: [ - // { - // // This will declare the call to use - // test: 'createLocalTransferTransaction', - // // This will be all the args for the above call - // args: [ - // '1000', - // '1000', - // '//Alice', - // BOB_KAH_ADDR, - // '[0]', - // '[2000]', - // '{ "format": "submittable", "transferLiquidToken": true }', - // ], - // // This will be a tuple that will allow us to verify if the xcm message - // // succesfully went through on the other end - // verification: ['[0]', '[2000]'], - // }, { // This will declare the call to use - test: 'createPayFeesTransaction', + test: 'createLocalTransferTransaction', // This will be all the args for the above call args: [ '1000', '1000', - '//Bob', - FERDE_KAH_ADDR, + '//Alice', + BOB_ADDR, '[0]', - '[30000]', - '{ "format": "payload", "xcmVersion": 3, "transferLiquidToken": true, "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}}, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }', + '[20000]', + '{ "format": "submittable", "transferLiquidToken": true }', ], // This will be a tuple that will allow us to verify if the xcm message // succesfully went through on the other end - verification: ['[0]', '[30000]'], + verification: ['[0]', '[2000]'], }, - ], - local: [ { // This will declare the call to use - test: 'createLocalTransferTransaction', + test: 'createPayFeesTransaction', // This will be all the args for the above call args: [ '1000', '1000', - '//Alice', - BOB_KAH_ADDR, - '[]', - '[10000000000000]', - '{ "format": "submittable", "keepAlive": true }', + '//Bob', + FERDE_ADDR, + '[0]', + '[3000000]', + '{ "format": "payload", "xcmVersion": 3, "transferLiquidToken": true, "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}}, "sendersAddr": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" }', ], // This will be a tuple that will allow us to verify if the xcm message // succesfully went through on the other end - verification: ['[0]', '[10000000000000]'], + verification: ['[0]', '[3000000]'], }, + ], + local: [ { // This will declare the call to use test: 'createLocalTransferTransaction', // This will be all the args for the above call args: [ - '1836', - '1836', + '1000', + '1000', '//Alice', - BOB_KAH_ADDR, + BOB_ADDR, '[]', - '[100000000000000000]', + '[100000000000]', '{ "format": "submittable", "keepAlive": true }', ], // This will be a tuple that will allow us to verify if the xcm message @@ -118,7 +101,7 @@ export const tests: TestGroups = { '0', '0', '//Alice', - BOB_KAH_ADDR, + BOB_ADDR, '[]', '[100000000000000000]', '{ "format": "submittable", "keepAlive": true }', @@ -137,7 +120,7 @@ export const tests: TestGroups = { '1000', '1000', '//Alice', - BOB_ROC_ADDR, + BOB_ADDR, '[1]', '[3000000000000]', '{ "format": "submittable", "keepAlive": true }', @@ -154,7 +137,7 @@ export const tests: TestGroups = { '1000', '1000', '//Bob', - FERDE_KAH_ADDR, + FERDE_ADDR, '[1]', '[200000000000]', '{ "format": "submittable", "keepAlive": true }', diff --git a/e2e-tests/tests/liquidPools.ts b/e2e-tests/tests/liquidPools.ts index f662d6ec..51d7086b 100644 --- a/e2e-tests/tests/liquidPools.ts +++ b/e2e-tests/tests/liquidPools.ts @@ -18,9 +18,7 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe }, }; - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, - { injectedRegistry }); - + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { injectedRegistry }); return assetApi; }; @@ -61,36 +59,17 @@ const createPayFeesTransaction = async ( ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); - let localTransferInfo: TxResult<'payload'>; + let transferInfo: TxResult<'payload'>; try { - let sender: string; - if (opts["sendersAddr"] === undefined) { - sender = '' - } else { - sender = opts["sendersAddr"]; - } - - localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - console.log(localTransferInfo.tx) + transferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + const payload = api.createType('ExtrinsicPayload', transferInfo.tx, { version: 4, - }) - - const message = payload.toU8a({ method: true }); - - const signat = origin.sign(message, { withType: true }); - - const extrinsic = api.createType( - 'Extrinsic', - { method: localTransferInfo.method }, - { version: 4 } - ).addSignature(sender, signat, localTransferInfo.tx); - - const tx = extrinsic.toHex() + }); - await api.rpc.author.submitExtrinsic(tx); + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + await api.tx(extrinsic).signAndSend(origin); } catch (e) { console.error(e); throw Error(e as string); diff --git a/e2e-tests/tests/local.ts b/e2e-tests/tests/local.ts index 4d1f9222..4ab1cdc7 100644 --- a/e2e-tests/tests/local.ts +++ b/e2e-tests/tests/local.ts @@ -7,7 +7,6 @@ import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { - const injectedRegistry = { rococo: { '1836': { @@ -20,9 +19,7 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe }, }; - const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, - { injectedRegistry }); - + const assetApi = new AssetTransferApi(api, specName, safeXcmVersion, { injectedRegistry }); return assetApi; }; diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts index 7e06af6f..286a89fe 100644 --- a/scripts/testNetworkForeignAssets.ts +++ b/scripts/testNetworkForeignAssets.ts @@ -18,7 +18,12 @@ const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { }, }; - const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata(rockmineMultilocatino, 'Asset Hub Rococo Hop', 'Hop', 12); + const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata( + rockmineMultilocatino, + 'Asset Hub Rococo Hop', + 'Hop', + 12, + ); const hexCall = assetHubApi.registry .createType('Call', { diff --git a/src/AssetTransferApi.ts b/src/AssetTransferApi.ts index 3005eeb9..53d60365 100644 --- a/src/AssetTransferApi.ts +++ b/src/AssetTransferApi.ts @@ -800,7 +800,7 @@ export class AssetTransferApi { 'CheckMortality', 'CheckNonce', 'CheckWeight', - 'ChargeTransactionPayment', + 'ChargeAssetTxPayment', ], tip: this._api.registry.createType('Compact', 0).toHex(), version: tx.version, @@ -898,20 +898,16 @@ export class AssetTransferApi { if (this._api.query.assetConversion !== undefined) { try { - for (const poolPairsData of await this._api.query.assetConversion.pools.keys()) { - const poolStorageKeyData = poolPairsData.toHuman(); + for (const poolPairsData of await this._api.query.assetConversion.pools.entries()) { + const tokenPairs = poolPairsData[0]; // remove any commas from multilocation key values e.g. Parachain: 2,125 -> Parachain: 2125 - const poolAssetDataStr = JSON.stringify(poolStorageKeyData).replace(/(\d),/g, '$1'); - const firstLpTokenSlice = poolAssetDataStr.slice(2, -2).slice(0, poolAssetDataStr.indexOf('},{"p') -1); - const secondLpTokenSlice = poolAssetDataStr.slice(2, -2).slice(poolAssetDataStr.indexOf('},{"p')); - - const firstLpToken = sanitizeKeys( - JSON.parse(firstLpTokenSlice), - ) as UnionXcmMultiLocation; - const secondLpToken = sanitizeKeys( - JSON.parse(secondLpTokenSlice), - ) as UnionXcmMultiLocation; + const sanitizedTokenPairs = JSON.stringify(tokenPairs).replace(/(\d),/g, '$1'); + const firstLpTokenSlice = sanitizedTokenPairs.slice(1, -1).slice(0, sanitizedTokenPairs.indexOf('},{"p')); + const secondLpTokenSlice = sanitizedTokenPairs.slice(1, -1).slice(sanitizedTokenPairs.indexOf(',{"p')); + + const firstLpToken = sanitizeKeys(JSON.parse(firstLpTokenSlice)) as UnionXcmMultiLocation; + const secondLpToken = sanitizeKeys(JSON.parse(secondLpTokenSlice)) as UnionXcmMultiLocation; if ( JSON.stringify(firstLpToken) == JSON.stringify(feeAsset) || diff --git a/zombienet/medium-network.toml b/zombienet/medium-network.toml index 66d76990..a7cd04ae 100644 --- a/zombienet/medium-network.toml +++ b/zombienet/medium-network.toml @@ -46,17 +46,17 @@ cumulus_based = true id = 1836 add_to_genesis = true cumulus_based = true -chain = "asset-hub-rococo-local" +chain = "trappist-local" [[parachains.collators]] name = "rockmine-collator01" - command = "./zombienet/bin/polkadot-parachain" + command = "./zombienet/bin/trappist-node" ws_port = 9920 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains.collators]] name = "rockmine-collator02" - command = "./zombienet/bin/polkadot-parachain" + command = "./zombienet/bin/trappist-node" ws_port = 9921 args = ["--log=xcm=trace,pallet-assets=trace"] From 729e79984813d2e7e27c0292470ea9f8e3cc6be2 Mon Sep 17 00:00:00 2001 From: bee344 Date: Fri, 12 Jan 2024 14:13:34 -0300 Subject: [PATCH 10/25] added logger --- e2e-tests/balance.ts | 1 - e2e-tests/executor.ts | 43 +++++++++++++++++------ e2e-tests/logger.ts | 73 +++++++++++++++++++++++++++++++++++++++ e2e-tests/verification.ts | 2 -- package.json | 5 ++- yarn.lock | 28 +++++++++++++++ 6 files changed, 137 insertions(+), 15 deletions(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index 0a707d61..d27694fc 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -40,7 +40,6 @@ export const balanceTracker = async ( if (!balance) { for (const assetId of assetIds) { accountInfo = await api.query.poolAssets.account(assetId, address); - console.log(accountInfo.value.toHuman()); if (accountInfo.isNone) { balances.initial.push([assetId, 0]); } else { diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index 694a9b1a..32039338 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -8,6 +8,7 @@ import { delay } from '../scripts/util'; import { constructApiPromise } from '../src'; import { balanceTracker, IBalance } from './balance'; import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; +import { startProgressBar, startTestLogger, terminateProgressBar, testResultLogger, updateProgressBar } from './logger'; import { assetTests, foreignAssetsTests, IndividualTest, liquidPoolsTests, localTests, tests } from './tests'; import { verification } from './verification'; @@ -16,7 +17,6 @@ const executor = async (testCase: string) => { let destWsUrl = ''; let testData: IndividualTest[] = []; - console.log(testCase); await cryptoWaitReady(); @@ -53,7 +53,6 @@ const executor = async (testCase: string) => { n = assetTests; break; } - console.log(n); let originChainId = ''; let destChainId = ''; @@ -62,6 +61,13 @@ const executor = async (testCase: string) => { let assetIds: string[] = []; let amounts: string[] = []; let opts: object = {}; + let counter: number = 0; + + startTestLogger(testCase); + + const progressBar = startProgressBar(testData, testCase); + + const results: [string, string, string, boolean][] = []; for (const t of testData) { originChainId = t.args[0]; @@ -73,40 +79,49 @@ const executor = async (testCase: string) => { opts = JSON.parse(t.args[6], (key: string, value: string) => { return key === 'paysWithFeeOrigin' ? JSON.stringify(value) : value; }) as object; + let chainName: string = ''; switch (originChainId) { case '0': originWsUrl = ROCOCO_ALICE_WS_URL; + chainName = 'Rococo'; break; case '1000': originWsUrl = KUSAMA_ASSET_HUB_WS_URL; + chainName = 'Kusama Asset Hub'; break; case '1836': originWsUrl = TRAPPIST_WS_URL; + chainName = 'Trappist'; break; case '4000': originWsUrl = MOONRIVER_WS_URL; + chainName = 'Moonriver'; break; } - if (originChainId == destChainId) { destWsUrl = originWsUrl; } else { switch (destChainId) { case '0': destWsUrl = ROCOCO_ALICE_WS_URL; + chainName = 'Rococo'; break; case '1000': destWsUrl = KUSAMA_ASSET_HUB_WS_URL; + chainName = 'Kusama Asset Hub'; break; case '1836': destWsUrl = TRAPPIST_WS_URL; + chainName = 'Trappist'; break; case '4000': destWsUrl = MOONRIVER_WS_URL; + chainName = 'Moonriver'; break; } } + const { api, specName, safeXcmVersion } = await constructApiPromise(originWsUrl); await api.isReady; @@ -139,19 +154,25 @@ const executor = async (testCase: string) => { const correctlyReceived = verification(assetIds, amounts, destFinalBalance); - for (let i = 0; i < assetIds.length; i++) { - if (correctlyReceived[i][1]) { - console.log('all good'); - } else { - console.log('badd'); - } - } - await delay(12000); await originApi.disconnect(); await destinationApi.disconnect(); + + counter += 1; + + updateProgressBar(counter, progressBar); + + for (let i = 0; i < assetIds.length; i++) { + results.push([t.test, assetIds[i], chainName, correctlyReceived[i][1]]); + } + } + + for (let i = 0; i < results.length; i++) { + testResultLogger(results[i][0], results[i][1], results[i][2], results[i][3]); } + + terminateProgressBar(progressBar, testCase); }; executor(process.argv[2]) diff --git a/e2e-tests/logger.ts b/e2e-tests/logger.ts index c9193b86..4de70a6d 100644 --- a/e2e-tests/logger.ts +++ b/e2e-tests/logger.ts @@ -1 +1,74 @@ // Copyright 2023 Parity Technologies (UK) Ltd. +import colors from 'ansi-colors'; +import chalk from 'chalk'; +import * as cliProgress from 'cli-progress'; +import { IndividualTest } from 'tests'; + +const defineTest = (testCase: string): string => { + let test: string = ''; + + switch (testCase) { + case '--foreign-assets': + test = 'Foreign Assets Transfers'; + break; + case '--liquidity-assets': + test = 'Liqudity Tokens Transfers'; + break; + case '--local': + test = 'Native Token Transfers'; + break; + case '--assets': + test = 'Local Assets Transfers'; + break; + } + return test; +}; + +export const startTestLogger = (testCase: string) => { + const test = defineTest(testCase); + + console.log(chalk.yellow(`Initializing tests for ${test}\n`)); +}; + +export const startProgressBar = (testData: IndividualTest[], testCase: string): cliProgress.SingleBar => { + const test = defineTest(testCase); + + const coverage: number = testData.length; + + const progressBar = new cliProgress.SingleBar({ + format: + `\n${test} Test Suite Progress |` + colors.cyan('{bar}') + '| {percentage}% || {value}/{total} tests covered \n', + barCompleteChar: '\u2588', + barIncompleteChar: '\u2591', + hideCursor: true, + }); + + progressBar.start(coverage, 0); + + return progressBar; +}; + +export const updateProgressBar = (counter: number, progressBar: cliProgress.SingleBar) => { + process.stdout.moveCursor(0, -2); + + process.stdout.clearLine(0); + + progressBar.increment(counter); +}; + +export const terminateProgressBar = (progressBar: cliProgress.SingleBar, testCase: string) => { + const test = defineTest(testCase); + console.log(chalk.yellow(`Test Suite for ${test} completed.\n`)); + + progressBar.stop(); + console.log('\n'); +}; + +export const testResultLogger = (testName: string, assetId: string, chainName: string, passed: boolean) => { + const tokenId = assetId === '' ? 'native asset' : `asset ${assetId}`; + if (passed) { + console.log(chalk.green(`Test ${testName} passed for ${chainName}'s ${tokenId} \u2705\n`)); + } else { + console.log(chalk.red(`Test ${testName} failed for ${chainName}'s ${tokenId} \u274E\n`)); + } +}; diff --git a/e2e-tests/verification.ts b/e2e-tests/verification.ts index 2e1470e1..196a9e58 100644 --- a/e2e-tests/verification.ts +++ b/e2e-tests/verification.ts @@ -5,8 +5,6 @@ export const verification = (assetIds: string[], amounts: string[], destBalance: const destInitialBalance: [string, number][] = destBalance.initial; const destFinalBalance: [string, number][] = destBalance.final; const correctlyReceived: [string, boolean][] = []; - console.log(destInitialBalance); - console.log(destFinalBalance); let check = true; for (let i = 0; i < assetIds.length; i++) { diff --git a/package.json b/package.json index 1433e553..833a07f5 100644 --- a/package.json +++ b/package.json @@ -41,10 +41,13 @@ "packageManager": "yarn@4.0.2", "devDependencies": { "@substrate/dev": "^0.7.1", + "@types/cli-progress": "^3", "chalk": "4.1.2", + "cli-progress": "^3.12.0", "typedoc": "^0.25.4", "typedoc-plugin-missing-exports": "^1.0.0", - "typedoc-theme-hierarchy": "^4.0.0" + "typedoc-theme-hierarchy": "^4.0.0", + "ansi-colors": "^4.1.3" }, "dependencies": { "@polkadot/api": "^10.11.2", diff --git a/yarn.lock b/yarn.lock index 4b13723c..f7c890f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1350,7 +1350,10 @@ __metadata: "@polkadot/api": "npm:^10.11.2" "@substrate/asset-transfer-api-registry": "npm:^0.2.11" "@substrate/dev": "npm:^0.7.1" + "@types/cli-progress": "npm:^3" + ansi-colors: "npm:^4.1.3" chalk: "npm:4.1.2" + cli-progress: "npm:^3.12.0" typedoc: "npm:^0.25.4" typedoc-plugin-missing-exports: "npm:^1.0.0" typedoc-theme-hierarchy: "npm:^4.0.0" @@ -1467,6 +1470,15 @@ __metadata: languageName: node linkType: hard +"@types/cli-progress@npm:^3": + version: 3.11.5 + resolution: "@types/cli-progress@npm:3.11.5" + dependencies: + "@types/node": "npm:*" + checksum: cb19187637b0a9b92219eab8d3d42250f1773328c24cb265d1bc677e3017f512e95e834e4846bcf0964efc232a13f86f7ef01843be804daa5433cc655c375bb3 + languageName: node + linkType: hard + "@types/graceful-fs@npm:^4.1.3": version: 4.1.6 resolution: "@types/graceful-fs@npm:4.1.6" @@ -1751,6 +1763,13 @@ __metadata: languageName: node linkType: hard +"ansi-colors@npm:^4.1.3": + version: 4.1.3 + resolution: "ansi-colors@npm:4.1.3" + checksum: 43d6e2fc7b1c6e4dc373de708ee76311ec2e0433e7e8bd3194e7ff123ea6a747428fc61afdcf5969da5be3a5f0fd054602bec56fc0ebe249ce2fcde6e649e3c2 + languageName: node + linkType: hard + "ansi-escapes@npm:^4.2.1": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -2155,6 +2174,15 @@ __metadata: languageName: node linkType: hard +"cli-progress@npm:^3.12.0": + version: 3.12.0 + resolution: "cli-progress@npm:3.12.0" + dependencies: + string-width: "npm:^4.2.3" + checksum: a6a549919a7461f5e798b18a4a19f83154bab145d3ec73d7f3463a8db8e311388c545ace1105557760a058cc4999b7f28c9d8d24d9783ee2912befb32544d4b8 + languageName: node + linkType: hard + "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" From 6730c621caef4685e7d907e25effa56f6ebc3dad Mon Sep 17 00:00:00 2001 From: bee344 Date: Fri, 12 Jan 2024 17:09:41 -0300 Subject: [PATCH 11/25] housekeeping and README --- README.md | 4 + e2e-tests/README.md | 36 +++++++++ e2e-tests/balance.ts | 12 ++- e2e-tests/consts.ts | 7 +- e2e-tests/executor.ts | 36 +++------ e2e-tests/logger.ts | 36 +++++++++ e2e-tests/tests/assets.ts | 32 ++++++-- e2e-tests/tests/foreignAssets.ts | 56 ++++++++++++-- e2e-tests/tests/index.ts | 105 +++++++++++++++----------- e2e-tests/tests/liquidPools.ts | 24 ++++-- e2e-tests/tests/local.ts | 111 ++++++++++++++++++++++++++-- e2e-tests/verification.ts | 8 ++ scripts/consts.ts | 2 +- scripts/testNetworkForeignAssets.ts | 54 +++++++------- scripts/testNetworkLiquidAssets.ts | 4 - zombienet/medium-network.toml | 18 ----- 16 files changed, 391 insertions(+), 154 deletions(-) create mode 100644 e2e-tests/README.md diff --git a/README.md b/README.md index 969b26e6..a05a0f95 100644 --- a/README.md +++ b/README.md @@ -323,3 +323,7 @@ From the root directory run `./ -p native spawn ./zombien ### Create an asset From the root directory run `yarn start:zombienet-post-script`. You can run this right after running your zombienet network. + +## E2E Testing + +You can access the E2E tests and its documentation [here](./e2e-tests/). diff --git a/e2e-tests/README.md b/e2e-tests/README.md new file mode 100644 index 00000000..55abafc5 --- /dev/null +++ b/e2e-tests/README.md @@ -0,0 +1,36 @@ +## E2E Tests + +End-to-end tests that run on a zombienet testnet. + +**NOTE: tested using polkadot v1.4.0** + +### Setup + +To setup the testing environment you need to first download the `polkadot`, `polkadot-execute-worker`, `polkadot-prepare-worker` and `polkadot-parachain` from the `polkadot-sdk` [release page](https://github.com/paritytech/polkadot-sdk/releases/latest), as well as the `trappist-node` from its [release page](https://github.com/paritytech/trappist/releases/latest), and place them in the `../zombienet/bin/` folder. + +You also need to have the latest `zombienet` executable in the `../zombienet/` folder, which you can download from [here](https://github.com/paritytech/zombienet/releases/latest). + +### Launching zombienet + +To launch the zombienet, all you need to do is run the following commands: +```bash +$ yarn build && yarn e2e:build +``` +Then you need to run: +```bash +$ yarn e2e:zombienet +``` +And this will launch the zombienet using the config file located in the `../zombienet/` directory. Once it finished its setup, you can proceed to the following step. + +### Launching the tests + +For testing, we provide 4 options: + +* Testing liquidity tokens transfers with the command `yarn e2e:liquidity-assets`. +* Testing foreign assets transfers with the command `yarn e2e:foreign-assets`. +* Testing local transferss with the command `yarn e2e:local`. +* Testing assets transfers with the command `yarn e2e:assets`. + +Each of these commands will run the appropiate script to setup the basics, located in `../scripts/`, wait for it to finish setting up the testing environment, and then go through the tests indicated in the `./tests/index.ts` file for the chosen option. + +After each testing suite has been completed, it's recommended to restart the zombienet before running another test suite. diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index d27694fc..cd387f47 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -8,6 +8,16 @@ export interface IBalance { final: [string, number][]; } +/** + * + * @param api api instance + * @param test name of the test currently being ran + * @param address address of the account whose balance is being queried + * @param assetIds Ids of the assets being queried + * @param balance initial balance for the account queried + * @returns instance of IBalance containing the initial and optionally the final + * balance of the account queried + */ export const balanceTracker = async ( api: ApiPromise, test: string, @@ -72,7 +82,7 @@ export const balanceTracker = async ( if (!balance) { for (const assetId of assetIds) { accountInfo = await api.query.assets.account(assetId, address); - if (accountInfo === null) { + if (accountInfo.isNone) { balances.initial.push([assetId, 0]); } else { balances.initial.push([assetId, accountInfo.unwrap().balance.toBn().toNumber()]); diff --git a/e2e-tests/consts.ts b/e2e-tests/consts.ts index a5b0e510..615f1672 100644 --- a/e2e-tests/consts.ts +++ b/e2e-tests/consts.ts @@ -3,13 +3,8 @@ export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; -export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; export const BOB_ADDR = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; export const FERDE_ADDR = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; -export const ASSET_ID = 1; - -export const MOONRIVER_ADDR = '5Eg2fnt8QeGtg4mcc5ELxPx6qxP2FSEWHbbYXENZ17ormkGP'; -export const TRAPPIST_ADDR = '5Eg2fntDDP4P8TjqRg3Jq89y5boE26JUMM3D7VU3bCAp76nc'; -export const ASSET_HUB_ADDR = '5Eg2fntNprdN3FgH4sfEaaZhYtddZQSQUqvYJ1f2mLtinVhV'; +export const EXTRINSIC_VERSION = 4; diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index 32039338..cb3a536f 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -7,7 +7,7 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import { delay } from '../scripts/util'; import { constructApiPromise } from '../src'; import { balanceTracker, IBalance } from './balance'; -import { KUSAMA_ASSET_HUB_WS_URL, MOONRIVER_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; +import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; import { startProgressBar, startTestLogger, terminateProgressBar, testResultLogger, updateProgressBar } from './logger'; import { assetTests, foreignAssetsTests, IndividualTest, liquidPoolsTests, localTests, tests } from './tests'; import { verification } from './verification'; @@ -54,13 +54,6 @@ const executor = async (testCase: string) => { break; } - let originChainId = ''; - let destChainId = ''; - let originAddr = ''; - let destAddr = ''; - let assetIds: string[] = []; - let amounts: string[] = []; - let opts: object = {}; let counter: number = 0; startTestLogger(testCase); @@ -70,13 +63,13 @@ const executor = async (testCase: string) => { const results: [string, string, string, boolean][] = []; for (const t of testData) { - originChainId = t.args[0]; - destChainId = t.args[1]; - originAddr = t.args[2]; - destAddr = t.args[3]; - assetIds = t.args[4].slice(1, -1).split(','); - amounts = t.args[5].slice(1, -1).split(','); - opts = JSON.parse(t.args[6], (key: string, value: string) => { + const originChainId: string = t.args[0]; + const destChainId: string = t.args[1]; + const originAddr: string = t.args[2]; + const destAddr: string = t.args[3]; + const assetIds: string[] = t.args[4].slice(1, -1).split(','); + const amounts: string[] = t.args[5].slice(1, -1).split(','); + const opts: object = JSON.parse(t.args[6], (key: string, value: string) => { return key === 'paysWithFeeOrigin' ? JSON.stringify(value) : value; }) as object; let chainName: string = ''; @@ -94,10 +87,6 @@ const executor = async (testCase: string) => { originWsUrl = TRAPPIST_WS_URL; chainName = 'Trappist'; break; - case '4000': - originWsUrl = MOONRIVER_WS_URL; - chainName = 'Moonriver'; - break; } if (originChainId == destChainId) { destWsUrl = originWsUrl; @@ -115,10 +104,6 @@ const executor = async (testCase: string) => { destWsUrl = TRAPPIST_WS_URL; chainName = 'Trappist'; break; - case '4000': - destWsUrl = MOONRIVER_WS_URL; - chainName = 'Moonriver'; - break; } } @@ -152,9 +137,10 @@ const executor = async (testCase: string) => { destInitialBalance, ); - const correctlyReceived = verification(assetIds, amounts, destFinalBalance); + const verificationAssetIds: string[] = t.verification[0].slice(1, -1).split(','); + const verificationAmounts: string[] = t.verification[1].slice(1, -1).split(','); - await delay(12000); + const correctlyReceived = verification(verificationAssetIds, verificationAmounts, destFinalBalance); await originApi.disconnect(); await destinationApi.disconnect(); diff --git a/e2e-tests/logger.ts b/e2e-tests/logger.ts index 4de70a6d..4076d53d 100644 --- a/e2e-tests/logger.ts +++ b/e2e-tests/logger.ts @@ -4,6 +4,11 @@ import chalk from 'chalk'; import * as cliProgress from 'cli-progress'; import { IndividualTest } from 'tests'; +/** + * + * @param testCase a string containing the test option selected + * @returns a prettified version of the testCase + */ const defineTest = (testCase: string): string => { let test: string = ''; @@ -24,12 +29,26 @@ const defineTest = (testCase: string): string => { return test; }; +/** + * Calls defineTest and prints a message signaling the begining of the tests + * @param testCase a string containing the test option selected + */ export const startTestLogger = (testCase: string) => { const test = defineTest(testCase); console.log(chalk.yellow(`Initializing tests for ${test}\n`)); }; +/** + * This creates and starts an instance of cliProgress containing a SingleBar to + * display the test suite's progress + * + * @param testData an array containing the individual tests for the test suite + * selected + * @param testCase the test suite selected + * @returns an instance of the cliProgress that will be used to track the progress + * of the tests + */ export const startProgressBar = (testData: IndividualTest[], testCase: string): cliProgress.SingleBar => { const test = defineTest(testCase); @@ -48,6 +67,11 @@ export const startProgressBar = (testData: IndividualTest[], testCase: string): return progressBar; }; +/** + * Clears the progress bar in place and prints an updated version + * @param counter current test number + * @param progressBar instance of the cliProgress + */ export const updateProgressBar = (counter: number, progressBar: cliProgress.SingleBar) => { process.stdout.moveCursor(0, -2); @@ -56,6 +80,11 @@ export const updateProgressBar = (counter: number, progressBar: cliProgress.Sing progressBar.increment(counter); }; +/** + * Terminates the cliProgess instance. It's called after the test suite is over + * @param progressBar instance of cliProgress to be terminated + * @param testCase + */ export const terminateProgressBar = (progressBar: cliProgress.SingleBar, testCase: string) => { const test = defineTest(testCase); console.log(chalk.yellow(`Test Suite for ${test} completed.\n`)); @@ -64,6 +93,13 @@ export const terminateProgressBar = (progressBar: cliProgress.SingleBar, testCas console.log('\n'); }; +/** + * + * @param testName current test's name + * @param assetId Id of the asset tested against + * @param chainName Name of the chain against the test ran + * @param passed whether the test passed or failed + */ export const testResultLogger = (testName: string, assetId: string, chainName: string, passed: boolean) => { const tokenId = assetId === '' ? 'native asset' : `asset ${assetId}`; if (passed) { diff --git a/e2e-tests/tests/assets.ts b/e2e-tests/tests/assets.ts index 998f73f9..7a2f3b6d 100644 --- a/e2e-tests/tests/assets.ts +++ b/e2e-tests/tests/assets.ts @@ -1,6 +1,7 @@ // Copyright 2023 Parity Technologies (UK) Ltd. import { ApiPromise } from '@polkadot/api'; import { KeyringPair } from '@polkadot/keyring/types'; +import { EXTRINSIC_VERSION } from 'consts'; import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; @@ -9,10 +10,10 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe const injectedRegistry = { rococo: { '1836': { - tokens: ['ROC'], + tokens: ['HOP'], assetsInfo: {}, foreignAssetsInfo: {}, - specName: 'asset-hub-rococo', + specName: 'trappist-rococo', poolPairsInfo: {}, }, }, @@ -36,10 +37,17 @@ const createLocalSystemAssetsTransferTransaction = async ( ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); - let localTransfer: TxResult<'submittable'>; + let localTransferInfo: TxResult<'payload'>; try { - localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - await localTransfer.tx.signAndSend(origin); + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); } catch (e) { console.error(e); throw Error(e as string); @@ -59,15 +67,23 @@ const createPayFeesTransaction = async ( ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); - let localTransfer: TxResult<'submittable'>; + let localTransferInfo: TxResult<'payload'>; try { - localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - await localTransfer.tx.signAndSend(origin); + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); } catch (e) { console.error(e); throw Error(e as string); } }; + export const assetTests: { [K: string]: Function } = { createLocalSystemAssetsTransferTransaction, createPayFeesTransaction, diff --git a/e2e-tests/tests/foreignAssets.ts b/e2e-tests/tests/foreignAssets.ts index 849bf089..0efdc03e 100644 --- a/e2e-tests/tests/foreignAssets.ts +++ b/e2e-tests/tests/foreignAssets.ts @@ -1,6 +1,7 @@ // Copyright 2023 Parity Technologies (UK) Ltd. import { ApiPromise } from '@polkadot/api'; import { KeyringPair } from '@polkadot/keyring/types'; +import { EXTRINSIC_VERSION } from 'consts'; import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; @@ -9,10 +10,10 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe const injectedRegistry = { rococo: { '1836': { - tokens: ['ROC'], + tokens: ['HOP'], assetsInfo: {}, foreignAssetsInfo: {}, - specName: 'asset-hub-rococo', + specName: 'trappist-rococo', poolPairsInfo: {}, }, }, @@ -23,7 +24,7 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe return assetApi; }; -const createTransferTransaction = async ( +const createForeignTransferTransaction = async ( origin: KeyringPair, destChainId: string, destAddr: string, @@ -36,13 +37,54 @@ const createTransferTransaction = async ( ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); - let localTransfer: TxResult<'submittable'>; + let localTransferInfo: TxResult<'payload'>; try { - localTransfer = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - await localTransfer.tx.signAndSend(origin); + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); } catch (e) { console.error(e); throw Error(e as string); } }; -export const foreignAssetsTests: { [K: string]: Function } = { createTransferTransaction }; + +const createLocalForeignTransferTransaction = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: object, + api: ApiPromise, + specName: string, + safeXcmVersion: number, +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'payload'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +export const foreignAssetsTests: { [K: string]: Function } = { + createForeignTransferTransaction, + createLocalForeignTransferTransaction, +}; diff --git a/e2e-tests/tests/index.ts b/e2e-tests/tests/index.ts index 2e2eacf1..b1c8cc82 100644 --- a/e2e-tests/tests/index.ts +++ b/e2e-tests/tests/index.ts @@ -22,28 +22,41 @@ export interface TestGroups { export const tests: TestGroups = { foreignAssets: [ { - // This will declare the call to use - test: 'createTransferTransactionCall', - // This will be all the args for the above call + test: 'createForeignTransferTransaction', args: [ - '1836', '1000', + '1836', '//Alice', BOB_ADDR, + '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "1836" }, { "GeneralIndex": "0" }]}}]', + '[200000000]', + '{ "format": "payload", "xcmVersion": 3, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }', + ], + verification: [ + '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "1836" }, { "GeneralIndex": "0" }]}}]', + '[200000000]', + ], + }, + { + test: 'createLocalForeignTransferTransaction', + args: [ + '1000', + '1000', + '//Alice', + FERDE_ADDR, + '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "1836" }, { "GeneralIndex": "0" }]}}]', + '[200000000000]', + '{ "format": "payload", "xcmVersion": 3, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }', + ], + verification: [ '[{ "parents": "1", "interior": { "X2": [{ "Parachain": "1836" }, { "GeneralIndex": "0" }]}}]', '[200000000000]', - '{ "format": "submittable", "xcmVersion": 3 }', ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['', ''], }, ], liquidPools: [ { - // This will declare the call to use test: 'createLocalTransferTransaction', - // This will be all the args for the above call args: [ '1000', '1000', @@ -51,16 +64,12 @@ export const tests: TestGroups = { BOB_ADDR, '[0]', '[20000]', - '{ "format": "submittable", "transferLiquidToken": true }', + '{ "format": "payload", "keepAlive": true, "transferLiquidToken": true, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }', ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[0]', '[2000]'], + verification: ['[0]', '[20000]'], }, { - // This will declare the call to use test: 'createPayFeesTransaction', - // This will be all the args for the above call args: [ '1000', '1000', @@ -68,18 +77,14 @@ export const tests: TestGroups = { FERDE_ADDR, '[0]', '[3000000]', - '{ "format": "payload", "xcmVersion": 3, "transferLiquidToken": true, "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}}, "sendersAddr": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" }', + '{ "format": "payload", "keepAlive": true, "transferLiquidToken": true, "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}}, "sendersAddr": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" }', ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end verification: ['[0]', '[3000000]'], }, ], local: [ { - // This will declare the call to use test: 'createLocalTransferTransaction', - // This will be all the args for the above call args: [ '1000', '1000', @@ -87,16 +92,12 @@ export const tests: TestGroups = { BOB_ADDR, '[]', '[100000000000]', - '{ "format": "submittable", "keepAlive": true }', + '{ "format": "payload", "keepAlive": true, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }', ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[0]', '[10000000000000]'], + verification: ['[]', '[100000000000]'], }, { - // This will declare the call to use - test: 'createLocalTransferTransaction', - // This will be all the args for the above call + test: 'createLocalTransferTransactionWithFees', args: [ '0', '0', @@ -104,18 +105,40 @@ export const tests: TestGroups = { BOB_ADDR, '[]', '[100000000000000000]', - '{ "format": "submittable", "keepAlive": true }', + '{ "format": "payload", "keepAlive": true, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}} }', + ], + verification: ['[]', '[10000000000000]'], + }, + { + test: 'createLimitedNativeTransferToRelay', + args: [ + '1000', + '0', + '//Alice', + BOB_ADDR, + '[]', + '[1000000000000000]', + '{ "format": "payload", "keepAlive": true, "xcmVersion": 3, "isLimited": true, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}} }', + ], + verification: ['[]', '[1000000000000000]'], + }, + { + test: 'createLimitedNativeTransferToSystem', + args: [ + '0', + '1000', + '//Bob', + FERDE_ADDR, + '[]', + '[210000000000000]', + '{ "format": "payload", "keepAlive": true, "xcmVersion": 3, "isLimited": true, "weightLimit": {"refTime": "10000" , "proofSize": "3000"}, "sendersAddr": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}} }', ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[0]', '[10000000000000]'], + verification: ['[]', '[210000000000000]'], }, ], assets: [ { - // This will declare the call to use test: 'createLocalSystemAssetsTransferTransaction', - // This will be all the args for the above call args: [ '1000', '1000', @@ -123,16 +146,12 @@ export const tests: TestGroups = { BOB_ADDR, '[1]', '[3000000000000]', - '{ "format": "submittable", "keepAlive": true }', + '{ "format": "payload", "keepAlive": true, "sendersAddr": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }', ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[1]', '[30000]'], + verification: ['[1]', '[3000000000000]'], }, { - // This will declare the call to use test: 'createPayFeesTransaction', - // This will be all the args for the above call args: [ '1000', '1000', @@ -140,11 +159,9 @@ export const tests: TestGroups = { FERDE_ADDR, '[1]', '[200000000000]', - '{ "format": "submittable", "keepAlive": true }', + '{ "format": "payload", "keepAlive": false, "sendersAddr": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", "paysWithFeeOrigin": { "parents": "0", "interior": { "X2": [{"PalletInstance": "50"}, { "GeneralIndex": "1" }]}} }', ], - // This will be a tuple that will allow us to verify if the xcm message - // succesfully went through on the other end - verification: ['[1]', '[2000]'], + verification: ['[1]', '[200000000000]'], }, ], }; diff --git a/e2e-tests/tests/liquidPools.ts b/e2e-tests/tests/liquidPools.ts index 51d7086b..49683064 100644 --- a/e2e-tests/tests/liquidPools.ts +++ b/e2e-tests/tests/liquidPools.ts @@ -4,15 +4,16 @@ import { KeyringPair } from '@polkadot/keyring/types'; import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; +import { EXTRINSIC_VERSION } from '../consts'; const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: number): AssetTransferApi => { const injectedRegistry = { rococo: { '1836': { - tokens: ['ROC'], + tokens: ['HOP'], assetsInfo: {}, foreignAssetsInfo: {}, - specName: 'asset-hub-rococo', + specName: 'trappist-rococo', poolPairsInfo: {}, }, }, @@ -36,10 +37,17 @@ const createLocalTransferTransaction = async ( ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); - let localTransferInfo: TxResult<'submittable'>; + let localTransferInfo: TxResult<'payload'>; try { localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - await localTransferInfo.tx.signAndSend(origin); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); } catch (e) { console.error(e); throw Error(e as string); @@ -59,12 +67,12 @@ const createPayFeesTransaction = async ( ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); - let transferInfo: TxResult<'payload'>; + let transferWithFeesInfo: TxResult<'payload'>; try { - transferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + transferWithFeesInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - const payload = api.createType('ExtrinsicPayload', transferInfo.tx, { - version: 4, + const payload = api.createType('ExtrinsicPayload', transferWithFeesInfo.tx, { + version: EXTRINSIC_VERSION, }); const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); diff --git a/e2e-tests/tests/local.ts b/e2e-tests/tests/local.ts index 4ab1cdc7..5cc3aec4 100644 --- a/e2e-tests/tests/local.ts +++ b/e2e-tests/tests/local.ts @@ -2,6 +2,7 @@ import { ApiPromise } from '@polkadot/api'; import { KeyringPair } from '@polkadot/keyring/types'; +import { EXTRINSIC_VERSION } from 'consts'; import { AssetTransferApi } from '../../src'; import { TxResult } from '../../src/types'; @@ -10,10 +11,10 @@ const createAssetApi = (api: ApiPromise, specName: string, safeXcmVersion: numbe const injectedRegistry = { rococo: { '1836': { - tokens: ['ROC'], + tokens: ['HOP'], assetsInfo: {}, foreignAssetsInfo: {}, - specName: 'asset-hub-rococo', + specName: 'trappist-rococo', poolPairsInfo: {}, }, }, @@ -30,17 +31,114 @@ const createLocalTransferTransaction = async ( destAddr: string, assetIds: string[], amounts: string[], - opts: object, + opts: {}, api: ApiPromise, specName: string, safeXcmVersion: number, ) => { const assetApi = createAssetApi(api, specName, safeXcmVersion); - let localTransferInfo: TxResult<'submittable'>; + let localTransferInfo: TxResult<'payload'>; try { localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); - await localTransferInfo.tx.signAndSend(origin); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +const createLocalTransferTransactionWithFees = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: {}, + api: ApiPromise, + specName: string, + safeXcmVersion: number, +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'payload'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +const createLimitedNativeTransferToRelay = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: {}, + api: ApiPromise, + specName: string, + safeXcmVersion: number, +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'payload'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); + } catch (e) { + console.error(e); + throw Error(e as string); + } +}; + +const createLimitedNativeTransferToSystem = async ( + origin: KeyringPair, + destChainId: string, + destAddr: string, + assetIds: string[], + amounts: string[], + opts: {}, + api: ApiPromise, + specName: string, + safeXcmVersion: number, +) => { + const assetApi = createAssetApi(api, specName, safeXcmVersion); + + let localTransferInfo: TxResult<'payload'>; + try { + localTransferInfo = await assetApi.createTransferTransaction(destChainId, destAddr, assetIds, amounts, opts); + + const payload = api.createType('ExtrinsicPayload', localTransferInfo.tx, { + version: EXTRINSIC_VERSION, + }); + + const extrinsic = api.registry.createType('Extrinsic', { method: payload.method }, { version: 4 }); + + await api.tx(extrinsic).signAndSend(origin); } catch (e) { console.error(e); throw Error(e as string); @@ -49,4 +147,7 @@ const createLocalTransferTransaction = async ( export const localTests: { [K: string]: Function } = { createLocalTransferTransaction, + createLocalTransferTransactionWithFees, + createLimitedNativeTransferToRelay, + createLimitedNativeTransferToSystem, }; diff --git a/e2e-tests/verification.ts b/e2e-tests/verification.ts index 196a9e58..99a88a4e 100644 --- a/e2e-tests/verification.ts +++ b/e2e-tests/verification.ts @@ -1,6 +1,14 @@ // Copyright 2023 Parity Technologies (UK) Ltd. import { IBalance } from './balance'; +/** + * This function verifies whether the test transaction impacted the destination's + * account balance + * @param assetIds assets to be queried + * @param amounts expected final balance + * @param destBalance stored queried balance + * @returns whetere the balance was modified as expected or not + */ export const verification = (assetIds: string[], amounts: string[], destBalance: IBalance) => { const destInitialBalance: [string, number][] = destBalance.initial; const destFinalBalance: [string, number][] = destBalance.final; diff --git a/scripts/consts.ts b/scripts/consts.ts index 721f697b..1a3e85ab 100644 --- a/scripts/consts.ts +++ b/scripts/consts.ts @@ -2,5 +2,5 @@ export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; -export const ROCOCO_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9921'; +export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts index 286a89fe..a8ff4d34 100644 --- a/scripts/testNetworkForeignAssets.ts +++ b/scripts/testNetworkForeignAssets.ts @@ -5,11 +5,11 @@ import { Keyring } from '@polkadot/keyring'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; -import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL, ROCOCO_ASSET_HUB_WS_URL } from './consts'; +import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL, TRAPPIST_WS_URL } from './consts'; import { awaitBlockProduction, awaitEpochChange, delay, logWithDate } from './util'; const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { - const rockmineMultilocatino = { + const trappistMultilocation = { parents: 1, interior: { X1: { @@ -19,7 +19,7 @@ const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { }; const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata( - rockmineMultilocatino, + trappistMultilocation, 'Asset Hub Rococo Hop', 'Hop', 12, @@ -36,17 +36,17 @@ const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { }; const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { - const rockmineMultilocatino = { + const trappistMultilocation = { parents: 1, interior: { X1: { - parachain: 3000, + parachain: 1836, }, }, }; const createTx = assetHubApi.tx.foreignAssets.create( - rockmineMultilocatino, + trappistMultilocation, '5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', // Sibling 1836 -> ParaId '100000000000', ); @@ -61,13 +61,13 @@ const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { return hexCall; }; -const sudoCallWrapper = (rockmineApi: ApiPromise, call: `0x${string}`) => { +const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { // Double encode the call - const xcmDoubleEncoded = rockmineApi.createType('XcmDoubleEncoded', { + const xcmDoubleEncoded = trappistApi.createType('XcmDoubleEncoded', { encoded: call, }); - const xcmOriginType = rockmineApi.createType('XcmOriginKind', 'Xcm'); + const xcmOriginType = trappistApi.createType('XcmOriginKind', 'Xcm'); const xcmDestMultiLocation = { V3: { parents: 1, @@ -145,8 +145,8 @@ const sudoCallWrapper = (rockmineApi: ApiPromise, call: `0x${string}`) => { }, ], }; - const xcmMsg = rockmineApi.tx.polkadotXcm.send(xcmDestMultiLocation, xcmMessage); - const xcmCall = rockmineApi.createType('Call', { + const xcmMsg = trappistApi.tx.polkadotXcm.send(xcmDestMultiLocation, xcmMessage); + const xcmCall = trappistApi.createType('Call', { callIndex: xcmMsg.callIndex, args: xcmMsg.args, }); @@ -154,14 +154,14 @@ const sudoCallWrapper = (rockmineApi: ApiPromise, call: `0x${string}`) => { return xcmCall; }; -const createForeignAssetViaSudo = (assetHubApi: ApiPromise, rockmineApi: ApiPromise) => { +const createForeignAssetViaSudo = (assetHubApi: ApiPromise, trappistApi: ApiPromise) => { const foreignAssetCreateCall = fAssetCreateCall(assetHubApi); - return sudoCallWrapper(rockmineApi, foreignAssetCreateCall); + return sudoCallWrapper(trappistApi, foreignAssetCreateCall); }; -const setMetadataForeignAssetViaSudo = (assetHubApi: ApiPromise, rockmineApi: ApiPromise) => { +const setMetadataForeignAssetViaSudo = (assetHubApi: ApiPromise, trappistApi: ApiPromise) => { const setMetadataCall = fAssetSetMetadataCall(assetHubApi); - return sudoCallWrapper(rockmineApi, setMetadataCall); + return sudoCallWrapper(trappistApi, setMetadataCall); }; const openHrmpChannels = (api: ApiPromise, sender: number, receiver: number) => { @@ -184,13 +184,13 @@ const main = async () => { await kusamaAssetHubApi.isReady; logWithDate(chalk.green('Created a connection to Kusama AssetHub')); - const rockmineApi = await ApiPromise.create({ - provider: new WsProvider(ROCOCO_ASSET_HUB_WS_URL), + const trappistApi = await ApiPromise.create({ + provider: new WsProvider(TRAPPIST_WS_URL), noInitWarn: true, }); - await rockmineApi.isReady; - logWithDate(chalk.green('Created a connection to Rococo Asset Hub')); + await trappistApi.isReady; + logWithDate(chalk.green('Created a connection to Trappist')); const relayApi = await ApiPromise.create({ provider: new WsProvider(ROCOCO_ALICE_WS_URL), @@ -213,23 +213,23 @@ const main = async () => { await awaitEpochChange(relayApi); logWithDate(chalk.magenta('HRMP channels open')); - logWithDate(chalk.magenta('Sending funds to Rococo Asset Hub Sibling on Kusama AssetHub')); + logWithDate(chalk.magenta('Sending funds to Trappist Sibling on Kusama AssetHub')); await kusamaAssetHubApi.tx.balances .transferKeepAlive('5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', 10000000000000) .signAndSend(bob); - const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo(kusamaAssetHubApi, rockmineApi); + const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo(kusamaAssetHubApi, trappistApi); logWithDate('Sending Sudo XCM message from relay chain to execute create foreign asset call on Kusama AssetHub'); - await rockmineApi.tx.sudo.sudo(foreignAssetsCreateSudoXcmCall).signAndSend(alice); + await trappistApi.tx.sudo.sudo(foreignAssetsCreateSudoXcmCall).signAndSend(alice); await delay(24000); - const foreignAssetsSetMetadataSudoXcmCall = setMetadataForeignAssetViaSudo(kusamaAssetHubApi, rockmineApi); + const foreignAssetsSetMetadataSudoXcmCall = setMetadataForeignAssetViaSudo(kusamaAssetHubApi, trappistApi); logWithDate('Sending Sudo XCM message from relay chain to execute setMetadata call on Kusama AssetHub'); - await rockmineApi.tx.sudo.sudo(foreignAssetsSetMetadataSudoXcmCall).signAndSend(alice); + await trappistApi.tx.sudo.sudo(foreignAssetsSetMetadataSudoXcmCall).signAndSend(alice); await delay(24000); @@ -237,13 +237,13 @@ const main = async () => { logWithDate(chalk.blue('Polkadot-js successfully disconnected from asset-hub')); }); - await rockmineApi.disconnect().then(() => { - logWithDate(chalk.blue('Polkadot-js successfully disconnected from Rococo Asset Hub')); + await trappistApi.disconnect().then(() => { + logWithDate(chalk.blue('Polkadot-js successfully disconnected from Trappist')); }); }; // eslint-disable-next-line @typescript-eslint/no-floating-promises -awaitBlockProduction(ROCOCO_ASSET_HUB_WS_URL).then(async () => { +awaitBlockProduction(TRAPPIST_WS_URL).then(async () => { await main() .catch(console.error) .finally(() => process.exit()); diff --git a/scripts/testNetworkLiquidAssets.ts b/scripts/testNetworkLiquidAssets.ts index 970fc48a..00c2e8cd 100644 --- a/scripts/testNetworkLiquidAssets.ts +++ b/scripts/testNetworkLiquidAssets.ts @@ -81,11 +81,7 @@ const main = async () => { const hrmpChannelCalls = []; hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1000), Number(1836))); - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1000), Number(4000))); hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1836), Number(1000))); - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(1836), Number(4000))); - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(4000), Number(1000))); - hrmpChannelCalls.push(openHrmpChannels(relayApi, Number(4000), Number(1836))); await relayApi.tx.sudo.sudo(relayApi.tx.utility.batchAll(hrmpChannelCalls)).signAndSend(alice); diff --git a/zombienet/medium-network.toml b/zombienet/medium-network.toml index a7cd04ae..ba485038 100644 --- a/zombienet/medium-network.toml +++ b/zombienet/medium-network.toml @@ -60,24 +60,6 @@ chain = "trappist-local" ws_port = 9921 args = ["--log=xcm=trace,pallet-assets=trace"] -[[parachains]] -id = 4000 -add_to_genesis = true -cumulus_based = true -chain = "moonriver-local" - - [[parachains.collators]] - name = "moonriver-collator01" - command = "./zombienet/bin/moonbeam" - ws_port = 9930 - args = ["--log=xcm=trace,pallet-assets=trace"] - - [[parachains.collators]] - name = "moonriver-collator02" - command = "./zombienet/bin/moonbeam" - ws_port = 9931 - args = ["--log=xcm=trace,pallet-assets=trace"] - [types.Header] number = "u64" parent_hash = "Hash" From e1ac10df2d8fd2b51c74926b288b95178e253a65 Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:44:13 -0500 Subject: [PATCH 12/25] Update medium-network.toml --- zombienet/medium-network.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zombienet/medium-network.toml b/zombienet/medium-network.toml index ba485038..b7fd3af2 100644 --- a/zombienet/medium-network.toml +++ b/zombienet/medium-network.toml @@ -49,13 +49,13 @@ cumulus_based = true chain = "trappist-local" [[parachains.collators]] - name = "rockmine-collator01" + name = "trappist-collator01" command = "./zombienet/bin/trappist-node" ws_port = 9920 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains.collators]] - name = "rockmine-collator02" + name = "trappist-collator02" command = "./zombienet/bin/trappist-node" ws_port = 9921 args = ["--log=xcm=trace,pallet-assets=trace"] From 0f9cd83e1b0e538c5a88bfb472a751c2a41d83c0 Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:45:10 -0500 Subject: [PATCH 13/25] Update consts.ts --- scripts/consts.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/consts.ts b/scripts/consts.ts index 1a3e85ab..fac167a5 100644 --- a/scripts/consts.ts +++ b/scripts/consts.ts @@ -3,4 +3,3 @@ export const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; export const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; export const TRAPPIST_WS_URL = 'ws://127.0.0.1:9921'; -export const MOONRIVER_WS_URL = 'ws://127.0.0.1:9931'; From 63df018f3e79f01cef5ecca47bcd1e990e46e132 Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:46:15 -0500 Subject: [PATCH 14/25] Added end of file newline to zombienet.sh --- e2e-tests/zombienet.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-tests/zombienet.sh b/e2e-tests/zombienet.sh index 0bcb857c..2f7831df 100755 --- a/e2e-tests/zombienet.sh +++ b/e2e-tests/zombienet.sh @@ -11,4 +11,4 @@ fi sed -i 's="./zombienet/zombienet": .*"="./zombienet/zombienet": "'$os' -p native spawn ./zombienet/medium-network.toml"=' package.json -yarn run zombienet \ No newline at end of file +yarn run zombienet From 7559b414f4ec6a95b6eefda31f5c8e7f831198a3 Mon Sep 17 00:00:00 2001 From: bee344 Date: Mon, 29 Jan 2024 12:06:39 -0300 Subject: [PATCH 15/25] modified configs to work with v1.6 --- zombienet/medium-network.toml | 10 +++++----- zombienet/small-network.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/zombienet/medium-network.toml b/zombienet/medium-network.toml index ba485038..6bec642d 100644 --- a/zombienet/medium-network.toml +++ b/zombienet/medium-network.toml @@ -27,17 +27,17 @@ chain = "rococo-local" [[parachains]] id = 1000 addToGenesis = true -chain = "statemine-local" +chain = "asset-hub-rococo-local" cumulus_based = true [[parachains.collators]] - name = "statemine-collator01" + name = "asset-hub-rococo-collator01" command = "./zombienet/bin/polkadot-parachain" args = ["--log=xcm=trace,pallet-assets=trace"] ws_port = 9910 [[parachains.collators]] - name = "statemine-collator02" + name = "asset-hub-rococo-collator02" command = "./zombienet/bin/polkadot-parachain" ws_port = 9911 args = ["--log=xcm=trace,pallet-assets=trace"] @@ -49,13 +49,13 @@ cumulus_based = true chain = "trappist-local" [[parachains.collators]] - name = "rockmine-collator01" + name = "trappist-collator01" command = "./zombienet/bin/trappist-node" ws_port = 9920 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains.collators]] - name = "rockmine-collator02" + name = "trappist-collator02" command = "./zombienet/bin/trappist-node" ws_port = 9921 args = ["--log=xcm=trace,pallet-assets=trace"] diff --git a/zombienet/small-network.toml b/zombienet/small-network.toml index fea80e04..725f6716 100644 --- a/zombienet/small-network.toml +++ b/zombienet/small-network.toml @@ -27,7 +27,7 @@ chain = "rococo-local" [[parachains]] id = 1000 addToGenesis = true -chain = "statemine-local" +chain = "asset-hub-rococo-local" cumulus_based = true [[parachains.collators]] From 2d19a0b47ae9a313d8795f0b907e67aed154194c Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:48:24 -0300 Subject: [PATCH 16/25] Update e2e-tests/README.md Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> --- e2e-tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-tests/README.md b/e2e-tests/README.md index 55abafc5..f5d52e70 100644 --- a/e2e-tests/README.md +++ b/e2e-tests/README.md @@ -12,7 +12,7 @@ You also need to have the latest `zombienet` executable in the `../zombienet/` f ### Launching zombienet -To launch the zombienet, all you need to do is run the following commands: +To launch the zombienet run the following commands: ```bash $ yarn build && yarn e2e:build ``` From d96e7c95936ff4c00bb8f0ae4487a291f91e4bc4 Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:48:32 -0300 Subject: [PATCH 17/25] Update e2e-tests/README.md Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> --- e2e-tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-tests/README.md b/e2e-tests/README.md index f5d52e70..638ee213 100644 --- a/e2e-tests/README.md +++ b/e2e-tests/README.md @@ -16,7 +16,7 @@ To launch the zombienet run the following commands: ```bash $ yarn build && yarn e2e:build ``` -Then you need to run: +Then run: ```bash $ yarn e2e:zombienet ``` From 5a8224a4ebf8ec65e85a983818bf691459572fa7 Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:49:03 -0300 Subject: [PATCH 18/25] Update e2e-tests/balance.ts Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> --- e2e-tests/balance.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index cd387f47..a4949ab7 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -3,6 +3,7 @@ import { ApiPromise } from '@polkadot/api'; import type { FrameSystemAccountInfo, PalletAssetsAssetAccount } from '@polkadot/types/lookup'; import type { Option } from '@polkadot/types-codec'; + export interface IBalance { initial: [string, number][]; final: [string, number][]; From 8b28df4f98ef3104627850217bd33cf52342b7da Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:49:42 -0300 Subject: [PATCH 19/25] Update e2e-tests/executor.ts Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> --- e2e-tests/executor.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index cb3a536f..2d11eaea 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -15,7 +15,6 @@ import { verification } from './verification'; const executor = async (testCase: string) => { let originWsUrl = ''; let destWsUrl = ''; - let testData: IndividualTest[] = []; await cryptoWaitReady(); From 95209021cc59c9c565c8d8b72527e4ba1589627c Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:50:09 -0300 Subject: [PATCH 20/25] Grammar Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> --- e2e-tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-tests/README.md b/e2e-tests/README.md index 638ee213..b4ccded8 100644 --- a/e2e-tests/README.md +++ b/e2e-tests/README.md @@ -31,6 +31,6 @@ For testing, we provide 4 options: * Testing local transferss with the command `yarn e2e:local`. * Testing assets transfers with the command `yarn e2e:assets`. -Each of these commands will run the appropiate script to setup the basics, located in `../scripts/`, wait for it to finish setting up the testing environment, and then go through the tests indicated in the `./tests/index.ts` file for the chosen option. +Each of these commands will run the appropiate script to setup the basics, located in `../scripts/`. Wait for it to finish setting up the testing environment, and then go through the tests indicated in the `./tests/index.ts` file for the chosen option. After each testing suite has been completed, it's recommended to restart the zombienet before running another test suite. From 67f5ca3cd98719ed4e3761a325560ca9a955202c Mon Sep 17 00:00:00 2001 From: Alberto Nicolas Penayo <74352651+bee344@users.noreply.github.com> Date: Tue, 30 Jan 2024 08:53:24 -0300 Subject: [PATCH 21/25] Update ApiPromise import Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com> --- e2e-tests/balance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index a4949ab7..8edd5ec2 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -1,6 +1,6 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import { ApiPromise } from '@polkadot/api'; +import type { ApiPromise } from '@polkadot/api'; import type { FrameSystemAccountInfo, PalletAssetsAssetAccount } from '@polkadot/types/lookup'; import type { Option } from '@polkadot/types-codec'; From 993435c28371cbec1e9cd4f0d5804df529a9f0d5 Mon Sep 17 00:00:00 2001 From: bee344 Date: Tue, 30 Jan 2024 09:15:03 -0300 Subject: [PATCH 22/25] updated balanceTracker's descriptions --- e2e-tests/balance.ts | 21 ++++++++++++++++++++- e2e-tests/executor.ts | 20 ++++---------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index a4949ab7..80620f91 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -1,15 +1,34 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import { ApiPromise } from '@polkadot/api'; +import type { ApiPromise } from '@polkadot/api'; import type { FrameSystemAccountInfo, PalletAssetsAssetAccount } from '@polkadot/types/lookup'; import type { Option } from '@polkadot/types-codec'; +/** + * Initial and final balances for a specific assetId, used by `balanceTracker` + * to validate the evolution of a particular account's balance + * + * @interface IBalance + * + * @property {[string, number][]} IBalance.initial Account's initial balance + * for the given assetIds + * @property {[string, number][]} IBalance.final Account's final balance for + * the given assetIds + */ export interface IBalance { initial: [string, number][]; final: [string, number][]; } /** + * Function to keep track of the evolution of the balances for specific assetIds + * for a given account, used to validate the correct processing of the tests' + * transactions. + * It queries the node for the appropiate pallet's balance for the given test + * suite, and stores it as either `initial`, if no previous value is stored, + * or `final`. Both properties consist of an array of tuples containing an assetId + * and its balance for the account for the moment the value was queried, either + * before or after running the test. * * @param api api instance * @param test name of the test currently being ran diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index 2d11eaea..63366056 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -20,35 +20,23 @@ const executor = async (testCase: string) => { await cryptoWaitReady(); const keyring = new Keyring({ type: 'sr25519' }); - - switch (testCase) { - case '--foreign-assets': - testData = tests.foreignAssets; - break; - case '--liquidity-assets': - testData = tests.liquidPools; - break; - case '--local': - testData = tests.local; - break; - case '--assets': - testData = tests.assets; - break; - } - let n: { [K: string]: Function } = {}; switch (testCase) { case '--foreign-assets': + testData = tests.foreignAssets; n = foreignAssetsTests; break; case '--liquidity-assets': + testData = tests.liquidPools; n = liquidPoolsTests; break; case '--local': + testData = tests.local; n = localTests; break; case '--assets': + testData = tests.assets; n = assetTests; break; } From e7ca12df4312963f1b9c4ee584d6c9a7978a2c15 Mon Sep 17 00:00:00 2001 From: bee344 Date: Tue, 30 Jan 2024 09:15:25 -0300 Subject: [PATCH 23/25] removed unused import --- e2e-tests/executor.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/e2e-tests/executor.ts b/e2e-tests/executor.ts index 63366056..4932963a 100644 --- a/e2e-tests/executor.ts +++ b/e2e-tests/executor.ts @@ -1,7 +1,6 @@ // Copyright 2023 Parity Technologies (UK) Ltd. import { ApiPromise, WsProvider } from '@polkadot/api'; import { Keyring } from '@polkadot/keyring'; -// import { KeyringPair } from '@polkadot/keyring/types'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import { delay } from '../scripts/util'; From fe12443a29f434b6e7270bfa380a838c32025098 Mon Sep 17 00:00:00 2001 From: bee344 Date: Tue, 30 Jan 2024 09:16:05 -0300 Subject: [PATCH 24/25] linting --- e2e-tests/balance.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e-tests/balance.ts b/e2e-tests/balance.ts index 80620f91..9edee8f1 100644 --- a/e2e-tests/balance.ts +++ b/e2e-tests/balance.ts @@ -7,12 +7,12 @@ import type { Option } from '@polkadot/types-codec'; /** * Initial and final balances for a specific assetId, used by `balanceTracker` * to validate the evolution of a particular account's balance - * + * * @interface IBalance - * + * * @property {[string, number][]} IBalance.initial Account's initial balance * for the given assetIds - * @property {[string, number][]} IBalance.final Account's final balance for + * @property {[string, number][]} IBalance.final Account's final balance for * the given assetIds */ export interface IBalance { @@ -25,7 +25,7 @@ export interface IBalance { * for a given account, used to validate the correct processing of the tests' * transactions. * It queries the node for the appropiate pallet's balance for the given test - * suite, and stores it as either `initial`, if no previous value is stored, + * suite, and stores it as either `initial`, if no previous value is stored, * or `final`. Both properties consist of an array of tuples containing an assetId * and its balance for the account for the moment the value was queried, either * before or after running the test. From fa16b174d5c26347d508ff23f66952491b834c73 Mon Sep 17 00:00:00 2001 From: bee344 Date: Tue, 30 Jan 2024 10:28:41 -0300 Subject: [PATCH 25/25] linting --- src/AssetTransferApi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AssetTransferApi.ts b/src/AssetTransferApi.ts index 5729602d..674e5b73 100644 --- a/src/AssetTransferApi.ts +++ b/src/AssetTransferApi.ts @@ -834,7 +834,7 @@ export class AssetTransferApi { if (this.api.query.assetConversion !== undefined) { try { - for (const poolPairsData of await this._api.query.assetConversion.pools.entries()) { + for (const poolPairsData of await this.api.query.assetConversion.pools.entries()) { const tokenPairs = poolPairsData[0]; // remove any commas from multilocation key values e.g. Parachain: 2,125 -> Parachain: 2125