Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove all use of MultiLocation, and use correct versioned type. #292

Merged
merged 12 commits into from
Sep 21, 2023
7 changes: 4 additions & 3 deletions src/AssetTransferApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
TxResult,
UnsignedTransaction,
} from './types';
import { resolveMultiLocation } from './util/resolveMultiLocation';
import { validateNumber } from './validate';

/**
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions src/createCalls/foreignAssets/transfer.spec.ts
Original file line number Diff line number Diff line change
@@ -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: [
Expand All @@ -17,7 +18,7 @@ describe('transfer', () => {
},
],
}),
});
}) as unknown as UnionXcmMultiLocation;

const res = transfer(
mockSystemApi,
Expand Down
5 changes: 3 additions & 2 deletions src/createCalls/foreignAssets/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions src/createCalls/foreignAssets/transferKeepAlive.spec.ts
Original file line number Diff line number Diff line change
@@ -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: [
Expand All @@ -17,7 +18,7 @@ describe('transfer', () => {
},
],
}),
});
}) as unknown as UnionXcmMultiLocation;

const res = transferKeepAlive(
mockSystemApi,
Expand Down
5 changes: 3 additions & 2 deletions src/createCalls/foreignAssets/transferKeepAlive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
62 changes: 33 additions & 29 deletions src/createXcmTypes/ParaToSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -125,6 +126,7 @@ export const ParaToSystem: ICreateXcmType = {
amounts,
specName,
assets,
xcmVersion,
opts.registry,
opts.isForeignAssetsTransfer
);
Expand Down Expand Up @@ -193,6 +195,7 @@ export const ParaToSystem: ICreateXcmType = {
normalizeArrToStr(amounts),
specName,
assetIds,
xcmVersion,
registry,
opts.isForeignAssetsTransfer
);
Expand Down Expand Up @@ -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: {
Expand All @@ -297,21 +300,17 @@ export const ParaToSystem: ICreateXcmType = {
};

if (xcmVersion === 2) {
return {
V2: multiAsset,
};
return { V2: multiAsset };
} else {
return {
V3: multiAsset,
};
return { V3: multiAsset };
}
},

createXTokensFeeAssetItem: (api: ApiPromise, opts: CreateFeeAssetItemOpts): XcmMultiLocation => {
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 {
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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: {
Expand All @@ -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',
Expand Down Expand Up @@ -437,14 +436,15 @@ const createParaToSystemMultiAssets = async (
amounts: string[],
specName: string,
assets: string[],
xcmVersion: number,
registry: Registry,
isForeignAssetsTransfer: boolean
): Promise<MultiAsset[]> => {
): Promise<FungibleStrMultiAsset[]> => {
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,
Expand All @@ -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: {
Expand Down Expand Up @@ -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 = {
Expand All @@ -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;
};
17 changes: 9 additions & 8 deletions src/createXcmTypes/SystemToPara.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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,
}),
},
Expand All @@ -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,
}),
},
Expand All @@ -338,6 +338,7 @@ describe('SystemToPara XcmVersioned Generation', () => {
specName,
assets,
registry,
2,
false,
false
);
Expand Down
Loading