From e803748e999bc0e8bbc8aa93338042d24e5dca89 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Mon, 4 Sep 2023 10:29:48 -0400 Subject: [PATCH 01/15] add consts file, and imports --- scripts/consts.ts | 4 ++++ scripts/testNetworkSetup.ts | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 scripts/consts.ts diff --git a/scripts/consts.ts b/scripts/consts.ts new file mode 100644 index 00000000..3d2191e6 --- /dev/null +++ b/scripts/consts.ts @@ -0,0 +1,4 @@ +// 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'; diff --git a/scripts/testNetworkSetup.ts b/scripts/testNetworkSetup.ts index 09e3baad..12efd4f0 100644 --- a/scripts/testNetworkSetup.ts +++ b/scripts/testNetworkSetup.ts @@ -9,14 +9,13 @@ import { formatDate } from '@polkadot/util'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; +import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL } from './consts'; + /** * This script is intended to be run after zombienet is running. * It uses the hard coded values given in `zombienet.toml`. */ -const KUSAMA_ASSET_HUB_WS_URL = 'ws://127.0.0.1:9911'; -const ROCOCO_ALICE_WS_URL = 'ws://127.0.0.1:9900'; - /** * Set a delay (sleep) * From f2ea0d23fa31a28c2e0da6f40742054ed157fbc9 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Mon, 4 Sep 2023 10:31:57 -0400 Subject: [PATCH 02/15] add trappist url --- scripts/consts.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/consts.ts b/scripts/consts.ts index 3d2191e6..fac167a5 100644 --- a/scripts/consts.ts +++ b/scripts/consts.ts @@ -2,3 +2,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'; From d63f00b5ca4d75fd4ca490314eccd4e345827543 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Mon, 4 Sep 2023 10:40:41 -0400 Subject: [PATCH 03/15] setup Util --- scripts/testNetworkSetup.ts | 21 +-------------------- scripts/util.ts | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 20 deletions(-) create mode 100644 scripts/util.ts diff --git a/scripts/testNetworkSetup.ts b/scripts/testNetworkSetup.ts index 12efd4f0..d04fdd17 100644 --- a/scripts/testNetworkSetup.ts +++ b/scripts/testNetworkSetup.ts @@ -5,36 +5,17 @@ import '@polkadot/api-augment'; import { ApiPromise, WsProvider } from '@polkadot/api'; import { Keyring } from '@polkadot/keyring'; import { DispatchError } from '@polkadot/types/interfaces'; -import { formatDate } from '@polkadot/util'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL } from './consts'; +import { delay, logWithDate } from './util'; /** * This script is intended to be run after zombienet is running. * It uses the hard coded values given in `zombienet.toml`. */ -/** - * Set a delay (sleep) - * - * @param ms Milliseconds - */ -const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); - -/** - * Formats a string to match the output of polkadot-js logging. - * - * @param log String to be logged - * @param remove Remove lines before that were cleared by std - */ -const logWithDate = (log: string, remove?: boolean) => { - remove - ? console.log(`\r${formatDate(new Date())} ${log}`) - : console.log(`${formatDate(new Date())} ${log}`); -}; - /** * Will block the main script from running until there is blocks in Polkadot AssetHub being produced. */ diff --git a/scripts/util.ts b/scripts/util.ts new file mode 100644 index 00000000..8fbc5685 --- /dev/null +++ b/scripts/util.ts @@ -0,0 +1,23 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +import { formatDate } from '@polkadot/util'; + +/** + * Set a delay (sleep) + * + * @param ms Milliseconds + */ +export const delay = (ms: number) => + new Promise((resolve) => setTimeout(resolve, ms)); + +/** + * Formats a string to match the output of polkadot-js logging. + * + * @param log String to be logged + * @param remove Remove lines before that were cleared by std + */ +export const logWithDate = (log: string, remove?: boolean) => { + remove + ? console.log(`\r${formatDate(new Date())} ${log}`) + : console.log(`${formatDate(new Date())} ${log}`); +}; From e76cde7f09a51d07fbcf4f7c3a74e6d4e33cb773 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Mon, 4 Sep 2023 22:04:27 -0400 Subject: [PATCH 04/15] yarn script to run foreign assets script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 4f6c723a..2b7cc0a9 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "build:examples": "substrate-exec-rimraf examples/build/ && substrate-exec-tsc --project examples/tsconfig.json", "start": "node ./lib/index.js", "start:zombienet-post-script": "yarn build:scripts && node ./scripts/build/testNetworkSetup.js", + "start:zombienet-foriegn-assets-scirpt": "yarn build:scripts && node ./scripts/build/testNetworkForeignAssets.js", "lint": "substrate-dev-run-lint", "lint:fix": "substrate-dev-run-lint --fix", "test": "NODE_ENV=test substrate-exec-jest --detectOpenHandles", From b25a54bc70b44ecf4a01b981cc7c92c4dc6fadae Mon Sep 17 00:00:00 2001 From: tarikgul Date: Mon, 4 Sep 2023 22:04:49 -0400 Subject: [PATCH 05/15] Update to use trappist-node --- zombienet/medium-network.toml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/zombienet/medium-network.toml b/zombienet/medium-network.toml index 0036ca1f..4aff42c4 100644 --- a/zombienet/medium-network.toml +++ b/zombienet/medium-network.toml @@ -46,16 +46,17 @@ cumulus_based = true id = 2000 add_to_genesis = true cumulus_based = true +chain = "trappist-local" [[parachains.collators]] name = "trappist-collator01" - command = "./bin/trappist-collator" + command = "./bin/trappist-node" ws_port = 9920 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains.collators]] name = "trappist-collator02" - command = "./bin/trappist-collator" + command = "./bin/trappist-node" ws_port = 9921 args = ["--log=xcm=trace,pallet-assets=trace"] @@ -63,16 +64,17 @@ cumulus_based = true id = 3000 add_to_genesis = true cumulus_based = true +chain = "trappist-local" [[parachains.collators]] name = "stout-collator01" - command = "./bin/trappist-collator" + command = "./bin/trappist-node" ws_port = 9930 args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains.collators]] name = "stout-collator02" - command = "./bin/trappist-collator" + command = "./bin/trappist-node" ws_port = 9931 args = ["--log=xcm=trace,pallet-assets=trace"] From 180445f9d1b8b59b6a7a22d32932ad477ee8dbe7 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Mon, 4 Sep 2023 22:05:28 -0400 Subject: [PATCH 06/15] Initial script --- scripts/testNetworkForeignAssets.ts | 188 ++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 scripts/testNetworkForeignAssets.ts diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts new file mode 100644 index 00000000..9d7d5edc --- /dev/null +++ b/scripts/testNetworkForeignAssets.ts @@ -0,0 +1,188 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +import { ApiPromise, WsProvider } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +import { cryptoWaitReady } from '@polkadot/util-crypto'; +import chalk from 'chalk'; + +import { KUSAMA_ASSET_HUB_WS_URL, TRAPPIST_WS_URL } from './consts'; +import { logWithDate } from './util'; + +const createForeignAssetCall = ( + assetHubApi: ApiPromise, + trappistApi: ApiPromise +) => { + const trappistMultiLocation = assetHubApi.registry.createType( + 'MultiLocation', + { + parents: 1, + interior: { + X1: { + parachain: 1836, + }, + }, + } + ); + + const foreignAssetCreateTx = assetHubApi.tx.foreignAssets.create( + trappistMultiLocation, + 'FBeL7DbnXs4AvP7LqG1yiuFYAsPxE9Yiv4wayoLguBH46Bp', // Sibling 1836 -> ParaId + '33333333' + ); + + const foreignAssetCreateCallHex = assetHubApi.registry + .createType('Call', { + callIndex: foreignAssetCreateTx.callIndex, + args: foreignAssetCreateTx.args, + }) + .toHex(); + + // Double encode the call + const xcmDoubleEncoded = trappistApi.createType('XcmDoubleEncoded', { + encoded: foreignAssetCreateCallHex, + }); + + const xcmOriginType = trappistApi.createType('XcmOriginKind', 'Xcm'); + const xcmDestMultiLocation = trappistApi.createType( + 'XcmVersionedMultiLocation', + { + V3: { + parents: 0, + interior: { + X1: { + parachain: 1000, + }, + }, + }, + } + ); + const xcmMessage = { + V3: [ + { + withdrawAsset: { + id: { + concrete: { + parents: 1, + interior: { Here: '' }, + }, + }, + fun: { + fungible: 100000000000, + }, + }, + }, + { + buyExecution: { + fees: { + id: { + concrete: { + parents: 1, + interior: { Here: '' }, + }, + }, + fun: { + fungible: 100000000000, + }, + }, + weightLimit: { Unlimited: '' }, + }, + }, + { + transact: { + originKind: xcmOriginType, + requireWeightAtMost: { + refTime: 1000000000, + proofSize: 900000, + }, + call: xcmDoubleEncoded, + }, + }, + { + refundSurplus: true, + }, + { + depositAsset: { + assets: { + wild: { + All: '', + }, + }, + beneficiary: { + parents: 0, + interior: { + x1: { + AccountId32: { + id: '0x7369626c2c070000000000000000000000000000000000000000000000000000', + }, + }, + }, + }, + }, + }, + ], + }; + const xcmVersionedMsg = trappistApi.createType('XcmVersionedXcm', xcmMessage); + const xcmMsg = trappistApi.tx.xcmPallet.send( + xcmDestMultiLocation, + xcmVersionedMsg + ); + const xcmCall = trappistApi.createType('Call', { + callIndex: xcmMsg.callIndex, + args: xcmMsg.args, + }); + + return xcmCall; +}; + +const main = async () => { + logWithDate( + chalk.yellow('Initializing script to create foreignAssets on chain') + ); + await cryptoWaitReady(); + + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + console.log(alice); + + const kusamaAssetHubApi = await ApiPromise.create({ + provider: new WsProvider(KUSAMA_ASSET_HUB_WS_URL), + noInitWarn: true, + }); + + await kusamaAssetHubApi.isReady; + logWithDate(chalk.green('Created a connection to Kusama AssetHub')); + + const trappistApi = await ApiPromise.create({ + provider: new WsProvider(TRAPPIST_WS_URL), + noInitWarn: true, + }); + + await trappistApi.isReady; + logWithDate(chalk.green('Created a connection to Trappist')); + + const createForeignAssetsXcmCall = createForeignAssetCall( + kusamaAssetHubApi, + trappistApi + ); + + logWithDate( + 'Sending Sudo XCM message from relay chain to execute forceCreate call on Kusama AssetHub' + ); + await trappistApi.tx.sudo.sudo(createForeignAssetsXcmCall).signAndSend(alice); + + await kusamaAssetHubApi.disconnect().then(() => { + logWithDate( + chalk.blue('Polkadot-js successfully disconnected from asset-hub') + ); + }); + + await trappistApi.disconnect().then(() => { + logWithDate( + chalk.blue('Polkadot-js successfully disconnected from trappist') + ); + }); +}; + +main() + .catch(console.error) + .finally(() => process.exit()); From fa27a163d0e11e566dc8f8b0d8b775f6849a6d59 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Mon, 4 Sep 2023 22:09:18 -0400 Subject: [PATCH 07/15] add wip to title github action --- .github/workflows/semantic.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/semantic.yml b/.github/workflows/semantic.yml index d51ad737..114f91fc 100644 --- a/.github/workflows/semantic.yml +++ b/.github/workflows/semantic.yml @@ -25,3 +25,5 @@ jobs: uses: amannn/action-semantic-pull-request@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + wip: true From 99bbec0180f584fea91238acf461950657c75048 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Mon, 4 Sep 2023 22:11:31 -0400 Subject: [PATCH 08/15] remove wip since it gives write permissions --- .github/workflows/semantic.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/semantic.yml b/.github/workflows/semantic.yml index 114f91fc..d51ad737 100644 --- a/.github/workflows/semantic.yml +++ b/.github/workflows/semantic.yml @@ -25,5 +25,3 @@ jobs: uses: amannn/action-semantic-pull-request@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - wip: true From a2f0743f6c1d2a5129bde0055ce28c0830704d7f Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 5 Sep 2023 15:12:45 -0400 Subject: [PATCH 09/15] Set medium network to one trappist collator and fix paraId --- zombienet/medium-network.toml | 48 +++-------------------------------- 1 file changed, 3 insertions(+), 45 deletions(-) diff --git a/zombienet/medium-network.toml b/zombienet/medium-network.toml index 4aff42c4..fe7552d2 100644 --- a/zombienet/medium-network.toml +++ b/zombienet/medium-network.toml @@ -43,7 +43,7 @@ cumulus_based = true args = ["--log=xcm=trace,pallet-assets=trace"] [[parachains]] -id = 2000 +id = 1836 add_to_genesis = true cumulus_based = true chain = "trappist-local" @@ -60,24 +60,6 @@ chain = "trappist-local" ws_port = 9921 args = ["--log=xcm=trace,pallet-assets=trace"] -[[parachains]] -id = 3000 -add_to_genesis = true -cumulus_based = true -chain = "trappist-local" - - [[parachains.collators]] - name = "stout-collator01" - command = "./bin/trappist-node" - ws_port = 9930 - args = ["--log=xcm=trace,pallet-assets=trace"] - - [[parachains.collators]] - name = "stout-collator02" - command = "./bin/trappist-node" - ws_port = 9931 - args = ["--log=xcm=trace,pallet-assets=trace"] - [types.Header] number = "u64" parent_hash = "Hash" @@ -85,36 +67,12 @@ post_state = "Hash" [[hrmp_channels]] sender = 1000 -recipient = 2000 +recipient = 1836 max_capacity = 8 max_message_size = 512 [[hrmp_channels]] -sender = 2000 +sender = 1836 recipient = 1000 max_capacity = 8 max_message_size = 512 - -[[hrmp_channels]] -sender = 1000 -recipient = 3000 -max_capacity = 8 -max_message_size = 512 - -[[hrmp_channels]] -sender = 3000 -recipient = 1000 -max_capacity = 8 -max_message_size = 512 - -[[hrmp_channels]] -sender = 2000 -recipient = 3000 -max_capacity = 8 -max_message_size = 512 - -[[hrmp_channels]] -sender = 3000 -recipient = 2000 -max_capacity = 8 -max_message_size = 512 From 389849eb4c44cab8894d15131e7492ea11724275 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Wed, 6 Sep 2023 11:02:19 -0400 Subject: [PATCH 10/15] Make awaitBlockProduction reusable --- scripts/testNetworkSetup.ts | 47 ++----------------------------------- scripts/util.ts | 45 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/scripts/testNetworkSetup.ts b/scripts/testNetworkSetup.ts index d04fdd17..2c4b7378 100644 --- a/scripts/testNetworkSetup.ts +++ b/scripts/testNetworkSetup.ts @@ -9,56 +9,13 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL } from './consts'; -import { delay, logWithDate } from './util'; +import { delay, logWithDate, awaitBlockProduction } from './util'; /** * This script is intended to be run after zombienet is running. * It uses the hard coded values given in `zombienet.toml`. */ -/** - * Will block the main script from running until there is blocks in Polkadot AssetHub being produced. - */ -const awaitBlockProduction = async () => { - logWithDate( - chalk.yellow( - `Initializing polkadot-js: Polling until ${KUSAMA_ASSET_HUB_WS_URL} is available` - ) - ); - const kusamaAssetHubApi = await ApiPromise.create({ - provider: new WsProvider(KUSAMA_ASSET_HUB_WS_URL), - noInitWarn: true, - }); - logWithDate(chalk.yellow('Polkadot-js is connected')); - - await kusamaAssetHubApi.isReady; - - let counter = 3; - let blocksProducing = false; - while (!blocksProducing) { - const { number } = await kusamaAssetHubApi.rpc.chain.getHeader(); - - if (number.toNumber() > 0) { - blocksProducing = true; - } - await delay(1000); - - counter += 1; - process.stdout.clearLine(0); - process.stdout.write( - `\rWaiting for Block production on Kusama AssetHub${'.'.repeat( - (counter % 3) + 1 - )}` - ); - } - - process.stdout.clearLine(0); - logWithDate(chalk.magenta('Blocks are producing'), true); - await kusamaAssetHubApi.disconnect().then(() => { - logWithDate(chalk.blue('Polkadot-js successfully disconnected')); - }); -}; - const main = async () => { logWithDate(chalk.yellow('Initializing script to run transaction on chain')); await cryptoWaitReady(); @@ -222,7 +179,7 @@ const main = async () => { }; // eslint-disable-next-line @typescript-eslint/no-floating-promises -awaitBlockProduction().then(async () => { +awaitBlockProduction(KUSAMA_ASSET_HUB_WS_URL).then(async () => { await main() .catch(console.error) .finally(() => process.exit()); diff --git a/scripts/util.ts b/scripts/util.ts index 8fbc5685..ebc2adc8 100644 --- a/scripts/util.ts +++ b/scripts/util.ts @@ -1,6 +1,8 @@ // Copyright 2023 Parity Technologies (UK) Ltd. +import { ApiPromise, WsProvider } from '@polkadot/api'; import { formatDate } from '@polkadot/util'; +import chalk from 'chalk'; /** * Set a delay (sleep) @@ -21,3 +23,46 @@ export const logWithDate = (log: string, remove?: boolean) => { ? console.log(`\r${formatDate(new Date())} ${log}`) : console.log(`${formatDate(new Date())} ${log}`); }; + +/** + * Will block the main script from running until there is blocks in Polkadot AssetHub being produced. + */ +export const awaitBlockProduction = async (wsUrl: string) => { + logWithDate( + chalk.yellow( + `Initializing polkadot-js: Polling until ${wsUrl} is available` + ) + ); + const api = await ApiPromise.create({ + provider: new WsProvider(wsUrl), + noInitWarn: true, + }); + logWithDate(chalk.yellow('Polkadot-js is connected')); + + await api.isReady; + + let counter = 3; + let blocksProducing = false; + while (!blocksProducing) { + const { number } = await api.rpc.chain.getHeader(); + + if (number.toNumber() > 0) { + blocksProducing = true; + } + await delay(1000); + + counter += 1; + process.stdout.clearLine(0); + process.stdout.write( + `\rWaiting for Block production on Kusama AssetHub${'.'.repeat( + (counter % 3) + 1 + )}` + ); + } + + process.stdout.clearLine(0); + logWithDate(chalk.magenta('Blocks are producing'), true); + await api.disconnect().then(() => { + logWithDate(chalk.blue('Polkadot-js successfully disconnected')); + }); +}; From 84f38266d5e4e4fa3ede2b92617a41cd1b244faa Mon Sep 17 00:00:00 2001 From: tarikgul Date: Wed, 6 Sep 2023 11:06:32 -0400 Subject: [PATCH 11/15] abstract functionality into smaller functions --- scripts/testNetworkForeignAssets.ts | 50 +++++++++++++++++++---------- scripts/testNetworkSetup.ts | 2 +- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts index 9d7d5edc..1ce49b2b 100644 --- a/scripts/testNetworkForeignAssets.ts +++ b/scripts/testNetworkForeignAssets.ts @@ -6,12 +6,9 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; import { KUSAMA_ASSET_HUB_WS_URL, TRAPPIST_WS_URL } from './consts'; -import { logWithDate } from './util'; +import { awaitBlockProduction, logWithDate } from './util'; -const createForeignAssetCall = ( - assetHubApi: ApiPromise, - trappistApi: ApiPromise -) => { +const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { const trappistMultiLocation = assetHubApi.registry.createType( 'MultiLocation', { @@ -24,22 +21,26 @@ const createForeignAssetCall = ( } ); - const foreignAssetCreateTx = assetHubApi.tx.foreignAssets.create( + const createTx = assetHubApi.tx.foreignAssets.create( trappistMultiLocation, 'FBeL7DbnXs4AvP7LqG1yiuFYAsPxE9Yiv4wayoLguBH46Bp', // Sibling 1836 -> ParaId '33333333' ); - const foreignAssetCreateCallHex = assetHubApi.registry + const hexCall = assetHubApi.registry .createType('Call', { - callIndex: foreignAssetCreateTx.callIndex, - args: foreignAssetCreateTx.args, + callIndex: createTx.callIndex, + args: createTx.args, }) .toHex(); + return hexCall; +}; + +const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { // Double encode the call const xcmDoubleEncoded = trappistApi.createType('XcmDoubleEncoded', { - encoded: foreignAssetCreateCallHex, + encoded: call, }); const xcmOriginType = trappistApi.createType('XcmOriginKind', 'Xcm'); @@ -91,8 +92,8 @@ const createForeignAssetCall = ( transact: { originKind: xcmOriginType, requireWeightAtMost: { - refTime: 1000000000, - proofSize: 900000, + refTime: 8000000000, + proofSize: 65536, }, call: xcmDoubleEncoded, }, @@ -134,6 +135,16 @@ const createForeignAssetCall = ( return xcmCall; }; +const createForeignAssetViaSudo = ( + assetHubApi: ApiPromise, + trappistApi: ApiPromise +) => { + const foreignAssetCreateCall = fAssetCreateCall(assetHubApi); + const sudoCall = sudoCallWrapper(trappistApi, foreignAssetCreateCall); + + return sudoCall; +}; + const main = async () => { logWithDate( chalk.yellow('Initializing script to create foreignAssets on chain') @@ -160,7 +171,7 @@ const main = async () => { await trappistApi.isReady; logWithDate(chalk.green('Created a connection to Trappist')); - const createForeignAssetsXcmCall = createForeignAssetCall( + const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo( kusamaAssetHubApi, trappistApi ); @@ -168,7 +179,9 @@ const main = async () => { logWithDate( 'Sending Sudo XCM message from relay chain to execute forceCreate call on Kusama AssetHub' ); - await trappistApi.tx.sudo.sudo(createForeignAssetsXcmCall).signAndSend(alice); + await trappistApi.tx.sudo + .sudo(foreignAssetsCreateSudoXcmCall) + .signAndSend(alice); await kusamaAssetHubApi.disconnect().then(() => { logWithDate( @@ -183,6 +196,9 @@ const main = async () => { }); }; -main() - .catch(console.error) - .finally(() => process.exit()); +// eslint-disable-next-line @typescript-eslint/no-floating-promises +awaitBlockProduction(TRAPPIST_WS_URL).then(async () => { + await main() + .catch(console.error) + .finally(() => process.exit()); +}); diff --git a/scripts/testNetworkSetup.ts b/scripts/testNetworkSetup.ts index 2c4b7378..34251bbb 100644 --- a/scripts/testNetworkSetup.ts +++ b/scripts/testNetworkSetup.ts @@ -9,7 +9,7 @@ import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; import { KUSAMA_ASSET_HUB_WS_URL, ROCOCO_ALICE_WS_URL } from './consts'; -import { delay, logWithDate, awaitBlockProduction } from './util'; +import { awaitBlockProduction, delay, logWithDate } from './util'; /** * This script is intended to be run after zombienet is running. From 5a88e566234bb87218a13e56223be8e3e1fc5199 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Wed, 6 Sep 2023 11:24:34 -0400 Subject: [PATCH 12/15] add setMetadata call --- scripts/testNetworkForeignAssets.ts | 61 +++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts index 1ce49b2b..433d6f61 100644 --- a/scripts/testNetworkForeignAssets.ts +++ b/scripts/testNetworkForeignAssets.ts @@ -2,11 +2,42 @@ import { ApiPromise, WsProvider } from '@polkadot/api'; import { Keyring } from '@polkadot/keyring'; +import { stringToU8a } from '@polkadot/util'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; import { KUSAMA_ASSET_HUB_WS_URL, TRAPPIST_WS_URL } from './consts'; -import { awaitBlockProduction, logWithDate } from './util'; +import { awaitBlockProduction, delay, logWithDate } from './util'; + +const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { + const trappistMultiLocation = assetHubApi.registry.createType( + 'MultiLocation', + { + parents: 1, + interior: { + X1: { + parachain: 1836, + }, + }, + } + ); + + const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata( + trappistMultiLocation, + stringToU8a('Trappist Hop'), + stringToU8a('Hop'), + 12 + ); + + const hexCall = assetHubApi.registry + .createType('Call', { + callIndex: setMetadataTx.callIndex, + args: setMetadataTx.args, + }) + .toHex(); + + return hexCall; +}; const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { const trappistMultiLocation = assetHubApi.registry.createType( @@ -140,9 +171,15 @@ const createForeignAssetViaSudo = ( trappistApi: ApiPromise ) => { const foreignAssetCreateCall = fAssetCreateCall(assetHubApi); - const sudoCall = sudoCallWrapper(trappistApi, foreignAssetCreateCall); + return sudoCallWrapper(trappistApi, foreignAssetCreateCall); +}; - return sudoCall; +const setMetadataForeignAssetViaSudo = ( + assetHubApi: ApiPromise, + trappistApi: ApiPromise +) => { + const setMetadataCall = fAssetSetMetadataCall(assetHubApi); + return sudoCallWrapper(trappistApi, setMetadataCall); }; const main = async () => { @@ -177,12 +214,28 @@ const main = async () => { ); logWithDate( - 'Sending Sudo XCM message from relay chain to execute forceCreate call on Kusama AssetHub' + '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 delay(24000); + + const foreignAssetsSetMetadataSudoXcmCall = setMetadataForeignAssetViaSudo( + kusamaAssetHubApi, + trappistApi + ); + + logWithDate( + 'Sending Sudo XCM message from relay chain to execute setMetadata call on Kusama AssetHub' + ); + await trappistApi.tx.sudo + .sudo(foreignAssetsSetMetadataSudoXcmCall) + .signAndSend(alice); + + await delay(24000); + await kusamaAssetHubApi.disconnect().then(() => { logWithDate( chalk.blue('Polkadot-js successfully disconnected from asset-hub') From 14ebce252c9b75265064d21b92cfa0f84a8798a1 Mon Sep 17 00:00:00 2001 From: bee344 Date: Wed, 1 Nov 2023 20:24:28 -0300 Subject: [PATCH 13/15] completed circuit --- scripts/testNetworkForeignAssets.ts | 46 +++++++++++++---------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts index 433d6f61..60765c70 100644 --- a/scripts/testNetworkForeignAssets.ts +++ b/scripts/testNetworkForeignAssets.ts @@ -2,7 +2,6 @@ import { ApiPromise, WsProvider } from '@polkadot/api'; import { Keyring } from '@polkadot/keyring'; -import { stringToU8a } from '@polkadot/util'; import { cryptoWaitReady } from '@polkadot/util-crypto'; import chalk from 'chalk'; @@ -10,22 +9,19 @@ import { KUSAMA_ASSET_HUB_WS_URL, TRAPPIST_WS_URL } from './consts'; import { awaitBlockProduction, delay, logWithDate } from './util'; const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { - const trappistMultiLocation = assetHubApi.registry.createType( - 'MultiLocation', - { + const trappistMultiLocation = { parents: 1, interior: { X1: { parachain: 1836, }, }, - } - ); + }; const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata( trappistMultiLocation, - stringToU8a('Trappist Hop'), - stringToU8a('Hop'), + 'Trappist Hop', + 'Hop', 12 ); @@ -40,8 +36,7 @@ const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { }; const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { - const trappistMultiLocation = assetHubApi.registry.createType( - 'MultiLocation', + const trappistMultiLocation = { parents: 1, interior: { @@ -49,13 +44,12 @@ const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { parachain: 1836, }, }, - } - ); + }; const createTx = assetHubApi.tx.foreignAssets.create( trappistMultiLocation, - 'FBeL7DbnXs4AvP7LqG1yiuFYAsPxE9Yiv4wayoLguBH46Bp', // Sibling 1836 -> ParaId - '33333333' + '5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', // Sibling 1836 -> ParaId + '100000000000' ); const hexCall = assetHubApi.registry @@ -75,23 +69,20 @@ const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { }); const xcmOriginType = trappistApi.createType('XcmOriginKind', 'Xcm'); - const xcmDestMultiLocation = trappistApi.createType( - 'XcmVersionedMultiLocation', - { + const xcmDestMultiLocation = { V3: { - parents: 0, + parents: 1, interior: { X1: { parachain: 1000, }, }, }, - } - ); + }; const xcmMessage = { V3: [ { - withdrawAsset: { + withdrawAsset: [{ id: { concrete: { parents: 1, @@ -101,7 +92,7 @@ const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { fun: { fungible: 100000000000, }, - }, + }], }, { buyExecution: { @@ -153,10 +144,9 @@ const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { }, ], }; - const xcmVersionedMsg = trappistApi.createType('XcmVersionedXcm', xcmMessage); - const xcmMsg = trappistApi.tx.xcmPallet.send( + const xcmMsg = trappistApi.tx.polkadotXcm.send( xcmDestMultiLocation, - xcmVersionedMsg + xcmMessage ); const xcmCall = trappistApi.createType('Call', { callIndex: xcmMsg.callIndex, @@ -190,7 +180,7 @@ const main = async () => { const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); - console.log(alice); + const bob = keyring.addFromUri('//Bob'); const kusamaAssetHubApi = await ApiPromise.create({ provider: new WsProvider(KUSAMA_ASSET_HUB_WS_URL), @@ -208,6 +198,10 @@ const main = async () => { await trappistApi.isReady; logWithDate(chalk.green('Created a connection to Trappist')); + logWithDate(chalk.magenta('Sending funds to Trappist Sibling on Kusama AssetHub')); + + await kusamaAssetHubApi.tx.balances.transferKeepAlive('5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', 10000000000000).signAndSend(bob); + const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo( kusamaAssetHubApi, trappistApi From 17636578f1eb16dac8ff3ebe6a70b1b890209957 Mon Sep 17 00:00:00 2001 From: bee344 Date: Wed, 1 Nov 2023 20:28:19 -0300 Subject: [PATCH 14/15] typos in package.json script for FA --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b7cc0a9..42a1be66 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build:examples": "substrate-exec-rimraf examples/build/ && substrate-exec-tsc --project examples/tsconfig.json", "start": "node ./lib/index.js", "start:zombienet-post-script": "yarn build:scripts && node ./scripts/build/testNetworkSetup.js", - "start:zombienet-foriegn-assets-scirpt": "yarn build:scripts && node ./scripts/build/testNetworkForeignAssets.js", + "start:zombienet-foreign-assets-script": "yarn build:scripts && node ./scripts/build/testNetworkForeignAssets.js", "lint": "substrate-dev-run-lint", "lint:fix": "substrate-dev-run-lint --fix", "test": "NODE_ENV=test substrate-exec-jest --detectOpenHandles", From ac1d8b208891d9fda4ee21cafde44dc2059dbd21 Mon Sep 17 00:00:00 2001 From: bee344 Date: Thu, 2 Nov 2023 12:57:48 -0300 Subject: [PATCH 15/15] lint:fix --- scripts/testNetworkForeignAssets.ts | 123 +++++++++++----------------- scripts/util.ts | 15 +--- 2 files changed, 49 insertions(+), 89 deletions(-) diff --git a/scripts/testNetworkForeignAssets.ts b/scripts/testNetworkForeignAssets.ts index 60765c70..d8789c64 100644 --- a/scripts/testNetworkForeignAssets.ts +++ b/scripts/testNetworkForeignAssets.ts @@ -10,20 +10,15 @@ import { awaitBlockProduction, delay, logWithDate } from './util'; const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { const trappistMultiLocation = { - parents: 1, - interior: { - X1: { - parachain: 1836, - }, + parents: 1, + interior: { + X1: { + parachain: 1836, }, - }; + }, + }; - const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata( - trappistMultiLocation, - 'Trappist Hop', - 'Hop', - 12 - ); + const setMetadataTx = assetHubApi.tx.foreignAssets.setMetadata(trappistMultiLocation, 'Trappist Hop', 'Hop', 12); const hexCall = assetHubApi.registry .createType('Call', { @@ -36,15 +31,14 @@ const fAssetSetMetadataCall = (assetHubApi: ApiPromise): `0x${string}` => { }; const fAssetCreateCall = (assetHubApi: ApiPromise): `0x${string}` => { - const trappistMultiLocation = - { - parents: 1, - interior: { - X1: { - parachain: 1836, - }, + const trappistMultiLocation = { + parents: 1, + interior: { + X1: { + parachain: 1836, }, - }; + }, + }; const createTx = assetHubApi.tx.foreignAssets.create( trappistMultiLocation, @@ -70,29 +64,31 @@ const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { const xcmOriginType = trappistApi.createType('XcmOriginKind', 'Xcm'); const xcmDestMultiLocation = { - V3: { - parents: 1, - interior: { - X1: { - parachain: 1000, - }, + V3: { + parents: 1, + interior: { + X1: { + parachain: 1000, }, }, + }, }; const xcmMessage = { V3: [ { - withdrawAsset: [{ - id: { - concrete: { - parents: 1, - interior: { Here: '' }, + withdrawAsset: [ + { + id: { + concrete: { + parents: 1, + interior: { Here: '' }, + }, + }, + fun: { + fungible: 100000000000, }, }, - fun: { - fungible: 100000000000, - }, - }], + ], }, { buyExecution: { @@ -144,10 +140,7 @@ const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { }, ], }; - const xcmMsg = trappistApi.tx.polkadotXcm.send( - xcmDestMultiLocation, - xcmMessage - ); + const xcmMsg = trappistApi.tx.polkadotXcm.send(xcmDestMultiLocation, xcmMessage); const xcmCall = trappistApi.createType('Call', { callIndex: xcmMsg.callIndex, args: xcmMsg.args, @@ -156,26 +149,18 @@ const sudoCallWrapper = (trappistApi: ApiPromise, call: `0x${string}`) => { return xcmCall; }; -const createForeignAssetViaSudo = ( - assetHubApi: ApiPromise, - trappistApi: ApiPromise -) => { +const createForeignAssetViaSudo = (assetHubApi: ApiPromise, trappistApi: ApiPromise) => { const foreignAssetCreateCall = fAssetCreateCall(assetHubApi); return sudoCallWrapper(trappistApi, foreignAssetCreateCall); }; -const setMetadataForeignAssetViaSudo = ( - assetHubApi: ApiPromise, - trappistApi: ApiPromise -) => { +const setMetadataForeignAssetViaSudo = (assetHubApi: ApiPromise, trappistApi: ApiPromise) => { const setMetadataCall = fAssetSetMetadataCall(assetHubApi); return sudoCallWrapper(trappistApi, setMetadataCall); }; const main = async () => { - logWithDate( - chalk.yellow('Initializing script to create foreignAssets on chain') - ); + logWithDate(chalk.yellow('Initializing script to create foreignAssets on chain')); await cryptoWaitReady(); const keyring = new Keyring({ type: 'sr25519' }); @@ -200,46 +185,30 @@ const main = async () => { logWithDate(chalk.magenta('Sending funds to Trappist Sibling on Kusama AssetHub')); - await kusamaAssetHubApi.tx.balances.transferKeepAlive('5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', 10000000000000).signAndSend(bob); + await kusamaAssetHubApi.tx.balances + .transferKeepAlive('5Eg2fnsjAAr8RGZfa8Sy5mYFPabA9ZLNGYECCKXPD6xnK6D2', 10000000000000) + .signAndSend(bob); - const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo( - kusamaAssetHubApi, - trappistApi - ); + const foreignAssetsCreateSudoXcmCall = createForeignAssetViaSudo(kusamaAssetHubApi, trappistApi); - 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); + 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 delay(24000); - const foreignAssetsSetMetadataSudoXcmCall = setMetadataForeignAssetViaSudo( - kusamaAssetHubApi, - trappistApi - ); + const foreignAssetsSetMetadataSudoXcmCall = setMetadataForeignAssetViaSudo(kusamaAssetHubApi, trappistApi); - logWithDate( - 'Sending Sudo XCM message from relay chain to execute setMetadata call on Kusama AssetHub' - ); - await trappistApi.tx.sudo - .sudo(foreignAssetsSetMetadataSudoXcmCall) - .signAndSend(alice); + logWithDate('Sending Sudo XCM message from relay chain to execute setMetadata call on Kusama AssetHub'); + await trappistApi.tx.sudo.sudo(foreignAssetsSetMetadataSudoXcmCall).signAndSend(alice); await delay(24000); await kusamaAssetHubApi.disconnect().then(() => { - logWithDate( - chalk.blue('Polkadot-js successfully disconnected from asset-hub') - ); + logWithDate(chalk.blue('Polkadot-js successfully disconnected from asset-hub')); }); await trappistApi.disconnect().then(() => { - logWithDate( - chalk.blue('Polkadot-js successfully disconnected from trappist') - ); + logWithDate(chalk.blue('Polkadot-js successfully disconnected from trappist')); }); }; diff --git a/scripts/util.ts b/scripts/util.ts index ebc2adc8..0d3e3ad6 100644 --- a/scripts/util.ts +++ b/scripts/util.ts @@ -9,8 +9,7 @@ import chalk from 'chalk'; * * @param ms Milliseconds */ -export const delay = (ms: number) => - new Promise((resolve) => setTimeout(resolve, ms)); +export const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); /** * Formats a string to match the output of polkadot-js logging. @@ -28,11 +27,7 @@ export const logWithDate = (log: string, remove?: boolean) => { * Will block the main script from running until there is blocks in Polkadot AssetHub being produced. */ export const awaitBlockProduction = async (wsUrl: string) => { - logWithDate( - chalk.yellow( - `Initializing polkadot-js: Polling until ${wsUrl} is available` - ) - ); + logWithDate(chalk.yellow(`Initializing polkadot-js: Polling until ${wsUrl} is available`)); const api = await ApiPromise.create({ provider: new WsProvider(wsUrl), noInitWarn: true, @@ -53,11 +48,7 @@ export const awaitBlockProduction = async (wsUrl: string) => { counter += 1; process.stdout.clearLine(0); - process.stdout.write( - `\rWaiting for Block production on Kusama AssetHub${'.'.repeat( - (counter % 3) + 1 - )}` - ); + process.stdout.write(`\rWaiting for Block production on Kusama AssetHub${'.'.repeat((counter % 3) + 1)}`); } process.stdout.clearLine(0);