From efbe7c3256b566ff5decdee71afc4f922ea1c60c Mon Sep 17 00:00:00 2001 From: Tarik Gul <47201679+TarikGul@users.noreply.github.com> Date: Tue, 26 Sep 2023 07:59:40 -0700 Subject: [PATCH] fix: rococo initialization in the registry (#297) --- examples/rococoAssetHubToRelay.ts | 50 ++++++++++++++++++++++++++++++ src/consts.ts | 2 ++ src/registry/Registry.spec.ts | 6 ++++ src/registry/findRelayChain.ts | 12 ++++++- src/registry/parseRegistry.spec.ts | 5 ++- src/registry/parseRegistry.ts | 7 +++++ 6 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 examples/rococoAssetHubToRelay.ts diff --git a/examples/rococoAssetHubToRelay.ts b/examples/rococoAssetHubToRelay.ts new file mode 100644 index 00000000..cd64ed1f --- /dev/null +++ b/examples/rococoAssetHubToRelay.ts @@ -0,0 +1,50 @@ +/** + * When importing from @substrate/asset-transfer-api it would look like the following + * + * import { AssetTransferApi, constructApiPromise } from '@substrate/asset-transfer-api' + */ +import { AssetTransferApi, constructApiPromise } from '../src'; +import { TxResult } from '../src/types'; +import { GREEN, PURPLE, RESET } from './colors'; + +/** + * In this example we are creating a call to send 1 ROC from a asset-hub-rococo (System Parachain) account + * to a Rococo (Relay Chain) account, where the `xcmVersion` is set to 2, and the `isLimited` declaring that + * it will be `unlimited` since there is no `weightLimit` option as well. + * + * NOTE: + * + * - When `isLimited` is true it will use the `limited` version of the either `reserveAssetTransfer`, or `teleportAssets`. + * + * - Currently rococos asset-hub shares the same `specName` as kusamas asset-hub, therefore to use rococo you will need to hardcore the + * `specName` value as `asset-hub-rococo` into the `AssetTransferApi`. + */ +const main = async () => { + const { api, safeXcmVersion } = await constructApiPromise('wss://rococo-asset-hub-rpc.polkadot.io'); + const assetApi = new AssetTransferApi(api, 'asset-hub-rococo', safeXcmVersion); + + let callInfo: TxResult<'call'>; + try { + callInfo = await assetApi.createTransferTransaction( + '0', // NOTE: The destination id is `0` noting that we are sending to the relay chain. + '5EWNeodpcQ6iYibJ3jmWVe85nsok1EDG8Kk3aFg8ZzpfY1qX', + ['ROC'], + ['1000000000000'], + { + format: 'call', + isLimited: true, + xcmVersion: 2, + } + ); + + console.log(callInfo); + } catch (e) { + console.error(e); + throw Error(e as string); + } + + const decoded = assetApi.decodeExtrinsic(callInfo.tx, 'call'); + console.log(`\n${PURPLE}The following decoded tx:\n${GREEN} ${JSON.stringify(JSON.parse(decoded), null, 4)}${RESET}`); +}; + +main().finally(() => process.exit()); diff --git a/src/consts.ts b/src/consts.ts index 1d34f879..9b55014e 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -24,6 +24,7 @@ export const SYSTEM_PARACHAINS_NAMES = [ 'asset-hub-kusama', 'asset-hub-polkadot', 'asset-hub-westend', + 'asset-hub-rococo', 'bridge-hub-kusama', 'bridge-hub-polkadot', 'encointer-parachain', @@ -32,6 +33,7 @@ export const SYSTEM_PARACHAINS_NAMES = [ export const POLKADOT_ASSET_HUB_SPEC_NAMES = ['statemint', 'asset-hub-polkadot']; export const KUSAMA_ASSET_HUB_SPEC_NAMES = ['statemine', 'asset-hub-kusama']; export const WESTEND_ASSET_HUB_SPEC_NAMES = ['westmint', 'asset-hub-westend']; +export const ROCOCO_ASSET_HUB_SPEC_NAME = ['asset-hub-rococo']; /** * The default xcm version to construct a xcm message. diff --git a/src/registry/Registry.spec.ts b/src/registry/Registry.spec.ts index e2f77c51..a47bd002 100644 --- a/src/registry/Registry.spec.ts +++ b/src/registry/Registry.spec.ts @@ -3,6 +3,12 @@ import type { ForeignAssetsData } from './types'; describe('Registry', () => { const registry = new Registry('polkadot', {}); + describe('initialization', () => { + it('Should initalize rococo correctly', () => { + const registry = new Registry('rococo', {}); + expect(registry.relayChain).toEqual('rococo'); + }); + }); describe('lookupTokenSymbol', () => { it('Should return the correct result', () => { const res = registry.lookupTokenSymbol('GLMR'); diff --git a/src/registry/findRelayChain.ts b/src/registry/findRelayChain.ts index e994f6ed..5ab86d80 100644 --- a/src/registry/findRelayChain.ts +++ b/src/registry/findRelayChain.ts @@ -1,4 +1,9 @@ -import { KUSAMA_ASSET_HUB_SPEC_NAMES, POLKADOT_ASSET_HUB_SPEC_NAMES, WESTEND_ASSET_HUB_SPEC_NAMES } from '../consts'; +import { + KUSAMA_ASSET_HUB_SPEC_NAMES, + POLKADOT_ASSET_HUB_SPEC_NAMES, + ROCOCO_ASSET_HUB_SPEC_NAME, + WESTEND_ASSET_HUB_SPEC_NAMES, +} from '../consts'; import { BaseError, BaseErrorsEnum } from '../errors'; import type { ChainInfoRegistry, RelayChains } from './types'; /** @@ -21,5 +26,10 @@ export const findRelayChain = (specName: string, registry: ChainInfoRegistry): R if (westendChains.includes(specName.toLowerCase()) || WESTEND_ASSET_HUB_SPEC_NAMES.includes(specName.toLowerCase())) return 'westend'; + const rococoChains = Object.keys(registry.rococo).map((val) => registry.rococo[val].specName); + if (rococoChains.includes(specName.toLowerCase()) || ROCOCO_ASSET_HUB_SPEC_NAME) { + return 'rococo'; + } + throw new BaseError(`Cannot find the relay chain for specName: ${specName}`, BaseErrorsEnum.InternalError); }; diff --git a/src/registry/parseRegistry.spec.ts b/src/registry/parseRegistry.spec.ts index 5ca9cccc..d0370c04 100644 --- a/src/registry/parseRegistry.spec.ts +++ b/src/registry/parseRegistry.spec.ts @@ -11,7 +11,10 @@ describe('parseRegistry', () => { expect(registry.westend['0'].tokens).toStrictEqual(['WND']); expect(registry.rococo['0'].tokens).toStrictEqual(['ROC']); }); - + it('Should correctly overwrite rococos asset-hub specName', () => { + const registry = parseRegistry({}); + expect(registry.rococo['1000'].specName).toEqual('asset-hub-rococo'); + }); it('Should correctly inject an injectedRegsitry', () => { const assetsInfo = {}; const foreignAssetsInfo = {}; diff --git a/src/registry/parseRegistry.ts b/src/registry/parseRegistry.ts index dbe4c174..9cce8714 100644 --- a/src/registry/parseRegistry.ts +++ b/src/registry/parseRegistry.ts @@ -2,6 +2,7 @@ import registry from '@substrate/asset-transfer-api-registry'; +import { ASSET_HUB_CHAIN_ID } from '../consts'; import type { AssetTransferApiOpts } from '../types'; import type { ChainInfoRegistry } from './types'; @@ -19,5 +20,11 @@ export const parseRegistry = (assetsOpts: AssetTransferApiOpts): ChainInfoRegist if (rococo) Object.assign(registry.rococo, rococo); } + /** + * This is a temporary overwrite to ensure the statemine specName is not shared between + * kusama and rococo for their asset-hub chains. + */ + registry.rococo[ASSET_HUB_CHAIN_ID].specName = 'asset-hub-rococo'; + return registry as ChainInfoRegistry; };