diff --git a/src/AssetTransferApi.ts b/src/AssetTransferApi.ts index 8b38c4f4..a36340aa 100644 --- a/src/AssetTransferApi.ts +++ b/src/AssetTransferApi.ts @@ -53,6 +53,7 @@ import { TxResult, UnsignedTransaction, } from './types'; +import { resolveMultiLocation } from './util/resolveMultiLocation'; import { validateNumber } from './validate'; /** @@ -169,6 +170,8 @@ export class AssetTransferApi { const isForeignAssetsTransfer: boolean = this.checkIsForeignAssetTransfer(assetIds); const isPrimaryParachainNativeAsset = isParachainPrimaryNativeAsset(registry, _specName, xcmDirection, assetIds[0]); const xcmPallet = establishXcmPallet(_api, xcmDirection, isForeignAssetsTransfer, isPrimaryParachainNativeAsset); + const declaredXcmVersion = xcmVersion === undefined ? _safeXcmVersion : xcmVersion; + checkXcmVersion(declaredXcmVersion); // Throws an error when the xcmVersion is not supported. /** * Create a local asset transfer on a system parachain @@ -227,7 +230,7 @@ export class AssetTransferApi { : poolAssets.transfer(_api, addr, assetId, amount); palletMethod = `poolAssets::${method}`; } else { - const multiLocation = _api.registry.createType('MultiLocation', JSON.parse(assetId)); + const multiLocation = resolveMultiLocation(_api, assetId, declaredXcmVersion); tx = method === 'transferKeepAlive' ? foreignAssets.transferKeepAlive(_api, addr, multiLocation, amount) @@ -255,8 +258,6 @@ export class AssetTransferApi { } } - const declaredXcmVersion = xcmVersion === undefined ? _safeXcmVersion : xcmVersion; - checkXcmVersion(declaredXcmVersion); // Throws an error when the xcmVersion is not supported. await checkXcmTxInputs( _api, destChainId, diff --git a/src/createCalls/foreignAssets/transfer.spec.ts b/src/createCalls/foreignAssets/transfer.spec.ts index 84d17de8..edc90919 100644 --- a/src/createCalls/foreignAssets/transfer.spec.ts +++ b/src/createCalls/foreignAssets/transfer.spec.ts @@ -1,11 +1,12 @@ // Copyright 2023 Parity Technologies (UK) Ltd. import { mockSystemApi } from '../../testHelpers/mockSystemApi'; +import type { UnionXcmMultiLocation } from '../../types'; import { transfer } from './transfer'; describe('transfer', () => { it('Should construct a valid foreignAsset transfer extrinsic', () => { - const foreignAsset = mockSystemApi.createType('MultiLocation', { + const foreignAsset = mockSystemApi.createType('XcmV2MultiLocation', { parents: '1', interior: mockSystemApi.registry.createType('InteriorMultiLocation', { X2: [ @@ -17,7 +18,7 @@ describe('transfer', () => { }, ], }), - }); + }) as unknown as UnionXcmMultiLocation; const res = transfer( mockSystemApi, diff --git a/src/createCalls/foreignAssets/transfer.ts b/src/createCalls/foreignAssets/transfer.ts index 2510c05e..bd95c397 100644 --- a/src/createCalls/foreignAssets/transfer.ts +++ b/src/createCalls/foreignAssets/transfer.ts @@ -2,13 +2,14 @@ import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; -import { MultiLocation } from '@polkadot/types/interfaces'; import type { ISubmittableResult } from '@polkadot/types/types'; +import type { UnionXcmMultiLocation } from '../../types'; + export const transfer = ( api: ApiPromise, destAddr: string, - assetId: MultiLocation, + assetId: UnionXcmMultiLocation, amount: string ): SubmittableExtrinsic<'promise', ISubmittableResult> => { return api.tx.foreignAssets.transfer(assetId, destAddr, amount); diff --git a/src/createCalls/foreignAssets/transferKeepAlive.spec.ts b/src/createCalls/foreignAssets/transferKeepAlive.spec.ts index cf636171..b7e8a250 100644 --- a/src/createCalls/foreignAssets/transferKeepAlive.spec.ts +++ b/src/createCalls/foreignAssets/transferKeepAlive.spec.ts @@ -1,11 +1,12 @@ // Copyright 2023 Parity Technologies (UK) Ltd. import { mockSystemApi } from '../../testHelpers/mockSystemApi'; +import type { UnionXcmMultiLocation } from '../../types'; import { transferKeepAlive } from './transferKeepAlive'; describe('transfer', () => { it('Should construct a valid foreignAssets transferKeepAlive extrinsic', () => { - const foreignAssetMultiLocation = mockSystemApi.createType('MultiLocation', { + const foreignAssetMultiLocation = mockSystemApi.createType('XcmV2MultiLocation', { parents: '1', interior: mockSystemApi.registry.createType('InteriorMultiLocation', { X2: [ @@ -17,7 +18,7 @@ describe('transfer', () => { }, ], }), - }); + }) as unknown as UnionXcmMultiLocation; const res = transferKeepAlive( mockSystemApi, diff --git a/src/createCalls/foreignAssets/transferKeepAlive.ts b/src/createCalls/foreignAssets/transferKeepAlive.ts index 12d6d562..6898566c 100644 --- a/src/createCalls/foreignAssets/transferKeepAlive.ts +++ b/src/createCalls/foreignAssets/transferKeepAlive.ts @@ -2,13 +2,14 @@ import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; -import { MultiLocation } from '@polkadot/types/interfaces'; import type { ISubmittableResult } from '@polkadot/types/types'; +import type { UnionXcmMultiLocation } from '../../types'; + export const transferKeepAlive = ( api: ApiPromise, destAddr: string, - assetId: MultiLocation, + assetId: UnionXcmMultiLocation, amount: string ): SubmittableExtrinsic<'promise', ISubmittableResult> => { return api.tx.foreignAssets.transferKeepAlive(assetId, destAddr, amount); diff --git a/src/createXcmTypes/ParaToSystem.ts b/src/createXcmTypes/ParaToSystem.ts index e278d794..62ad0539 100644 --- a/src/createXcmTypes/ParaToSystem.ts +++ b/src/createXcmTypes/ParaToSystem.ts @@ -4,26 +4,27 @@ import type { ApiPromise } from '@polkadot/api'; import type { u32 } from '@polkadot/types'; import type { MultiAssetsV2, - MultiLocation, VersionedMultiAssets, VersionedMultiLocation, WeightLimitV2, } from '@polkadot/types/interfaces'; import type { XcmV3MultiassetMultiAssets } from '@polkadot/types/lookup'; +import type { AnyJson } from '@polkadot/types/types'; import { BaseError, BaseErrorsEnum } from '../errors'; import { Registry } from '../registry'; import { XCMChainInfoDataKeys, XCMChainInfoKeys } from '../registry/types'; import { Direction, - MultiAsset, + FungibleObjMultiAsset, + FungibleStrMultiAsset, XCMDestBenificiary, - XcmMultiAsset, XcmMultiLocation, XcmVersionedMultiAsset, } from '../types'; import { getFeeAssetItemIndex } from '../util/getFeeAssetItemIndex'; import { normalizeArrToStr } from '../util/normalizeArrToStr'; +import { resolveMultiLocation } from '../util/resolveMultiLocation'; import { validateNumber } from '../validate'; import type { CreateAssetsOpts, @@ -125,6 +126,7 @@ export const ParaToSystem: ICreateXcmType = { amounts, specName, assets, + xcmVersion, opts.registry, opts.isForeignAssetsTransfer ); @@ -193,6 +195,7 @@ export const ParaToSystem: ICreateXcmType = { normalizeArrToStr(amounts), specName, assetIds, + xcmVersion, registry, opts.isForeignAssetsTransfer ); @@ -283,9 +286,9 @@ export const ParaToSystem: ICreateXcmType = { } } - const xcAssetMultiLocation = (xcAsset as XCMChainInfoDataKeys).xcmV1MultiLocation.v1; + const xcAssetMultiLocation = (xcAsset as XCMChainInfoDataKeys).xcmV1MultiLocation.v1 as unknown as AnyJson; - const concreteMultiLocation = api.registry.createType('MultiLocation', xcAssetMultiLocation); + const concreteMultiLocation = resolveMultiLocation(api, xcAssetMultiLocation, xcmVersion); const multiAsset = { id: { @@ -297,13 +300,9 @@ export const ParaToSystem: ICreateXcmType = { }; if (xcmVersion === 2) { - return { - V2: multiAsset, - }; + return { V2: multiAsset }; } else { - return { - V3: multiAsset, - }; + return { V3: multiAsset }; } }, @@ -311,7 +310,7 @@ export const ParaToSystem: ICreateXcmType = { const { paysWithFeeDest, xcmVersion } = opts; if (xcmVersion && paysWithFeeDest) { - const paysWithFeeMultiLocation = api.registry.createType('MultiLocation', JSON.parse(paysWithFeeDest)); + const paysWithFeeMultiLocation = resolveMultiLocation(api, paysWithFeeDest, xcmVersion); if (xcmVersion === 2) { return { @@ -348,7 +347,7 @@ const createXTokensMultiAssets = async ( const { xcAssets } = registry; const currentRelayChainSpecName = registry.relayChain; - let multiAssets: XcmMultiAsset[] = []; + let multiAssets: FungibleObjMultiAsset[] = []; for (let i = 0; i < assets.length; i++) { const amount = amounts[i]; @@ -381,9 +380,9 @@ const createXTokensMultiAssets = async ( } } } - const xcAssetMultiLocation = (xcAsset as XCMChainInfoDataKeys).xcmV1MultiLocation.v1; + const xcAssetMultiLocation = (xcAsset as XCMChainInfoDataKeys).xcmV1MultiLocation.v1 as unknown as AnyJson; - const concreteMultiLocation = api.registry.createType('MultiLocation', xcAssetMultiLocation); + const concreteMultiLocation = resolveMultiLocation(api, xcAssetMultiLocation, xcmVersion); const multiAsset = { id: { @@ -397,8 +396,8 @@ const createXTokensMultiAssets = async ( multiAssets.push(multiAsset); } - multiAssets = sortMultiAssetsAscending(multiAssets) as XcmMultiAsset[]; - const sortedAndDedupedMultiAssets = dedupeMultiAssets(multiAssets) as XcmMultiAsset[]; + multiAssets = sortMultiAssetsAscending(multiAssets) as FungibleObjMultiAsset[]; + const sortedAndDedupedMultiAssets = dedupeMultiAssets(multiAssets) as FungibleObjMultiAsset[]; if (xcmVersion === 2) { const multiAssetsType: MultiAssetsV2 = api.registry.createType( 'XcmV2MultiassetMultiAssets', @@ -437,14 +436,15 @@ const createParaToSystemMultiAssets = async ( amounts: string[], specName: string, assets: string[], + xcmVersion: number, registry: Registry, isForeignAssetsTransfer: boolean -): Promise => { +): Promise => { const { xcAssets } = registry; const currentRelayChainSpecName = registry.relayChain; const palletId = fetchPalletInstanceId(api, false, isForeignAssetsTransfer); - let multiAssets: MultiAsset[] = []; - let concreteMultiLocation: MultiLocation; + let multiAssets: FungibleStrMultiAsset[] = []; + let concreteMultiLocation; const isPrimaryParachainNativeAsset = isParachainPrimaryNativeAsset( registry, specName, @@ -453,10 +453,14 @@ const createParaToSystemMultiAssets = async ( ); if (isPrimaryParachainNativeAsset) { - concreteMultiLocation = api.registry.createType('MultiLocation', { - parents: 0, - interior: { Here: '' }, - }); + concreteMultiLocation = resolveMultiLocation( + api, + { + parents: 0, + interior: { Here: '' }, + }, + xcmVersion + ); const multiAsset = { id: { @@ -500,12 +504,12 @@ const createParaToSystemMultiAssets = async ( } } } - const xcAssetMultiLocation = (xcAsset as XCMChainInfoDataKeys).xcmV1MultiLocation.v1; + const xcAssetMultiLocation = (xcAsset as XCMChainInfoDataKeys).xcmV1MultiLocation.v1 as unknown as AnyJson; if (isForeignAssetsTransfer) { - concreteMultiLocation = constructForeignAssetMultiLocationFromAssetId(api, assetId, palletId); + concreteMultiLocation = constructForeignAssetMultiLocationFromAssetId(api, assetId, palletId, xcmVersion); } else { - concreteMultiLocation = api.registry.createType('MultiLocation', xcAssetMultiLocation); + concreteMultiLocation = resolveMultiLocation(api, xcAssetMultiLocation, xcmVersion); } const multiAsset = { @@ -520,9 +524,9 @@ const createParaToSystemMultiAssets = async ( } } - multiAssets = sortMultiAssetsAscending(multiAssets) as MultiAsset[]; + multiAssets = sortMultiAssetsAscending(multiAssets) as FungibleStrMultiAsset[]; - const sortedAndDedupedMultiAssets = dedupeMultiAssets(multiAssets) as MultiAsset[]; + const sortedAndDedupedMultiAssets = dedupeMultiAssets(multiAssets) as FungibleStrMultiAsset[]; return sortedAndDedupedMultiAssets; }; diff --git a/src/createXcmTypes/SystemToPara.spec.ts b/src/createXcmTypes/SystemToPara.spec.ts index c4e7d6b3..818d826f 100644 --- a/src/createXcmTypes/SystemToPara.spec.ts +++ b/src/createXcmTypes/SystemToPara.spec.ts @@ -2,7 +2,7 @@ import { Registry } from '../registry'; import { mockSystemApi } from '../testHelpers/mockSystemApi'; -import { MultiAsset } from '../types'; +import { FungibleStrMultiAsset } from '../types'; import { SystemToPara } from './SystemToPara'; import { createSystemToParaMultiAssets } from './SystemToPara'; @@ -300,16 +300,16 @@ describe('SystemToPara XcmVersioned Generation', () => { describe('createSystemToParaMultiAssets', () => { it('Should correctly create system multi assets for SystemToPara xcm direction', async () => { - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '300000000000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '11' }], - }), + }, parents: 0, }), }, @@ -319,10 +319,10 @@ describe('SystemToPara XcmVersioned Generation', () => { Fungible: '100000000000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { Here: '', - }), + }, parents: 1, }), }, @@ -338,6 +338,7 @@ describe('SystemToPara XcmVersioned Generation', () => { specName, assets, registry, + 2, false, false ); diff --git a/src/createXcmTypes/SystemToPara.ts b/src/createXcmTypes/SystemToPara.ts index 85534b9a..cef91318 100644 --- a/src/createXcmTypes/SystemToPara.ts +++ b/src/createXcmTypes/SystemToPara.ts @@ -3,9 +3,7 @@ import type { ApiPromise } from '@polkadot/api'; import type { u32 } from '@polkadot/types'; import type { - InteriorMultiLocation, MultiAssetsV2, - MultiLocation, VersionedMultiAssets, VersionedMultiLocation, WeightLimitV2, @@ -15,7 +13,7 @@ import { isEthereumAddress } from '@polkadot/util-crypto'; import { BaseError, BaseErrorsEnum } from '../errors'; import type { Registry } from '../registry'; -import { MultiAsset } from '../types'; +import { FungibleStrMultiAsset, UnionXcmMultiLocation } from '../types'; import { getFeeAssetItemIndex } from '../util/getFeeAssetItemIndex'; import { normalizeArrToStr } from '../util/normalizeArrToStr'; import { validateNumber } from '../validate'; @@ -121,6 +119,7 @@ export const SystemToPara: ICreateXcmType = { specName, assets, registry, + xcmVersion, isForeignAssetsTransfer, isLiquidTokenTransfer ); @@ -200,6 +199,7 @@ export const SystemToPara: ICreateXcmType = { specName, assetIds, registry, + xcmVersion, isForeignAssetsTransfer, isLiquidTokenTransfer ); @@ -242,10 +242,11 @@ export const createSystemToParaMultiAssets = async ( specName: string, assets: string[], registry: Registry, + xcmVersion: number, isForeignAssetsTransfer: boolean, isLiquidTokenTransfer: boolean -): Promise => { - let multiAssets: MultiAsset[] = []; +): Promise => { + let multiAssets: FungibleStrMultiAsset[] = []; const palletId = fetchPalletInstanceId(api, isLiquidTokenTransfer, isForeignAssetsTransfer); const systemChainId = registry.lookupChainIdBySpecName(specName); @@ -269,19 +270,19 @@ export const createSystemToParaMultiAssets = async ( assetId = await getAssetId(api, registry, assetId, specName, isForeignAssetsTransfer); } - let concreteMultiLocation: MultiLocation; + let concreteMultiLocation: UnionXcmMultiLocation; if (isForeignAssetsTransfer) { - concreteMultiLocation = constructForeignAssetMultiLocationFromAssetId(api, assetId, palletId); + concreteMultiLocation = constructForeignAssetMultiLocationFromAssetId(api, assetId, palletId, xcmVersion); } else { const parents = isRelayNative ? 1 : 0; - const interior: InteriorMultiLocation = isRelayNative - ? api.registry.createType('InteriorMultiLocation', { Here: '' }) - : api.registry.createType('InteriorMultiLocation', { + const interior = isRelayNative + ? { Here: '' } + : { X2: [{ PalletInstance: palletId }, { GeneralIndex: assetId }], - }); + }; - concreteMultiLocation = api.registry.createType('MultiLocation', { + concreteMultiLocation = api.registry.createType('XcmV2MultiLocation', { parents, interior, }); @@ -299,9 +300,9 @@ export const createSystemToParaMultiAssets = async ( multiAssets.push(multiAsset); } - multiAssets = sortMultiAssetsAscending(multiAssets) as MultiAsset[]; + multiAssets = sortMultiAssetsAscending(multiAssets) as FungibleStrMultiAsset[]; - const sortedAndDedupedMultiAssets = dedupeMultiAssets(multiAssets) as MultiAsset[]; + const sortedAndDedupedMultiAssets = dedupeMultiAssets(multiAssets) as FungibleStrMultiAsset[]; return sortedAndDedupedMultiAssets; }; diff --git a/src/createXcmTypes/SystemToSystem.ts b/src/createXcmTypes/SystemToSystem.ts index 9f69aa99..1afcd90c 100644 --- a/src/createXcmTypes/SystemToSystem.ts +++ b/src/createXcmTypes/SystemToSystem.ts @@ -3,9 +3,7 @@ import type { ApiPromise } from '@polkadot/api'; import { u32 } from '@polkadot/types'; import type { - InteriorMultiLocation, MultiAssetsV2, - MultiLocation, VersionedMultiAssets, VersionedMultiLocation, WeightLimitV2, @@ -16,8 +14,9 @@ import { BaseError, BaseErrorsEnum } from '../errors'; import type { Registry } from '../registry'; import { getFeeAssetItemIndex } from '../util/getFeeAssetItemIndex'; import { normalizeArrToStr } from '../util/normalizeArrToStr'; +import { resolveMultiLocation } from '../util/resolveMultiLocation'; import { validateNumber } from '../validate'; -import { MultiAsset } from './../types'; +import { FungibleStrMultiAsset, UnionXcmMultiLocation } from './../types'; import { CreateAssetsOpts, CreateFeeAssetItemOpts, CreateWeightLimitOpts, ICreateXcmType, IWeightLimit } from './types'; import { dedupeMultiAssets } from './util/dedupeMultiAssets'; import { fetchPalletInstanceId } from './util/fetchPalletInstanceId'; @@ -114,6 +113,7 @@ export const SystemToSystem: ICreateXcmType = { specName, assets, registry, + xcmVersion, isForeignAssetsTransfer, isLiquidTokenTransfer ); @@ -193,6 +193,7 @@ export const SystemToSystem: ICreateXcmType = { specName, assetIds, registry, + xcmVersion, isForeignAssetsTransfer, isLiquidTokenTransfer ); @@ -237,10 +238,11 @@ export const createSystemToSystemMultiAssets = async ( specName: string, assets: string[], registry: Registry, + xcmVersion: number, isForeignAssetsTransfer: boolean, isLiquidTokenTransfer: boolean -): Promise => { - let multiAssets: MultiAsset[] = []; +): Promise => { + let multiAssets: FungibleStrMultiAsset[] = []; const systemChainId = registry.lookupChainIdBySpecName(specName); const palletId = fetchPalletInstanceId(api, isLiquidTokenTransfer, isForeignAssetsTransfer); @@ -264,10 +266,10 @@ export const createSystemToSystemMultiAssets = async ( assetId = await getAssetId(api, registry, assetId, specName, isForeignAssetsTransfer); } - let concreteMultiLocation: MultiLocation; + let concreteMultiLocation: UnionXcmMultiLocation; if (isForeignAssetsTransfer) { - const assetIdMultiLocation = api.registry.createType('MultiLocation', JSON.parse(assetId)); + const assetIdMultiLocation = resolveMultiLocation(api, assetId, xcmVersion); // start of the junctions values of the assetId. + 1 to ignore the '[' const junctionsStartIndex = assetId.indexOf('[') + 1; @@ -283,21 +285,29 @@ export const createSystemToSystemMultiAssets = async ( const palletInstanceJunctionStr = `{"PalletInstance":"${palletId}"},`; const interiorMultiLocationStr = `{${numberOfJunctions}:[${palletInstanceJunctionStr}${junctions}]}`; - concreteMultiLocation = api.registry.createType('MultiLocation', { - parents: assetIdMultiLocation.parents, - interior: api.registry.createType('InteriorMultiLocation', JSON.parse(interiorMultiLocationStr)), - }); + concreteMultiLocation = resolveMultiLocation( + api, + { + parents: assetIdMultiLocation.parents.toNumber(), + interior: interiorMultiLocationStr, + }, + xcmVersion + ); } else { const parents = isRelayNative ? 1 : 0; - const interior: InteriorMultiLocation = isRelayNative - ? api.registry.createType('InteriorMultiLocation', { Here: '' }) - : api.registry.createType('InteriorMultiLocation', { + const interior = isRelayNative + ? { Here: '' } + : { X2: [{ PalletInstance: palletId }, { GeneralIndex: assetId }], - }); - concreteMultiLocation = api.registry.createType('MultiLocation', { - parents, - interior, - }); + }; + concreteMultiLocation = resolveMultiLocation( + api, + { + parents, + interior, + }, + xcmVersion + ); } const multiAsset = { @@ -312,9 +322,9 @@ export const createSystemToSystemMultiAssets = async ( multiAssets.push(multiAsset); } - multiAssets = sortMultiAssetsAscending(multiAssets) as MultiAsset[]; + multiAssets = sortMultiAssetsAscending(multiAssets) as FungibleStrMultiAsset[]; - const sortedAndDedupedMultiAssets = dedupeMultiAssets(multiAssets) as MultiAsset[]; + const sortedAndDedupedMultiAssets = dedupeMultiAssets(multiAssets) as FungibleStrMultiAsset[]; return sortedAndDedupedMultiAssets; }; diff --git a/src/createXcmTypes/util/constructForeignAssetMultiLocationFromAssetId.spec.ts b/src/createXcmTypes/util/constructForeignAssetMultiLocationFromAssetId.spec.ts index b4039032..b6349057 100644 --- a/src/createXcmTypes/util/constructForeignAssetMultiLocationFromAssetId.spec.ts +++ b/src/createXcmTypes/util/constructForeignAssetMultiLocationFromAssetId.spec.ts @@ -18,7 +18,8 @@ describe('constructForeignAssetMultiLocationFromAssetId', () => { const multiLocation = constructForeignAssetMultiLocationFromAssetId( mockSystemApi, assetId, - foreignAssetsPalletInstance + foreignAssetsPalletInstance, + 2 ); expect(JSON.stringify(multiLocation)).toEqual(JSON.stringify(expectedMultiLocation)); diff --git a/src/createXcmTypes/util/constructForeignAssetMultiLocationFromAssetId.ts b/src/createXcmTypes/util/constructForeignAssetMultiLocationFromAssetId.ts index 8af589f6..b9e21490 100644 --- a/src/createXcmTypes/util/constructForeignAssetMultiLocationFromAssetId.ts +++ b/src/createXcmTypes/util/constructForeignAssetMultiLocationFromAssetId.ts @@ -1,7 +1,10 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import { ApiPromise } from '@polkadot/api'; -import { MultiLocation } from '@polkadot/types/interfaces'; +import type { ApiPromise } from '@polkadot/api'; +import type { AnyJson } from '@polkadot/types/types'; + +import { UnionXcmMultiLocation } from '../../types'; +import { resolveMultiLocation } from '../../util/resolveMultiLocation'; /** * constructs a foreign asset multilocation from an assetId string @@ -15,10 +18,11 @@ import { MultiLocation } from '@polkadot/types/interfaces'; export const constructForeignAssetMultiLocationFromAssetId = ( api: ApiPromise, multiLocationAssetId: string, - foreignAssetsPalletInstance: string -): MultiLocation => { + foreignAssetsPalletInstance: string, + xcmVersion: number +): UnionXcmMultiLocation => { const numberOfAdditionalJunctions = 1; - const assetIdMultiLocation = api.registry.createType('MultiLocation', JSON.parse(multiLocationAssetId)); + const assetIdMultiLocation = resolveMultiLocation(api, multiLocationAssetId, xcmVersion); // start of the junctions values of the assetId. + 1 to ignore the '[' const junctionsStartIndex = multiLocationAssetId.indexOf('['); @@ -33,9 +37,10 @@ export const constructForeignAssetMultiLocationFromAssetId = ( const numberOfJunctions = `"X${junctionCount}"`; const palletInstanceJunctionStr = `{"PalletInstance":"${foreignAssetsPalletInstance}"},`; const interiorMultiLocationStr = `{${numberOfJunctions}:[${palletInstanceJunctionStr}${junctions}]}`; + const multiLocation = { + parents: assetIdMultiLocation.parents.toNumber(), + interior: JSON.parse(interiorMultiLocationStr) as AnyJson, + }; - return api.registry.createType('MultiLocation', { - parents: assetIdMultiLocation.parents, - interior: api.registry.createType('InteriorMultiLocation', JSON.parse(interiorMultiLocationStr)), - }); + return resolveMultiLocation(api, multiLocation, xcmVersion); }; diff --git a/src/createXcmTypes/util/dedupeMultiAssets.spec.ts b/src/createXcmTypes/util/dedupeMultiAssets.spec.ts index 8aa3f537..16bffee1 100644 --- a/src/createXcmTypes/util/dedupeMultiAssets.spec.ts +++ b/src/createXcmTypes/util/dedupeMultiAssets.spec.ts @@ -1,21 +1,21 @@ // Copyright 2023 Parity Technologies (UK) Ltd. import { mockSystemApi } from '../../testHelpers/mockSystemApi'; -import { MultiAsset } from '../../types'; +import type { FungibleStrMultiAsset } from '../../types'; import { dedupeMultiAssets } from './dedupeMultiAssets'; describe('dedupeMultiAssets', () => { it('Should dedupe a sorted list of MultiAssets', () => { - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, parents: 0, }), }, @@ -25,25 +25,25 @@ describe('dedupeMultiAssets', () => { Fungible: '200000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, parents: 1, }), }, }, ]; - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, parents: 0, }), }, @@ -53,10 +53,10 @@ describe('dedupeMultiAssets', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, parents: 0, }), }, @@ -66,10 +66,10 @@ describe('dedupeMultiAssets', () => { Fungible: '200000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, parents: 1, }), }, @@ -84,21 +84,21 @@ describe('dedupeMultiAssets', () => { }); it('Should correctly dedupe a sorted list of foreign asset MultiAssets', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [ { Parachain: '2000' }, { PalletInstance: '50' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }, ], - }), + }, }), }, }, @@ -107,15 +107,15 @@ describe('dedupeMultiAssets', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [ { Parachain: '2000' }, { PalletInstance: '50' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }, ], - }), + }, }), }, }, @@ -124,31 +124,31 @@ describe('dedupeMultiAssets', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '50' }, { GeneralIndex: '1' }], - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [ { Parachain: '2000' }, { PalletInstance: '50' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }, ], - }), + }, }), }, }, @@ -157,11 +157,11 @@ describe('dedupeMultiAssets', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '50' }, { GeneralIndex: '1' }], - }), + }, }), }, }, diff --git a/src/createXcmTypes/util/dedupeMultiAssets.ts b/src/createXcmTypes/util/dedupeMultiAssets.ts index 081e8fe8..666b9ba1 100644 --- a/src/createXcmTypes/util/dedupeMultiAssets.ts +++ b/src/createXcmTypes/util/dedupeMultiAssets.ts @@ -1,13 +1,15 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import { MultiAsset, XcmMultiAsset } from '../../types'; +import type { FungibleObjMultiAsset, FungibleStrMultiAsset } from '../../types'; /** * This removes duplicate multi assets when given a sorted list * * @param multiAssets MulitAsset[] */ -export const dedupeMultiAssets = (multiAssets: MultiAsset[] | XcmMultiAsset[]): MultiAsset[] | XcmMultiAsset[] => { +export const dedupeMultiAssets = ( + multiAssets: FungibleStrMultiAsset[] | FungibleObjMultiAsset[] +): FungibleStrMultiAsset[] | FungibleObjMultiAsset[] => { const dedupedAssets = []; for (let i = 0; i < multiAssets.length; i++) { @@ -27,8 +29,8 @@ export const dedupeMultiAssets = (multiAssets: MultiAsset[] | XcmMultiAsset[]): } if (typeof multiAssets[0].fun.Fungible === 'string') { - return dedupedAssets as MultiAsset[]; + return dedupedAssets as FungibleStrMultiAsset[]; } - return dedupedAssets as XcmMultiAsset[]; + return dedupedAssets as FungibleObjMultiAsset[]; }; diff --git a/src/createXcmTypes/util/sortMultiAssetsAscending.spec.ts b/src/createXcmTypes/util/sortMultiAssetsAscending.spec.ts index adbc84e3..e8e0baff 100644 --- a/src/createXcmTypes/util/sortMultiAssetsAscending.spec.ts +++ b/src/createXcmTypes/util/sortMultiAssetsAscending.spec.ts @@ -1,21 +1,21 @@ // Copyright 2023 Parity Technologies (UK) Ltd. import { mockSystemApi } from '../../testHelpers/mockSystemApi'; -import { MultiAsset, XcmMultiAsset } from '../../types'; +import { FungibleObjMultiAsset, FungibleStrMultiAsset } from '../../types'; import { sortMultiAssetsAscending } from './sortMultiAssetsAscending'; describe('sortMultiAssetsAscending', () => { it('Should sort an unsorted multi asset array in ascending order', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '300000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, parents: 1, }), }, @@ -25,11 +25,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { Here: '', - }), + }, }), }, }, @@ -38,27 +38,27 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, parents: 0, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { Here: '', - }), + }, }), }, }, @@ -67,10 +67,10 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, parents: 0, }), }, @@ -80,11 +80,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '300000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, }), }, }, @@ -99,19 +99,19 @@ describe('sortMultiAssetsAscending', () => { }); it('Should sort an unsorted multi foreign asset array of X1s in ascending order', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -120,13 +120,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 2, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978', }, - }), + }, }), }, }, @@ -135,31 +135,31 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA83397cEfcCFdE9re7B23F3g0C462eF099E9E995', }, - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -168,13 +168,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA83397cEfcCFdE9re7B23F3g0C462eF099E9E995', }, - }), + }, }), }, }, @@ -183,13 +183,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 2, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978', }, - }), + }, }), }, }, @@ -204,19 +204,19 @@ describe('sortMultiAssetsAscending', () => { }); it('Should correctly sort an unsorted multi asset array with the same `parents` and `Junction`type based on their `Junction` keys', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA83397cEfcCFdE9re7B23F3g0C462eF099E9E995', }, - }), + }, }), }, }, @@ -225,31 +225,31 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -258,13 +258,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA83397cEfcCFdE9re7B23F3g0C462eF099E9E995', }, - }), + }, }), }, }, @@ -279,19 +279,19 @@ describe('sortMultiAssetsAscending', () => { }); it('Should correctly sort an unsorted multiasset array with in ascending order when parents values are different', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA83397cEfcCFdE9re7B23F3g0C462eF099E9E995', }, - }), + }, }), }, }, @@ -300,13 +300,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -315,31 +315,31 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 2, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { PalletInstance: '50', }, - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA83397cEfcCFdE9re7B23F3g0C462eF099E9E995', }, - }), + }, }), }, }, @@ -348,13 +348,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -363,13 +363,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 2, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { PalletInstance: '50', }, - }), + }, }), }, }, @@ -384,17 +384,17 @@ describe('sortMultiAssetsAscending', () => { }); it('Should correctly sort based on differing first Junction key value for X2s when other fields are the same', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2023' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -403,27 +403,27 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2000' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2000' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -432,11 +432,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2023' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -451,17 +451,17 @@ describe('sortMultiAssetsAscending', () => { }); it('Should correctly sort based on differing third Junction key value for X3s when all other fields are the same', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, }), }, }, @@ -470,27 +470,27 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '50' }, { GeneralIndex: '1' }], - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '50' }, { GeneralIndex: '1' }], - }), + }, }), }, }, @@ -499,11 +499,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, }), }, }, @@ -518,17 +518,17 @@ describe('sortMultiAssetsAscending', () => { }); it('Should correctly sort different X2 MultiLocations', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2023' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -537,11 +537,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, }), }, }, @@ -550,27 +550,27 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2000' }, { GeneralIndex: '0' }], - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2000' }, { GeneralIndex: '0' }], - }), + }, }), }, }, @@ -579,11 +579,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2023' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -592,11 +592,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, }), }, }, @@ -611,17 +611,17 @@ describe('sortMultiAssetsAscending', () => { }); it('Should correctly sort based on differing GeneralIndex values for X3s when all other fields are the same', () => { - const multiAssets: XcmMultiAsset[] = [ + const multiAssets: FungibleObjMultiAsset[] = [ { fun: { Fungible: { Fungible: '200000000' }, }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '1000' }, { PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, }), }, }, @@ -630,27 +630,27 @@ describe('sortMultiAssetsAscending', () => { Fungible: { Fungible: '200000000' }, }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '1000' }, { PalletInstance: '50' }, { GeneralIndex: '8' }], - }), + }, }), }, }, ]; - const expected: XcmMultiAsset[] = [ + const expected: FungibleObjMultiAsset[] = [ { fun: { Fungible: { Fungible: '200000000' }, }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '1000' }, { PalletInstance: '50' }, { GeneralIndex: '8' }], - }), + }, }), }, }, @@ -659,17 +659,17 @@ describe('sortMultiAssetsAscending', () => { Fungible: { Fungible: '200000000' }, }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '1000' }, { PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, }), }, }, ]; - const res = sortMultiAssetsAscending(multiAssets) as XcmMultiAsset[]; + const res = sortMultiAssetsAscending(multiAssets) as FungibleObjMultiAsset[]; expect(res.length).toEqual(expected.length); expect(res[0].id).toEqual(expected[0].id); @@ -678,21 +678,21 @@ describe('sortMultiAssetsAscending', () => { }); it('Should correctly sort based on differing third Junction keys for X3s when all other fields are the same', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [ { Parachain: '2000' }, { PalletInstance: '50' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }, ], - }), + }, }), }, }, @@ -701,27 +701,27 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '50' }, { GeneralIndex: '1' }], - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '50' }, { GeneralIndex: '1' }], - }), + }, }), }, }, @@ -730,15 +730,15 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [ { Parachain: '2000' }, { PalletInstance: '50' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }, ], - }), + }, }), }, }, @@ -753,19 +753,19 @@ describe('sortMultiAssetsAscending', () => { }); it('Should sort an unsorted multi foreign asset array of Here, X1s and X2s in ascending order', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 2, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978', }, - }), + }, }), }, }, @@ -774,11 +774,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '300000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 2, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, }), }, }, @@ -787,11 +787,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2000' }, { GeneralIndex: '0' }], - }), + }, }), }, }, @@ -800,11 +800,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2000' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -813,11 +813,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2023' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -826,11 +826,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '300000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, }), }, }, @@ -839,11 +839,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '300000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, }), }, }, @@ -852,11 +852,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '55' }, { GeneralIndex: '0' }], - }), + }, }), }, }, @@ -865,11 +865,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { Here: '', - }), + }, }), }, }, @@ -878,13 +878,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -893,29 +893,29 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978', }, - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { Here: '', - }), + }, }), }, }, @@ -924,13 +924,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -939,13 +939,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978', }, - }), + }, }), }, }, @@ -954,11 +954,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2000' }, { GeneralIndex: '0' }], - }), + }, }), }, }, @@ -967,11 +967,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2000' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -980,11 +980,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2023' }, { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978' }], - }), + }, }), }, }, @@ -993,11 +993,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '300000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, }), }, }, @@ -1006,11 +1006,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '300000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, }), }, }, @@ -1019,11 +1019,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X3: [{ Parachain: '2000' }, { PalletInstance: '55' }, { GeneralIndex: '0' }], - }), + }, }), }, }, @@ -1032,13 +1032,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 2, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { GeneralKey: '0xA73397cE0cCFdE92e7B23F3d0C462eF099E9E978', }, - }), + }, }), }, }, @@ -1047,11 +1047,11 @@ describe('sortMultiAssetsAscending', () => { Fungible: '300000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 2, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, }), }, }, @@ -1066,19 +1066,19 @@ describe('sortMultiAssetsAscending', () => { }); it('Should correctly sort an unsorted multiasset array based on fungible value when all other values are the same', () => { - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { fun: { Fungible: '200000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -1087,31 +1087,31 @@ describe('sortMultiAssetsAscending', () => { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, ]; - const expected: MultiAsset[] = [ + const expected: FungibleStrMultiAsset[] = [ { fun: { Fungible: '100000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, @@ -1120,13 +1120,13 @@ describe('sortMultiAssetsAscending', () => { Fungible: '200000', }, id: { - Concrete: mockSystemApi.registry.createType('MultiLocation', { + Concrete: mockSystemApi.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: mockSystemApi.registry.createType('InteriorMultiLocation', { + interior: { X1: { Parachain: '2023', }, - }), + }, }), }, }, diff --git a/src/createXcmTypes/util/sortMultiAssetsAscending.ts b/src/createXcmTypes/util/sortMultiAssetsAscending.ts index a8668827..80653bb4 100644 --- a/src/createXcmTypes/util/sortMultiAssetsAscending.ts +++ b/src/createXcmTypes/util/sortMultiAssetsAscending.ts @@ -1,10 +1,10 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import { JunctionV1 } from '@polkadot/types/interfaces'; -import { ITuple } from '@polkadot/types-codec/types'; +import type { XcmV2Junction, XcmV3Junction } from '@polkadot/types/lookup'; +import type { ITuple } from '@polkadot/types-codec/types'; import { BN } from 'bn.js'; -import { MultiAsset, XcmMultiAsset } from '../../types'; +import type { FungibleObjMultiAsset, FungibleStrMultiAsset } from '../../types'; import { validateNumber } from '../../validate'; /** @@ -12,17 +12,19 @@ import { validateNumber } from '../../validate'; * * @param multiAssets MultiAsset[] */ -export const sortMultiAssetsAscending = (multiAssets: MultiAsset[] | XcmMultiAsset[]) => { +export const sortMultiAssetsAscending = (multiAssets: FungibleStrMultiAsset[] | FungibleObjMultiAsset[]) => { return multiAssets.sort((a, b) => { let parentSortOrder = 0; // sort order based on parents value let interiorMultiLocationTypeSortOrder = 0; // sort order based on interior multilocation type value (e.g. X1 < X2) let interiorMultiLocationSortOrder = 0; // sort order based on multilocation junction values let fungibleSortOrder = 0; // sort order based on fungible value if (typeof a.fun.Fungible === 'string' && typeof b.fun.Fungible === 'string') { - fungibleSortOrder = (a as MultiAsset).fun.Fungible.localeCompare((b as MultiAsset).fun.Fungible); + fungibleSortOrder = (a as FungibleStrMultiAsset).fun.Fungible.localeCompare( + (b as FungibleStrMultiAsset).fun.Fungible + ); } else { - fungibleSortOrder = (a as XcmMultiAsset).fun.Fungible.Fungible.localeCompare( - (b as XcmMultiAsset).fun.Fungible.Fungible + fungibleSortOrder = (a as FungibleObjMultiAsset).fun.Fungible.Fungible.localeCompare( + (b as FungibleObjMultiAsset).fun.Fungible.Fungible ); } @@ -47,8 +49,8 @@ export const sortMultiAssetsAscending = (multiAssets: MultiAsset[] | XcmMultiAss }; const getSameJunctionMultiLocationSortOrder = ( - a: MultiAsset | XcmMultiAsset, - b: MultiAsset | XcmMultiAsset + a: FungibleStrMultiAsset | FungibleObjMultiAsset, + b: FungibleStrMultiAsset | FungibleObjMultiAsset ): number => { let sortOrder = 0; @@ -103,14 +105,25 @@ const getSameJunctionMultiLocationSortOrder = ( return sortOrder; }; +type UnionJunction = XcmV3Junction | XcmV2Junction; + type MultiLocationJunctions = - | [JunctionV1, JunctionV1] - | [JunctionV1, JunctionV1, JunctionV1] - | [JunctionV1, JunctionV1, JunctionV1, JunctionV1] - | [JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1] - | [JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1] - | [JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1] - | [JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1, JunctionV1]; + | [UnionJunction, UnionJunction] + | [UnionJunction, UnionJunction, UnionJunction] + | [UnionJunction, UnionJunction, UnionJunction, UnionJunction] + | [UnionJunction, UnionJunction, UnionJunction, UnionJunction, UnionJunction] + | [UnionJunction, UnionJunction, UnionJunction, UnionJunction, UnionJunction, UnionJunction] + | [UnionJunction, UnionJunction, UnionJunction, UnionJunction, UnionJunction, UnionJunction, UnionJunction] + | [ + UnionJunction, + UnionJunction, + UnionJunction, + UnionJunction, + UnionJunction, + UnionJunction, + UnionJunction, + UnionJunction + ]; enum MultiLocationJunctionType { Parachain, @@ -122,6 +135,7 @@ enum MultiLocationJunctionType { GeneralKey, OnlyChild, Plurality, + GlobalConsensus, } const getSortOrderForX2ThroughX8 = (a: ITuple, b: ITuple): number => { diff --git a/src/types.ts b/src/types.ts index b30ebaed..db6f9132 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,9 +1,9 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import { ApiPromise } from '@polkadot/api'; +import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; -import { u8 } from '@polkadot/types'; -import { InteriorMultiLocation, MultiLocation } from '@polkadot/types/interfaces'; +import type { InteriorMultiLocation } from '@polkadot/types/interfaces'; +import type { XcmV2MultiLocation, XcmV3MultiLocation } from '@polkadot/types/lookup'; import type { ISubmittableResult } from '@polkadot/types/types'; import BN from 'bn.js'; @@ -223,21 +223,21 @@ export interface ChainInfo { specVersion: string; } -export type MultiAsset = { +export type FungibleStrMultiAsset = { fun: { Fungible: string; }; id: { - Concrete: MultiLocation; + Concrete: UnionXcmMultiLocation; }; }; -export type XcmMultiAsset = { +export type FungibleObjMultiAsset = { fun: { Fungible: { Fungible: string }; }; id: { - Concrete: MultiLocation; + Concrete: UnionXcmMultiLocation; }; }; @@ -359,26 +359,20 @@ export type XCMDestBenificiary = | XCMV2ParachainDestBenificiary | XCMV3ParachainDestBenificiary; -export interface XCMV2MultiAsset { +export interface IXcmV2MultiAsset { V2: { id: { - Concrete: { - parents: u8 | string | number; - interior: InteriorMultiLocation; - }; + Concrete: UnionXcmMultiLocation; }; fun: { Fungible: { Fungible: number | string }; }; }; } -export interface XCMV3MultiAsset { +export interface IXcmV3MultiAsset { V3: { id: { - Concrete: { - parents: u8 | string | number; - interior: InteriorMultiLocation; - }; + Concrete: UnionXcmMultiLocation; }; fun: { Fungible: { Fungible: number | string }; @@ -386,24 +380,24 @@ export interface XCMV3MultiAsset { }; } -export type XcmVersionedMultiAsset = XCMV2MultiAsset | XCMV3MultiAsset; +export type XcmVersionedMultiAsset = IXcmV2MultiAsset | IXcmV3MultiAsset; -export interface XCMV2MultiLocation { +export interface VersionedXcmV2MultiLocation { V2: { id: { - Concrete: MultiLocation; + Concrete: UnionXcmMultiLocation; }; }; } -export interface XCMV3MultiLocation { +export interface VersionedXcmV3MultiLocation { V3: { id: { - Concrete: MultiLocation; + Concrete: UnionXcmMultiLocation; }; }; } -export type XcmMultiLocation = XCMV2MultiLocation | XCMV3MultiLocation; +export type XcmMultiLocation = VersionedXcmV2MultiLocation | VersionedXcmV3MultiLocation; export interface XcmWeightUnlimited { Unlimited: null | undefined; @@ -451,3 +445,5 @@ export type AssetMetadata = { decimals: string; isFrozen: boolean; }; + +export type UnionXcmMultiLocation = XcmV3MultiLocation | XcmV2MultiLocation; diff --git a/src/util/getFeeAssetItemIndex.spec.ts b/src/util/getFeeAssetItemIndex.spec.ts index b09aec37..229e0203 100644 --- a/src/util/getFeeAssetItemIndex.spec.ts +++ b/src/util/getFeeAssetItemIndex.spec.ts @@ -6,10 +6,16 @@ import { AssetTransferApi } from '../AssetTransferApi'; import { Registry } from '../registry'; import { adjustedMockRelayApi } from '../testHelpers/adjustedMockRelayApi'; import { adjustedMockSystemApi } from '../testHelpers/adjustedMockSystemApi'; -import { MultiAsset } from '../types'; +import { FungibleStrMultiAsset } from '../types'; import { getFeeAssetItemIndex } from './getFeeAssetItemIndex'; -type Test = [paysWithFeeDest: string, specName: string, multiAssets: MultiAsset[], api: ApiPromise, expected: number]; +type Test = [ + paysWithFeeDest: string, + specName: string, + multiAssets: FungibleStrMultiAsset[], + api: ApiPromise, + expected: number +]; describe('getFeeAssetItemIndex', () => { const systemAssetsApi = new AssetTransferApi(adjustedMockSystemApi, 'statemine', 2); @@ -24,9 +30,9 @@ describe('getFeeAssetItemIndex', () => { [ { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { Here: '' }), + interior: { Here: '' }, }), }, fun: { @@ -35,11 +41,11 @@ describe('getFeeAssetItemIndex', () => { }, { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '8' }], - }), + }, }), }, fun: { @@ -56,9 +62,9 @@ describe('getFeeAssetItemIndex', () => { [ { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { Here: '' }), + interior: { Here: '' }, }), }, fun: { @@ -67,11 +73,11 @@ describe('getFeeAssetItemIndex', () => { }, { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '11' }], - }), + }, }), }, fun: { @@ -80,11 +86,11 @@ describe('getFeeAssetItemIndex', () => { }, { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, }), }, fun: { @@ -114,9 +120,9 @@ describe('getFeeAssetItemIndex', () => { [ { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { Here: '' }), + interior: { Here: '' }, }), }, fun: { @@ -125,11 +131,11 @@ describe('getFeeAssetItemIndex', () => { }, { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '8' }], - }), + }, }), }, fun: { @@ -138,11 +144,11 @@ describe('getFeeAssetItemIndex', () => { }, { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1984' }], - }), + }, }), }, fun: { @@ -159,9 +165,9 @@ describe('getFeeAssetItemIndex', () => { [ { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { Here: '' }), + interior: { Here: '' }, }), }, fun: { @@ -170,11 +176,11 @@ describe('getFeeAssetItemIndex', () => { }, { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '10' }], - }), + }, }), }, fun: { @@ -183,11 +189,11 @@ describe('getFeeAssetItemIndex', () => { }, { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '11' }], - }), + }, }), }, fun: { @@ -217,11 +223,11 @@ describe('getFeeAssetItemIndex', () => { [ { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ Parachain: '2125' }, { GeneralIndex: '0' }], - }), + }, }), }, fun: { @@ -245,14 +251,14 @@ describe('getFeeAssetItemIndex', () => { const paysWithFeeDest = '1984'; const specName = 'statemine'; - const multiAssets: MultiAsset[] = [ + const multiAssets: FungibleStrMultiAsset[] = [ { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 0, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { + interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1337' }], - }), + }, }), }, fun: { @@ -261,9 +267,9 @@ describe('getFeeAssetItemIndex', () => { }, { id: { - Concrete: systemAssetsApi._api.registry.createType('MultiLocation', { + Concrete: systemAssetsApi._api.registry.createType('XcmV2MultiLocation', { parents: 1, - interior: systemAssetsApi._api.registry.createType('InteriorMultiLocation', { Here: '' }), + interior: { Here: '' }, }), }, fun: { diff --git a/src/util/getFeeAssetItemIndex.ts b/src/util/getFeeAssetItemIndex.ts index fd66d7c0..ebbdb0ca 100644 --- a/src/util/getFeeAssetItemIndex.ts +++ b/src/util/getFeeAssetItemIndex.ts @@ -5,7 +5,7 @@ import { ApiPromise } from '@polkadot/api'; import { getAssetId } from '../createXcmTypes/util/getAssetId'; import { BaseError, BaseErrorsEnum } from '../errors'; import { Registry } from '../registry'; -import { MultiAsset } from '../types'; +import { FungibleStrMultiAsset } from '../types'; import { validateNumber } from '../validate/validateNumber'; /** @@ -20,7 +20,7 @@ export const getFeeAssetItemIndex = async ( api: ApiPromise, registry: Registry, paysWithFeeDest: string, - multiAssets: MultiAsset[], + multiAssets: FungibleStrMultiAsset[], specName: string, isForeignAssetsTransfer?: boolean ): Promise => { diff --git a/src/util/resolveMultiLocation.spec.ts b/src/util/resolveMultiLocation.spec.ts new file mode 100644 index 00000000..226527a6 --- /dev/null +++ b/src/util/resolveMultiLocation.spec.ts @@ -0,0 +1,12 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +import { adjustedMockSystemApi } from '../testHelpers/adjustedMockSystemApi'; +import { resolveMultiLocation } from './resolveMultiLocation'; + +describe('resolveMultiLocation', () => { + it('Should return V3 for globalConsensus', () => { + const str = '{"parents":2,"interior":{"x1":{"globalConsensus":{"polkadot":null}}}}'; + const res = resolveMultiLocation(adjustedMockSystemApi, str, 2); + expect(res.toRawType()).toEqual('{"parents":"u8","interior":"XcmV3Junctions"}'); + }); +}); diff --git a/src/util/resolveMultiLocation.ts b/src/util/resolveMultiLocation.ts new file mode 100644 index 00000000..e1963089 --- /dev/null +++ b/src/util/resolveMultiLocation.ts @@ -0,0 +1,30 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +import type { ApiPromise } from '@polkadot/api'; +import type { AnyJson } from '@polkadot/types/types'; + +import { SUPPORTED_XCM_VERSIONS } from '../consts'; +import { BaseError, BaseErrorsEnum } from '../errors/BaseError'; +import type { UnionXcmMultiLocation } from '../types'; + +export const resolveMultiLocation = ( + api: ApiPromise, + multiLocation: AnyJson, + xcmVersion: number +): UnionXcmMultiLocation => { + const multiLocationStr = typeof multiLocation === 'string' ? multiLocation : JSON.stringify(multiLocation); + // Ensure we check this first since the main difference between v2, and v3 is `globalConsensus` + if (multiLocationStr.includes('globalConsensus') || multiLocationStr.includes('GlobalConsensus')) { + return api.registry.createType('XcmV3MultiLocation', JSON.parse(multiLocationStr)); + } + + if (!SUPPORTED_XCM_VERSIONS.includes(xcmVersion)) { + throw new BaseError(`Invalid XcmVersion for mulitLocation construction`, BaseErrorsEnum.InternalError); + } + + if (xcmVersion === 2) { + return api.registry.createType('XcmV2MultiLocation', JSON.parse(multiLocationStr)); + } else { + return api.registry.createType('XcmV3MultiLocation', JSON.parse(multiLocationStr)); + } +};