From 5377acf26a7a80fd601f005e96eaefd27ddacd7f Mon Sep 17 00:00:00 2001 From: Tarik Gul <47201679+TarikGul@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:10:58 -0500 Subject: [PATCH] fix(internal): cleanup structure for args passed into calls (#328) --- src/AssetTransferApi.ts | 173 ++++-------------- .../limitedReserveTransferAssets.spec.ts | 163 +++++++---------- .../limitedReserveTransferAssets.ts | 25 +-- .../polkadotXcm/limitedTeleportAssets.spec.ts | 66 +++---- .../polkadotXcm/limitedTeleportAssets.ts | 25 +-- .../polkadotXcm/reserveTransferAssets.spec.ts | 104 ++++------- .../polkadotXcm/reserveTransferAssets.ts | 25 +-- .../polkadotXcm/teleportAssets.spec.ts | 56 +++--- .../polkadotXcm/teleportAssets.ts | 25 +-- src/createXcmCalls/polkadotXcm/types.ts | 5 + .../xTokens/transferMultiAsset.spec.ts | 89 +++------ .../xTokens/transferMultiAssetWithFee.spec.ts | 110 +++++------ .../xTokens/transferMultiAssets.spec.ts | 94 ++++------ .../xTokens/transferMultiasset.ts | 30 +-- .../xTokens/transferMultiassetWithFee.ts | 30 +-- .../xTokens/transferMultiassets.ts | 30 +-- src/createXcmCalls/xTokens/types.ts | 6 + src/createXcmTypes/types.ts | 7 - src/errors/checkXcmTxInputs.ts | 51 ++---- src/errors/types.ts | 10 + src/types.ts | 18 ++ 21 files changed, 389 insertions(+), 753 deletions(-) create mode 100644 src/createXcmCalls/polkadotXcm/types.ts create mode 100644 src/createXcmCalls/xTokens/types.ts create mode 100644 src/errors/types.ts diff --git a/src/AssetTransferApi.ts b/src/AssetTransferApi.ts index 2e0bad9f..b0468b40 100644 --- a/src/AssetTransferApi.ts +++ b/src/AssetTransferApi.ts @@ -271,24 +271,31 @@ export class AssetTransferApi { }); } } - - await checkXcmTxInputs( - _api, - destChainId, + const baseArgs = { + api: _api, + direction: xcmDirection as XcmDirection, + destAddr: addr, assetIds, amounts, - xcmDirection, - xcmPallet, - _specName, - registry, - isForeignAssetsTransfer, + destChainId, + xcmVersion: declaredXcmVersion, + specName: _specName, + registry: this.registry, + }; + + const baseOpts = { + isLimited, + weightLimit, + paysWithFeeDest, isLiquidTokenTransfer, - isPrimaryParachainNativeAsset, + isForeignAssetsTransfer, + }; + + await checkXcmTxInputs( + { ...baseArgs, xcmPallet }, { - xcmVersion: declaredXcmVersion, - paysWithFeeDest, - isLimited, - weightLimit, + ...baseOpts, + isPrimaryParachainNativeAsset, } ); @@ -315,147 +322,35 @@ export class AssetTransferApi { // This ensures paraToRelay always uses `transferMultiAsset`. if (xcmDirection === Direction.ParaToRelay || (!paysWithFeeDest && assetIds.length < 2)) { txMethod = 'transferMultiasset'; - transaction = await transferMultiasset( - _api, - xcmDirection, - addr, - assetIds, - amounts, - destChainId, - declaredXcmVersion, - _specName, - this.registry, - xcmPallet, - { - isLimited, - weightLimit, - paysWithFeeDest, - isForeignAssetsTransfer, - isLiquidTokenTransfer, - } - ); + transaction = await transferMultiasset({ ...baseArgs, xcmPallet }, baseOpts); } else if (paysWithFeeDest && paysWithFeeDest.includes('parents')) { txMethod = 'transferMultiassetWithFee'; - transaction = await transferMultiassetWithFee( - _api, - xcmDirection, - addr, - assetIds, - amounts, - destChainId, - declaredXcmVersion, - _specName, - this.registry, - xcmPallet, - { - isLimited, - weightLimit, - paysWithFeeDest, - isForeignAssetsTransfer, - isLiquidTokenTransfer, - } - ); + transaction = await transferMultiassetWithFee({ ...baseArgs, xcmPallet }, baseOpts); } else { txMethod = 'transferMultiassets'; - transaction = await transferMultiassets( - _api, - xcmDirection, - addr, - assetIds, - amounts, - destChainId, - declaredXcmVersion, - _specName, - this.registry, - xcmPallet, - { - isLimited, - weightLimit, - paysWithFeeDest, - isForeignAssetsTransfer, - isLiquidTokenTransfer, - } - ); + transaction = await transferMultiassets({ ...baseArgs, xcmPallet }, baseOpts); } } else if (assetCallType === AssetCallType.Reserve) { if (isLimited) { txMethod = 'limitedReserveTransferAssets'; - transaction = await limitedReserveTransferAssets( - _api, - xcmDirection as XcmDirection, - addr, - assetIds, - amounts, - destChainId, - declaredXcmVersion, - _specName, - this.registry, - { - isLimited, - weightLimit, - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + transaction = await limitedReserveTransferAssets(baseArgs, baseOpts); } else { txMethod = 'reserveTransferAssets'; - transaction = await reserveTransferAssets( - _api, - xcmDirection as XcmDirection, - addr, - assetIds, - amounts, - destChainId, - declaredXcmVersion, - _specName, - this.registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + transaction = await reserveTransferAssets(baseArgs, baseOpts); } } else { if (isLimited) { txMethod = 'limitedTeleportAssets'; - transaction = await limitedTeleportAssets( - _api, - xcmDirection as XcmDirection, - addr, - assetIds, - amounts, - destChainId, - declaredXcmVersion, - _specName, - this.registry, - { - isLimited, - weightLimit, - paysWithFeeDest, - isForeignAssetsTransfer, - isLiquidTokenTransfer: false, - } - ); + transaction = await limitedTeleportAssets(baseArgs, { + ...baseOpts, + isLiquidTokenTransfer: false, + }); } else { txMethod = 'teleportAssets'; - transaction = await teleportAssets( - _api, - xcmDirection as XcmDirection, - addr, - assetIds, - amounts, - destChainId, - declaredXcmVersion, - _specName, - this.registry, - { - paysWithFeeDest, - isForeignAssetsTransfer, - isLiquidTokenTransfer: false, - } - ); + transaction = await teleportAssets(baseArgs, { + ...baseOpts, + isLiquidTokenTransfer: false, + }); } } diff --git a/src/createXcmCalls/polkadotXcm/limitedReserveTransferAssets.spec.ts b/src/createXcmCalls/polkadotXcm/limitedReserveTransferAssets.spec.ts index e80c6f0c..9d596ac1 100644 --- a/src/createXcmCalls/polkadotXcm/limitedReserveTransferAssets.spec.ts +++ b/src/createXcmCalls/polkadotXcm/limitedReserveTransferAssets.spec.ts @@ -4,13 +4,28 @@ import type { ApiPromise } from '@polkadot/api'; import { Registry } from '../../registry'; import { adjustedMockSystemApi } from '../../testHelpers/adjustedMockSystemApi'; -import { Direction } from '../../types'; +import { Direction, XcmDirection } from '../../types'; import { limitedReserveTransferAssets } from './limitedReserveTransferAssets'; describe('limitedReserveTransferAssets', () => { const registry = new Registry('statemine', {}); describe('SystemToPara', () => { const isLiquidTokenTransfer = false; + const baseArgs = { + api: adjustedMockSystemApi, + direction: Direction.SystemToPara as XcmDirection, + destAddr: '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', + assetIds: ['1'], + amounts: ['100'], + destChainId: '2023', + xcmVersion: 2, + specName: 'statemine', + registry, + }; + const FAbaseArgs = { + ...baseArgs, + assetIds: ['{"parents":"1","interior":{ "X2":[{"Parachain":"2125"},{"GeneralIndex":"0"}]}}'], + }; it('Should correctly construct a tx for a system parachain with V2', async () => { const isLimited = true; const refTime = '1000'; @@ -18,27 +33,16 @@ describe('limitedReserveTransferAssets', () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = false; - const ext = await limitedReserveTransferAssets( - adjustedMockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '2023', - 2, - 'statemine', - registry, - { - isLimited, - weightLimit: { - refTime, - proofSize, - }, - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await limitedReserveTransferAssets(baseArgs, { + isLimited, + weightLimit: { + refTime, + proofSize, + }, + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0x0d01041f08010101009d1f0100010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b0104000002043205040091010000000001a10f411f' @@ -51,27 +55,16 @@ describe('limitedReserveTransferAssets', () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = false; - const ext = await limitedReserveTransferAssets( - adjustedMockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '2023', - 2, - 'statemine', - registry, - { - isLimited, - weightLimit: { - refTime, - proofSize, - }, - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await limitedReserveTransferAssets(baseArgs, { + isLimited, + weightLimit: { + refTime, + proofSize, + }, + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0x1501041f08010101009d1f0100010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b010400000204320504009101000000000102286bee411f' @@ -84,52 +77,31 @@ describe('limitedReserveTransferAssets', () => { const proofSize = '2000'; const mockApi = { tx: {} } as unknown as ApiPromise; + const mockApiBaseArgs = { ...baseArgs, api: mockApi }; const paysWithFeeDest = undefined; const isForeignAssetsTransfer = true; await expect(async () => { - await limitedReserveTransferAssets( - mockApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '2023', - 2, - 'statemine', - registry, - { - isLimited, - weightLimit: { - refTime, - proofSize, - }, - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + await limitedReserveTransferAssets(mockApiBaseArgs, { + isLimited, + weightLimit: { + refTime, + proofSize, + }, + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); }).rejects.toThrowError("Can't find the `polkadotXcm` or `xcmPallet` pallet with the given API"); }); it('Should correctly construct a foreign asset tx for a system parachain with V2', async () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = true; - const ext = await limitedReserveTransferAssets( - adjustedMockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['{"parents":"1","interior":{ "X2":[{"Parachain":"2125"},{"GeneralIndex":"0"}]}}'], - ['100'], - '2023', - 2, - 'statemine', - registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await limitedReserveTransferAssets(FAbaseArgs, { + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0x0901041f08010101009d1f0100010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b0104000103043500352105000091010000000000' @@ -143,27 +115,16 @@ describe('limitedReserveTransferAssets', () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = true; - const ext = await limitedReserveTransferAssets( - adjustedMockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['{"parents":"1","interior":{ "X2":[{"Parachain":"2125"},{"GeneralIndex":"0"}]}}'], - ['100'], - '2023', - 2, - 'statemine', - registry, - { - isLimited, - weightLimit: { - refTime, - proofSize, - }, - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await limitedReserveTransferAssets(FAbaseArgs, { + isLimited, + weightLimit: { + refTime, + proofSize, + }, + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0x2101041f08010101009d1f0100010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b010400010304350035210500009101000000000102286bee411f' diff --git a/src/createXcmCalls/polkadotXcm/limitedReserveTransferAssets.ts b/src/createXcmCalls/polkadotXcm/limitedReserveTransferAssets.ts index 89807c2c..aedbe44e 100644 --- a/src/createXcmCalls/polkadotXcm/limitedReserveTransferAssets.ts +++ b/src/createXcmCalls/polkadotXcm/limitedReserveTransferAssets.ts @@ -1,43 +1,26 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; import type { ISubmittableResult } from '@polkadot/types/types'; import { createXcmTypes } from '../../createXcmTypes'; -import type { Registry } from '../../registry'; -import { XcmDirection } from '../../types'; import { normalizeArrToStr } from '../../util/normalizeArrToStr'; import type { CreateXcmCallOpts } from '../types'; import { establishXcmPallet } from '../util/establishXcmPallet'; +import type { PolkadotXcmBaseArgs } from './types'; /** * Build a Polkadot-js SubmittableExtrinsic for a `limitedReserveTransferAssets` * call. * - * @param api ApiPromise - * @param direction Denotes the xcm direction of the call. - * @param destAddr The address the funds will be transfered too. - * @param assetIds An array of asset ids. Note, this should be the same size and order as amounts. - * @param amounts An array of amounts. Note, this should be the same size and order as assetIds. - * @param destChainId The id of the destination chain. This will be zero for a relay chain. - * @param xcmVersion Supported XCM version. - * @param specName The specName for the current chain - * @param registry Registry + * @param baseArgs The base args needed to construct this call. * @param opts CreateXcmCallOpts */ export const limitedReserveTransferAssets = async ( - api: ApiPromise, - direction: XcmDirection, - destAddr: string, - assetIds: string[], - amounts: string[], - destChainId: string, - xcmVersion: number, - specName: string, - registry: Registry, + baseArgs: PolkadotXcmBaseArgs, opts: CreateXcmCallOpts ): Promise> => { + const { api, direction, destAddr, assetIds, amounts, destChainId, xcmVersion, specName, registry } = baseArgs; const { isLimited, weightLimit, paysWithFeeDest, isLiquidTokenTransfer, isForeignAssetsTransfer } = opts; const pallet = establishXcmPallet(api); const ext = api.tx[pallet].limitedReserveTransferAssets; diff --git a/src/createXcmCalls/polkadotXcm/limitedTeleportAssets.spec.ts b/src/createXcmCalls/polkadotXcm/limitedTeleportAssets.spec.ts index 56b4c8c9..41c63ffe 100644 --- a/src/createXcmCalls/polkadotXcm/limitedTeleportAssets.spec.ts +++ b/src/createXcmCalls/polkadotXcm/limitedTeleportAssets.spec.ts @@ -2,13 +2,24 @@ import type { ApiPromise } from '@polkadot/api'; import { Registry } from '../../registry'; import { mockSystemApi } from '../../testHelpers/mockSystemApi'; -import { Direction } from '../../types'; +import { Direction, XcmDirection } from '../../types'; import { limitedTeleportAssets } from './limitedTeleportAssets'; describe('limitedTeleportAssets', () => { const registry = new Registry('statemine', {}); describe('SystemToPara', () => { const isLiquidTokenTransfer = false; + const baseArgs = { + api: mockSystemApi, + direction: Direction.SystemToPara as XcmDirection, + destAddr: '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', + assetIds: ['1'], + amounts: ['100'], + destChainId: '1000', + xcmVersion: 2, + specName: 'statemine', + registry, + }; it('Should correctly construct a tx for a system parachain with V2', async () => { const isLimited = true; const refTime = '1000000000'; @@ -17,27 +28,16 @@ describe('limitedTeleportAssets', () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = false; - const ext = await limitedTeleportAssets( - mockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '1000', - 2, - 'statemine', - registry, - { - isLimited, - weightLimit: { - refTime, - proofSize, - }, - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await limitedTeleportAssets(baseArgs, { + isLimited, + weightLimit: { + refTime, + proofSize, + }, + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0x1501041f0901010100a10f0100010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b010400000204320504009101000000000102286bee411f' @@ -45,26 +45,16 @@ describe('limitedTeleportAssets', () => { }); it('Should error when a api does not support the required pallets', async () => { const mockApi = { tx: {} } as unknown as ApiPromise; + const mockApiBaseArgs = { ...baseArgs, api: mockApi }; const paysWithFeeDest = undefined; const isForeignAssetsTransfer = false; await expect(async () => { - await limitedTeleportAssets( - mockApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '1000', - 2, - 'statemine', - registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + await limitedTeleportAssets(mockApiBaseArgs, { + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); }).rejects.toThrowError("Can't find the `polkadotXcm` or `xcmPallet` pallet with the given API"); }); }); diff --git a/src/createXcmCalls/polkadotXcm/limitedTeleportAssets.ts b/src/createXcmCalls/polkadotXcm/limitedTeleportAssets.ts index 0efd7031..24539605 100644 --- a/src/createXcmCalls/polkadotXcm/limitedTeleportAssets.ts +++ b/src/createXcmCalls/polkadotXcm/limitedTeleportAssets.ts @@ -1,42 +1,25 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; import type { ISubmittableResult } from '@polkadot/types/types'; import { createXcmTypes } from '../../createXcmTypes'; -import type { Registry } from '../../registry'; -import { XcmDirection } from '../../types'; import { normalizeArrToStr } from '../../util/normalizeArrToStr'; import type { CreateXcmCallOpts } from '../types'; import { establishXcmPallet } from '../util/establishXcmPallet'; +import type { PolkadotXcmBaseArgs } from './types'; /** * Build a Polkadot-js SubmittableExtrinsic for a `limitedTeleportAssets` call. * - * @param api ApiPromise - * @param direction Denotes the xcm direction of the call. - * @param destAddr The address the funds will be transfered too. - * @param assetIds An array of asset ids. Note, this should be the same size and order as amounts. - * @param amounts An array of amounts. Note, this should be the same size and order as assetIds. - * @param destChainId The id of the destination chain. This will be zero for a relay chain. - * @param xcmVersion Supported XCM version. - * @param specName The specName for the current chain - * @param registry Registry + * @param baseArgs The base args needed to construct this call. * @param opts CreateXcmCallOpts */ export const limitedTeleportAssets = async ( - api: ApiPromise, - direction: XcmDirection, - destAddr: string, - assetIds: string[], - amounts: string[], - destChainId: string, - xcmVersion: number, - specName: string, - registry: Registry, + baseArgs: PolkadotXcmBaseArgs, opts: CreateXcmCallOpts ): Promise> => { + const { api, direction, destAddr, assetIds, amounts, destChainId, xcmVersion, specName, registry } = baseArgs; const { isLimited, weightLimit, paysWithFeeDest, isForeignAssetsTransfer } = opts; const pallet = establishXcmPallet(api); const ext = api.tx[pallet].limitedTeleportAssets; diff --git a/src/createXcmCalls/polkadotXcm/reserveTransferAssets.spec.ts b/src/createXcmCalls/polkadotXcm/reserveTransferAssets.spec.ts index 1d126c1a..1d5450e9 100644 --- a/src/createXcmCalls/polkadotXcm/reserveTransferAssets.spec.ts +++ b/src/createXcmCalls/polkadotXcm/reserveTransferAssets.spec.ts @@ -4,33 +4,38 @@ import type { ApiPromise } from '@polkadot/api'; import { Registry } from '../../registry'; import { adjustedMockSystemApi } from '../../testHelpers/adjustedMockSystemApi'; -import { Direction } from '../../types'; +import { Direction, XcmDirection } from '../../types'; import { reserveTransferAssets } from './reserveTransferAssets'; describe('reserveTransferAssets', () => { const registry = new Registry('statemine', {}); describe('SystemToPara', () => { const isLiquidTokenTransfer = false; + const baseArgs = { + api: adjustedMockSystemApi, + direction: Direction.SystemToPara as XcmDirection, + destAddr: '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', + assetIds: ['1'], + amounts: ['100'], + destChainId: '1000', + xcmVersion: 2, + specName: 'statemine', + registry, + }; + const FAbaseArgs = { + ...baseArgs, + assetIds: ['{"parents":"1","interior":{ "X2":[{"Parachain":"2125"},{"GeneralIndex":"0"}]}}'], + destChainId: '2023', + }; it('Should correctly construct a tx for a system parachain with V2', async () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = false; - const ext = await reserveTransferAssets( - adjustedMockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '1000', - 2, - 'statemine', - registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await reserveTransferAssets(baseArgs, { + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0xf8041f0201010100a10f0100010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b01040000020432050400910100000000' @@ -38,26 +43,16 @@ describe('reserveTransferAssets', () => { }); it('Should error when a api does not support the required pallets', async () => { const mockApi = { tx: {} } as unknown as ApiPromise; + const mockApiBaseArgs = { ...baseArgs, api: mockApi }; const paysWithFeeDest = undefined; const isForeignAssetsTransfer = false; await expect(async () => { - await reserveTransferAssets( - mockApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '1000', - 2, - 'statemine', - registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + await reserveTransferAssets(mockApiBaseArgs, { + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); }).rejects.toThrowError("Can't find the `polkadotXcm` or `xcmPallet` pallet with the given API"); }); @@ -65,22 +60,11 @@ describe('reserveTransferAssets', () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = true; - const ext = await reserveTransferAssets( - adjustedMockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['{"parents":"1","interior":{ "X2":[{"Parachain":"2125"},{"GeneralIndex":"0"}]}}'], - ['100'], - '2023', - 2, - 'statemine', - registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await reserveTransferAssets(FAbaseArgs, { + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0x0501041f02010101009d1f0100010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b01040001030435003521050000910100000000' @@ -90,23 +74,13 @@ describe('reserveTransferAssets', () => { it('Should correctly construct a foreign asset tx for a system parachain with V3 TEST', async () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = true; + const xcmVersionBaseArgs = { ...FAbaseArgs, xcmVersion: 3 }; - const ext = await reserveTransferAssets( - adjustedMockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['{"parents":"1","interior":{ "X2":[{"Parachain":"2125"},{"GeneralIndex":"0"}]}}'], - ['100'], - '2023', - 3, - 'statemine', - registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await reserveTransferAssets(xcmVersionBaseArgs, { + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0x0501041f02030101009d1f0300010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b03040001030435003521050000910100000000' diff --git a/src/createXcmCalls/polkadotXcm/reserveTransferAssets.ts b/src/createXcmCalls/polkadotXcm/reserveTransferAssets.ts index 28895ec6..97b45dcd 100644 --- a/src/createXcmCalls/polkadotXcm/reserveTransferAssets.ts +++ b/src/createXcmCalls/polkadotXcm/reserveTransferAssets.ts @@ -1,42 +1,25 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; import type { ISubmittableResult } from '@polkadot/types/types'; import { createXcmTypes } from '../../createXcmTypes'; -import type { Registry } from '../../registry'; -import { XcmDirection } from '../../types'; import { normalizeArrToStr } from '../../util/normalizeArrToStr'; import type { CreateXcmCallOpts } from '../types'; import { establishXcmPallet } from '../util/establishXcmPallet'; +import type { PolkadotXcmBaseArgs } from './types'; /** * Build a Polkadot-js SubmittableExtrinsic for a `reserveTransferAssets` call. * - * @param api ApiPromise - * @param direction Denotes the xcm direction of the call. - * @param destAddr The address the funds will be transfered too. - * @param assetIds An array of asset ids. Note, this should be the same size and order as amounts. - * @param amounts An array of amounts. Note, this should be the same size and order as assetIds. - * @param destChainId The id of the destination chain. This will be zero for a relay chain. - * @param xcmVersion Supported XCM version. - * @param specName The specName for the current chain - * @param registry Registry + * @param baseArgs The base args needed to construct this call. * @param opts CreateXcmCallOpts */ export const reserveTransferAssets = async ( - api: ApiPromise, - direction: XcmDirection, - destAddr: string, - assetIds: string[], - amounts: string[], - destChainId: string, - xcmVersion: number, - specName: string, - registry: Registry, + baseArgs: PolkadotXcmBaseArgs, opts: CreateXcmCallOpts ): Promise> => { + const { api, direction, destAddr, assetIds, amounts, destChainId, xcmVersion, specName, registry } = baseArgs; const { paysWithFeeDest, isLiquidTokenTransfer, isForeignAssetsTransfer } = opts; const pallet = establishXcmPallet(api); const ext = api.tx[pallet].reserveTransferAssets; diff --git a/src/createXcmCalls/polkadotXcm/teleportAssets.spec.ts b/src/createXcmCalls/polkadotXcm/teleportAssets.spec.ts index ea175536..655dcb0e 100644 --- a/src/createXcmCalls/polkadotXcm/teleportAssets.spec.ts +++ b/src/createXcmCalls/polkadotXcm/teleportAssets.spec.ts @@ -2,33 +2,33 @@ import type { ApiPromise } from '@polkadot/api'; import { Registry } from '../../registry'; import { mockSystemApi } from '../../testHelpers/mockSystemApi'; -import { Direction } from '../../types'; +import { Direction, XcmDirection } from '../../types'; import { teleportAssets } from './teleportAssets'; describe('teleportAssets', () => { const registry = new Registry('statemine', {}); describe('SystemToPara', () => { const isLiquidTokenTransfer = false; + const baseArgs = { + api: mockSystemApi, + direction: Direction.SystemToPara as XcmDirection, + destAddr: '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', + assetIds: ['1'], + amounts: ['100'], + destChainId: '2004', + xcmVersion: 2, + specName: 'statemine', + registry, + }; it('Should correctly construct a tx for a system parachain with V2', async () => { const paysWithFeeDest = undefined; const isForeignAssetsTransfer = false; - const ext = await teleportAssets( - mockSystemApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '2004', - 2, - 'statemine', - registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + const ext = await teleportAssets(baseArgs, { + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); expect(ext.toHex()).toBe( '0xf8041f0101010100511f0100010100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b01040000020432050400910100000000' @@ -36,26 +36,16 @@ describe('teleportAssets', () => { }); it('Should error when a api does not support the required pallets', async () => { const mockApi = { tx: {} } as unknown as ApiPromise; + const mockApiBaseArgs = { ...baseArgs, api: mockApi }; const paysWithFeeDest = undefined; const isForeignAssetsTransfer = true; await expect(async () => { - await teleportAssets( - mockApi, - Direction.SystemToPara, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['1'], - ['100'], - '1000', - 2, - 'statemine', - registry, - { - paysWithFeeDest, - isLiquidTokenTransfer, - isForeignAssetsTransfer, - } - ); + await teleportAssets(mockApiBaseArgs, { + paysWithFeeDest, + isLiquidTokenTransfer, + isForeignAssetsTransfer, + }); }).rejects.toThrowError("Can't find the `polkadotXcm` or `xcmPallet` pallet with the given API"); }); }); diff --git a/src/createXcmCalls/polkadotXcm/teleportAssets.ts b/src/createXcmCalls/polkadotXcm/teleportAssets.ts index cf5220e6..c868bd21 100644 --- a/src/createXcmCalls/polkadotXcm/teleportAssets.ts +++ b/src/createXcmCalls/polkadotXcm/teleportAssets.ts @@ -1,42 +1,25 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; import type { ISubmittableResult } from '@polkadot/types/types'; import { createXcmTypes } from '../../createXcmTypes'; -import { Registry } from '../../registry'; -import { XcmDirection } from '../../types'; import { normalizeArrToStr } from '../../util/normalizeArrToStr'; import type { CreateXcmCallOpts } from '../types'; import { establishXcmPallet } from '../util/establishXcmPallet'; +import type { PolkadotXcmBaseArgs } from './types'; /** * Build a Polkadot-js SubmittableExtrinsic for a `teleportAssets` call. * - * @param api ApiPromise - * @param direction Denotes the xcm direction of the call. - * @param destAddr The address the funds will be transfered too. - * @param assetIds An array of asset ids. Note, this should be the same size and order as amounts. - * @param amounts An array of amounts. Note, this should be the same size and order as assetIds. - * @param destChainId The id of the destination chain. This will be zero for a relay chain. - * @param xcmVersion Supported XCM version. - * @param specName The specName for the current chain - * @param registry Registry + * @param baseArgs The base args needed to construct this call. * @param opts CreateXcmCallOpts */ export const teleportAssets = async ( - api: ApiPromise, - direction: XcmDirection, - destAddr: string, - assetIds: string[], - amounts: string[], - destChainId: string, - xcmVersion: number, - specName: string, - registry: Registry, + baseArgs: PolkadotXcmBaseArgs, opts: CreateXcmCallOpts ): Promise> => { + const { api, direction, destAddr, assetIds, amounts, destChainId, xcmVersion, specName, registry } = baseArgs; const { paysWithFeeDest, isForeignAssetsTransfer } = opts; const pallet = establishXcmPallet(api); const ext = api.tx[pallet].teleportAssets; diff --git a/src/createXcmCalls/polkadotXcm/types.ts b/src/createXcmCalls/polkadotXcm/types.ts new file mode 100644 index 00000000..be141218 --- /dev/null +++ b/src/createXcmCalls/polkadotXcm/types.ts @@ -0,0 +1,5 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +import type { XcmBaseArgs } from '../../types'; + +export type PolkadotXcmBaseArgs = XcmBaseArgs; diff --git a/src/createXcmCalls/xTokens/transferMultiAsset.spec.ts b/src/createXcmCalls/xTokens/transferMultiAsset.spec.ts index 59bf65ca..b42b79ec 100644 --- a/src/createXcmCalls/xTokens/transferMultiAsset.spec.ts +++ b/src/createXcmCalls/xTokens/transferMultiAsset.spec.ts @@ -2,59 +2,46 @@ import { Registry } from '../../registry'; import { adjustedMockMoonriverParachainApi } from '../../testHelpers/adjustedMockMoonriverParachainApi'; -import { Direction } from '../../types'; +import { Direction, XcmDirection } from '../../types'; import { XcmPalletName } from '../util/establishXcmPallet'; import { transferMultiasset } from './transferMultiasset'; describe('transferMultiasset', () => { describe('ParaToSystem', () => { const registry = new Registry('moonriver', {}); - + const baseArgs = { + api: adjustedMockMoonriverParachainApi, + direction: Direction.ParaToSystem as XcmDirection, + destAddr: '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', + assetIds: ['311091173110107856861649819128533077277'], + amounts: ['1000000'], + destChainId: '1000', + xcmVersion: 2, + specName: 'moonriver', + registry, + xcmPallet: XcmPalletName.xTokens, + }; it('Should correctly construct an Unlimited transferMultiasset tx for V2', async () => { - const ext = await transferMultiasset( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['311091173110107856861649819128533077277'], - ['1000000'], - '1000', - 2, - 'moonriver', - registry, - XcmPalletName.xTokens, - { - isLimited: false, - isForeignAssetsTransfer: false, - isLiquidTokenTransfer: false, - } - ); + const ext = await transferMultiasset(baseArgs, { + isLimited: false, + isForeignAssetsTransfer: false, + isLiquidTokenTransfer: false, + }); expect(ext.toHex()).toBe( '0xf4046a010100010300a10f043205011f0002093d0001010200a10f0100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b00' ); }); it('Should correctly construct a Limited transferMultiasset tx for V2', async () => { - const ext = await transferMultiasset( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['311091173110107856861649819128533077277'], - ['1000000'], - '1000', - 2, - 'moonriver', - registry, - XcmPalletName.xTokens, - { - isLimited: true, - weightLimit: { - refTime: '1000', - proofSize: '2000', - }, - isForeignAssetsTransfer: false, - isLiquidTokenTransfer: false, - } - ); + const ext = await transferMultiasset(baseArgs, { + isLimited: true, + weightLimit: { + refTime: '1000', + proofSize: '2000', + }, + isForeignAssetsTransfer: false, + isLiquidTokenTransfer: false, + }); expect(ext.toHex()).toBe( '0x0501046a010100010300a10f043205011f0002093d0001010200a10f0100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b01a10f411f' @@ -63,16 +50,7 @@ describe('transferMultiasset', () => { it('Should correctly construct an Unlimited transferMultiasset tx for V3', async () => { const ext = await transferMultiasset( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['311091173110107856861649819128533077277'], - ['100'], - '1000', - 3, - 'moonriver', - registry, - XcmPalletName.xTokens, + { ...baseArgs, xcmVersion: 3, amounts: ['100'] }, { isLimited: false, isForeignAssetsTransfer: false, @@ -86,16 +64,7 @@ describe('transferMultiasset', () => { }); it('Should correctly construct a Limited transferMultiasset tx for V3', async () => { const ext = await transferMultiasset( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['42259045809535163221576417993425387648'], - ['1000000'], - '1000', - 3, - 'moonriver', - registry, - XcmPalletName.xTokens, + { ...baseArgs, xcmVersion: 3, assetIds: ['42259045809535163221576417993425387648'] }, { isLimited: true, weightLimit: { diff --git a/src/createXcmCalls/xTokens/transferMultiAssetWithFee.spec.ts b/src/createXcmCalls/xTokens/transferMultiAssetWithFee.spec.ts index 54558d39..cf61c28e 100644 --- a/src/createXcmCalls/xTokens/transferMultiAssetWithFee.spec.ts +++ b/src/createXcmCalls/xTokens/transferMultiAssetWithFee.spec.ts @@ -2,14 +2,25 @@ import { Registry } from '../../registry'; import { adjustedMockMoonriverParachainApi } from '../../testHelpers/adjustedMockMoonriverParachainApi'; -import { Direction } from '../../types'; +import { Direction, XcmDirection } from '../../types'; import { XcmPalletName } from '../util/establishXcmPallet'; import { transferMultiassetWithFee } from './transferMultiassetWithFee'; describe('transferMultiassetWithFee', () => { describe('ParaToSystem', () => { const registry = new Registry('moonriver', {}); - + const baseArgs = { + api: adjustedMockMoonriverParachainApi, + direction: Direction.ParaToSystem as XcmDirection, + destAddr: '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', + assetIds: ['311091173110107856861649819128533077277'], + amounts: ['1000000'], + destChainId: '1000', + xcmVersion: 2, + specName: 'moonriver', + registry, + xcmPallet: XcmPalletName.xTokens, + }; it('Should correctly construct an Unlimited transferMultiassetWithFee tx for V2', async () => { const isLimited = false; const refTime = undefined; @@ -17,28 +28,16 @@ describe('transferMultiassetWithFee', () => { const paysWithFeeDest = '{"parents": "1", "interior": {"X3": [{"Parachain": "1000"}, {"PalletInstance": "50"}, {"GeneralIndex": "1984"}]}}'; - const ext = await transferMultiassetWithFee( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['311091173110107856861649819128533077277'], - ['1000000'], - '1000', - 2, - 'moonriver', - registry, - XcmPalletName.xTokens, - { - isLimited, - weightLimit: { - refTime, - proofSize, - }, - paysWithFeeDest, - isForeignAssetsTransfer: false, - isLiquidTokenTransfer: false, - } - ); + const ext = await transferMultiassetWithFee(baseArgs, { + isLimited, + weightLimit: { + refTime, + proofSize, + }, + paysWithFeeDest, + isForeignAssetsTransfer: false, + isLiquidTokenTransfer: false, + }); expect(ext.toHex()).toBe( '0x2d01046a030100010300a10f043205011f0002093d000100010300a10f043205011f000001010200a10f0100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b00' @@ -51,28 +50,16 @@ describe('transferMultiassetWithFee', () => { const paysWithFeeDest = '{"parents": "1", "interior": {"X3": [{"Parachain": "1000"}, {"PalletInstance": "50"}, {"GeneralIndex": "1984"}]}}'; - const ext = await transferMultiassetWithFee( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['311091173110107856861649819128533077277'], - ['1000000'], - '1000', - 2, - 'moonriver', - registry, - XcmPalletName.xTokens, - { - isLimited, - weightLimit: { - refTime, - proofSize, - }, - paysWithFeeDest, - isForeignAssetsTransfer: false, - isLiquidTokenTransfer: false, - } - ); + const ext = await transferMultiassetWithFee(baseArgs, { + isLimited, + weightLimit: { + refTime, + proofSize, + }, + paysWithFeeDest, + isForeignAssetsTransfer: false, + isLiquidTokenTransfer: false, + }); expect(ext.toHex()).toBe( '0x3d01046a030100010300a10f043205011f0002093d000100010300a10f043205011f000001010200a10f0100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b01a10f411f' @@ -87,16 +74,12 @@ describe('transferMultiassetWithFee', () => { '{"parents": "1", "interior": {"X3": [{"Parachain": "1000"}, {"PalletInstance": "50"}, {"GeneralIndex": "1984"}]}}'; const ext = await transferMultiassetWithFee( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['42259045809535163221576417993425387648'], - ['10000000000'], - '1000', - 3, - 'moonriver', - registry, - XcmPalletName.xTokens, + { + ...baseArgs, + assetIds: ['42259045809535163221576417993425387648'], + amounts: ['10000000000'], + xcmVersion: 3, + }, { isLimited, weightLimit: { @@ -121,16 +104,11 @@ describe('transferMultiassetWithFee', () => { '{"parents": "1", "interior": {"X3": [{"Parachain": "1000"}, {"PalletInstance": "50"}, {"GeneralIndex": "1984"}]}}'; const ext = await transferMultiassetWithFee( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['311091173110107856861649819128533077277'], - ['100'], - '1000', - 3, - 'moonriver', - registry, - XcmPalletName.xTokens, + { + ...baseArgs, + amounts: ['100'], + xcmVersion: 3, + }, { isLimited, weightLimit: { diff --git a/src/createXcmCalls/xTokens/transferMultiAssets.spec.ts b/src/createXcmCalls/xTokens/transferMultiAssets.spec.ts index 5653fb82..84fe0f25 100644 --- a/src/createXcmCalls/xTokens/transferMultiAssets.spec.ts +++ b/src/createXcmCalls/xTokens/transferMultiAssets.spec.ts @@ -2,42 +2,41 @@ import { Registry } from '../../registry'; import { adjustedMockMoonriverParachainApi } from '../../testHelpers/adjustedMockMoonriverParachainApi'; -import { Direction } from '../../types'; +import { Direction, XcmDirection } from '../../types'; import { XcmPalletName } from '../util/establishXcmPallet'; import { transferMultiassets } from './transferMultiassets'; describe('transferMultiassets', () => { describe('ParaToSystem', () => { const registry = new Registry('moonriver', {}); - + const baseArgs = { + api: adjustedMockMoonriverParachainApi, + direction: Direction.ParaToSystem as XcmDirection, + destAddr: '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', + assetIds: ['42259045809535163221576417993425387648', '182365888117048807484804376330534607370'], + amounts: ['10000000000', '25000000000'], + destChainId: '1000', + xcmVersion: 2, + specName: 'moonriver', + registry, + xcmPallet: XcmPalletName.xTokens, + }; it('Should correctly construct an Unlimited transferMultiassets tx for V2', async () => { const isLimited = false; const refTime = undefined; const proofSize = undefined; const paysWithFeeDest = '0'; - const ext = await transferMultiassets( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['42259045809535163221576417993425387648', '182365888117048807484804376330534607370'], - ['10000000000', '25000000000'], - '1000', - 2, - 'moonriver', - registry, - XcmPalletName.xTokens, - { - isLimited, - weightLimit: { - refTime, - proofSize, - }, - paysWithFeeDest, - isForeignAssetsTransfer: false, - isLiquidTokenTransfer: false, - } - ); + const ext = await transferMultiassets(baseArgs, { + isLimited, + weightLimit: { + refTime, + proofSize, + }, + paysWithFeeDest, + isForeignAssetsTransfer: false, + isLiquidTokenTransfer: false, + }); expect(ext.toHex()).toBe( '0x3501046a050108000100000700e40b540200010300a10f04320520000700ba1dd2050000000001010200a10f0100f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b00' @@ -52,16 +51,11 @@ describe('transferMultiassets', () => { const paysWithFeeDest = '0'; const ext = await transferMultiassets( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['182365888117048807484804376330534607370', '311091173110107856861649819128533077277'], - ['1000000', '50000000000'], - '1000', - 2, - 'moonriver', - registry, - XcmPalletName.xTokens, + { + ...baseArgs, + assetIds: ['182365888117048807484804376330534607370', '311091173110107856861649819128533077277'], + amounts: ['1000000', '50000000000'], + }, { isLimited, weightLimit: { @@ -86,16 +80,12 @@ describe('transferMultiassets', () => { const paysWithFeeDest = '1'; const ext = await transferMultiassets( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['42259045809535163221576417993425387648', '311091173110107856861649819128533077277'], - ['20000000000', '1000000'], - '1000', - 3, - 'moonriver', - registry, - XcmPalletName.xTokens, + { + ...baseArgs, + assetIds: ['42259045809535163221576417993425387648', '311091173110107856861649819128533077277'], + amounts: ['20000000000', '1000000'], + xcmVersion: 3, + }, { isLimited, weightLimit: { @@ -119,16 +109,12 @@ describe('transferMultiassets', () => { const paysWithFeeDest = '0'; const ext = await transferMultiassets( - adjustedMockMoonriverParachainApi, - Direction.ParaToSystem, - '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', - ['311091173110107856861649819128533077277'], - ['1000000'], - '1000', - 3, - 'moonriver', - registry, - XcmPalletName.xTokens, + { + ...baseArgs, + assetIds: ['311091173110107856861649819128533077277'], + amounts: ['1000000'], + xcmVersion: 3, + }, { isLimited, weightLimit: { diff --git a/src/createXcmCalls/xTokens/transferMultiasset.ts b/src/createXcmCalls/xTokens/transferMultiasset.ts index 1bb020a1..dfd811f1 100644 --- a/src/createXcmCalls/xTokens/transferMultiasset.ts +++ b/src/createXcmCalls/xTokens/transferMultiasset.ts @@ -1,47 +1,27 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; import type { ISubmittableResult } from '@polkadot/types/types'; import { createXcmTypes } from '../../createXcmTypes'; import { BaseError, BaseErrorsEnum } from '../../errors'; -import type { Registry } from '../../registry'; -import { XcmDirection } from '../../types'; import type { CreateXcmCallOpts } from '../types'; -import { XcmPalletName } from '../util/establishXcmPallet'; +import type { XTokensBaseArgs } from './types'; /** * Build a Polkadot-js `transferMultiasset` SubmittableExtrinsic * call. * - * @param api ApiPromise - * @param direction Denotes the xcm direction of the call. - * @param destAddr The address the funds will be transfered too. - * @param assetIds An array of asset ids. Note, this should be the same size and order as amounts. - * @param amounts An array of amounts. Note, this should be the same size and order as assetIds. - * @param destChainId The id of the destination chain. This will be zero for a relay chain. - * @param xcmVersion Supported XCM version. - * @param specName The specName for the current chain - * @param registry Registry - * @param xcmPallet The pallet being used to construct xcm calls. + * @param baseArgs The base args needed to construct this call. * @param opts CreateXcmCallOpts */ export const transferMultiasset = async ( - api: ApiPromise, - direction: XcmDirection, - destAddr: string, - assetIds: string[], - amounts: string[], - destChainId: string, - xcmVersion: number, - specName: string, - registry: Registry, - xcmPallet: XcmPalletName, + baseArgs: XTokensBaseArgs, opts: CreateXcmCallOpts ): Promise> => { + const { api, direction, destAddr, assetIds, amounts, destChainId, xcmVersion, specName, registry } = baseArgs; const { isLimited, weightLimit, isForeignAssetsTransfer, isLiquidTokenTransfer } = opts; - const ext = api.tx[xcmPallet].transferMultiasset; + const ext = api.tx[baseArgs.xcmPallet].transferMultiasset; const typeCreator = createXcmTypes[direction]; const destWeightLimit = typeCreator.createWeightLimit({ isLimited, diff --git a/src/createXcmCalls/xTokens/transferMultiassetWithFee.ts b/src/createXcmCalls/xTokens/transferMultiassetWithFee.ts index 314d8768..eac85e0a 100644 --- a/src/createXcmCalls/xTokens/transferMultiassetWithFee.ts +++ b/src/createXcmCalls/xTokens/transferMultiassetWithFee.ts @@ -1,47 +1,27 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; import type { ISubmittableResult } from '@polkadot/types/types'; import { createXcmTypes } from '../../createXcmTypes'; import { BaseError, BaseErrorsEnum } from '../../errors'; -import type { Registry } from '../../registry'; -import { XcmDirection } from '../../types'; import type { CreateXcmCallOpts } from '../types'; -import { XcmPalletName } from '../util/establishXcmPallet'; +import type { XTokensBaseArgs } from './types'; /** * Build a Polkadot-js `transferMultiassetWithFee` SubmittableExtrinsic * call. * - * @param api ApiPromise - * @param direction Denotes the xcm direction of the call. - * @param destAddr The address the funds will be transfered too. - * @param assetIds An array of asset ids. Note, this should be the same size and order as amounts. - * @param amounts An array of amounts. Note, this should be the same size and order as assetIds. - * @param destChainId The id of the destination chain. This will be zero for a relay chain. - * @param xcmVersion Supported XCM version. - * @param specName The specName for the current chain - * @param registry Registry - * @param xcmPallet The pallet being used to construct xcm calls. + * @param baseArgs The base args needed to construct this call. * @param opts CreateXcmCallOpts */ export const transferMultiassetWithFee = async ( - api: ApiPromise, - direction: XcmDirection, - destAddr: string, - assetIds: string[], - amounts: string[], - destChainId: string, - xcmVersion: number, - specName: string, - registry: Registry, - xcmPallet: XcmPalletName, + baseArgs: XTokensBaseArgs, opts: CreateXcmCallOpts ): Promise> => { + const { api, direction, destAddr, assetIds, amounts, destChainId, xcmVersion, specName, registry } = baseArgs; const { isLimited, weightLimit, paysWithFeeDest, isForeignAssetsTransfer, isLiquidTokenTransfer } = opts; - const ext = api.tx[xcmPallet].transferMultiassetWithFee; + const ext = api.tx[baseArgs.xcmPallet].transferMultiassetWithFee; const typeCreator = createXcmTypes[direction]; const destWeightLimit = typeCreator.createWeightLimit({ isLimited, diff --git a/src/createXcmCalls/xTokens/transferMultiassets.ts b/src/createXcmCalls/xTokens/transferMultiassets.ts index c979d257..803dc2fd 100644 --- a/src/createXcmCalls/xTokens/transferMultiassets.ts +++ b/src/createXcmCalls/xTokens/transferMultiassets.ts @@ -1,6 +1,5 @@ // Copyright 2023 Parity Technologies (UK) Ltd. -import type { ApiPromise } from '@polkadot/api'; import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types'; import type { ISubmittableResult } from '@polkadot/types/types'; @@ -8,42 +7,23 @@ import { createXcmTypes } from '../../createXcmTypes'; import type { XcmDestBenificiaryXcAssets } from '../../createXcmTypes/types'; import { UnionXcAssetsMultiAssets } from '../../createXcmTypes/types'; import { BaseError, BaseErrorsEnum } from '../../errors'; -import type { Registry } from '../../registry'; -import { XcmDirection } from '../../types'; import type { CreateXcmCallOpts } from '../types'; -import { XcmPalletName } from '../util/establishXcmPallet'; +import type { XTokensBaseArgs } from './types'; /** * Build a Polkadot-js `transferMultiassets` SubmittableExtrinsic * call. * - * @param api ApiPromise - * @param direction Denotes the xcm direction of the call. - * @param destAddr The address the funds will be transfered too. - * @param assetIds An array of asset ids. Note, this should be the same size and order as amounts. - * @param amounts An array of amounts. Note, this should be the same size and order as assetIds. - * @param destChainId The id of the destination chain. This will be zero for a relay chain. - * @param xcmVersion Supported XCM version. - * @param specName The specName for the current chain - * @param registry Registry - * @param xcmPallet The pallet being used to construct xcm calls. + * @param baseArgs The base args needed to construct this call. * @param opts CreateXcmCallOpts */ export const transferMultiassets = async ( - api: ApiPromise, - direction: XcmDirection, - destAddr: string, - assetIds: string[], - amounts: string[], - destChainId: string, - xcmVersion: number, - specName: string, - registry: Registry, - xcmPallet: XcmPalletName, + baseArgs: XTokensBaseArgs, opts: CreateXcmCallOpts ): Promise> => { + const { api, direction, destAddr, assetIds, amounts, destChainId, xcmVersion, specName, registry } = baseArgs; const { isLimited, weightLimit, paysWithFeeDest, isForeignAssetsTransfer, isLiquidTokenTransfer } = opts; - const ext = api.tx[xcmPallet].transferMultiassets; + const ext = api.tx[baseArgs.xcmPallet].transferMultiassets; const typeCreator = createXcmTypes[direction]; const destWeightLimit = typeCreator.createWeightLimit({ diff --git a/src/createXcmCalls/xTokens/types.ts b/src/createXcmCalls/xTokens/types.ts new file mode 100644 index 00000000..0eb4df87 --- /dev/null +++ b/src/createXcmCalls/xTokens/types.ts @@ -0,0 +1,6 @@ +import type { XcmBaseArgs } from '../../types'; +import type { XcmPalletName } from '../util/establishXcmPallet'; + +export interface XTokensBaseArgs extends XcmBaseArgs { + xcmPallet: XcmPalletName; +} diff --git a/src/createXcmTypes/types.ts b/src/createXcmTypes/types.ts index 90a3b499..f57fc2a9 100644 --- a/src/createXcmTypes/types.ts +++ b/src/createXcmTypes/types.ts @@ -279,13 +279,6 @@ export interface CreateWeightLimitOpts { weightLimit?: { refTime?: string; proofSize?: string }; } -export interface CheckXcmTxInputsOpts { - xcmVersion: number; - paysWithFeeDest?: string; - isLimited?: boolean; - weightLimit?: { refTime?: string; proofSize?: string }; -} - export interface ICreateXcmType { createBeneficiary: (accountId: string, xcmVersion: number) => XcmDestBenificiary; createDest: (destId: string, xcmVersion: number) => XcmDestBenificiary; diff --git a/src/errors/checkXcmTxInputs.ts b/src/errors/checkXcmTxInputs.ts index 9885a0b7..7593a859 100644 --- a/src/errors/checkXcmTxInputs.ts +++ b/src/errors/checkXcmTxInputs.ts @@ -6,16 +6,17 @@ import { isEthereumAddress } from '@polkadot/util-crypto'; import { MAX_ASSETS_FOR_TRANSFER, RELAY_CHAIN_IDS } from '../consts'; import { XcmPalletName } from '../createXcmCalls/util/establishXcmPallet'; -import { CheckXcmTxInputsOpts } from '../createXcmTypes/types'; import { foreignAssetMultiLocationIsInCacheOrRegistry } from '../createXcmTypes/util/foreignAssetMultiLocationIsInCacheOrRegistry'; import { foreignAssetsMultiLocationExists } from '../createXcmTypes/util/foreignAssetsMultiLocationExists'; import { isParachainPrimaryNativeAsset } from '../createXcmTypes/util/isParachainPrimaryNativeAsset'; import { multiLocationAssetIsParachainsNativeAsset } from '../createXcmTypes/util/multiLocationAssetIsParachainsNativeAsset'; import { Registry } from '../registry'; import type { ChainInfo, ChainInfoKeys } from '../registry/types'; +import type { XcmBaseArgsWithPallet } from '../types'; import { AssetInfo, Direction } from '../types'; import { validateNumber } from '../validate'; import { BaseError, BaseErrorsEnum } from './BaseError'; +import type { CheckXcmTxInputsOpts } from './types'; /** * Ensure when sending tx's to or from the relay chain that the length of the assetIds array @@ -1041,24 +1042,12 @@ export const checkAssetIdInput = async ( * @param specName * @param registry */ -export const checkXcmTxInputs = async ( - api: ApiPromise, - destChainId: string, - assetIds: string[], - amounts: string[], - xcmDirection: Direction, - xcmPallet: XcmPalletName, - specName: string, - registry: Registry, - isForeignAssetsTransfer: boolean, - isLiquidTokenTransfer: boolean, - isParachainPrimaryNativeAsset: boolean, - opts: CheckXcmTxInputsOpts -) => { - const { xcmVersion, paysWithFeeDest } = opts; +export const checkXcmTxInputs = async (baseArgs: XcmBaseArgsWithPallet, opts: CheckXcmTxInputsOpts) => { + const { api, direction, assetIds, amounts, destChainId, xcmVersion, specName, registry, xcmPallet } = baseArgs; + const { paysWithFeeDest, isForeignAssetsTransfer, isLiquidTokenTransfer, isPrimaryParachainNativeAsset } = opts; const relayChainInfo = registry.currentRelayRegistry; - if (isParachainPrimaryNativeAsset) { + if (isPrimaryParachainNativeAsset) { /** * Checks that the assetIds length is correct for primary native parachain asset tx */ @@ -1072,12 +1061,12 @@ export const checkXcmTxInputs = async ( /** * Checks that the XcmVersion works with `PaysWithFeeDest` option */ - checkXcmVersionIsValidForPaysWithFeeDest(xcmDirection, xcmVersion, paysWithFeeDest); + checkXcmVersionIsValidForPaysWithFeeDest(direction, xcmVersion, paysWithFeeDest); /** * Checks that the direction of the `transferLiquidToken` option is correct. */ - checkLiquidTokenTransferDirectionValidity(xcmDirection, isLiquidTokenTransfer); + checkLiquidTokenTransferDirectionValidity(direction, isLiquidTokenTransfer); /** * Checks to ensure that assetId's have a length no greater than MAX_ASSETS_FOR_TRANSFER @@ -1102,55 +1091,55 @@ export const checkXcmTxInputs = async ( assetIds, relayChainInfo, specName, - xcmDirection, + direction, registry, xcmVersion, isForeignAssetsTransfer, isLiquidTokenTransfer ); - if (xcmDirection === Direction.RelayToSystem) { + if (direction === Direction.RelayToSystem) { checkRelayAssetIdLength(assetIds); checkRelayAmountsLength(amounts); } - if (xcmDirection === Direction.RelayToPara) { + if (direction === Direction.RelayToPara) { checkRelayAssetIdLength(assetIds); checkRelayAmountsLength(amounts); } - if (xcmDirection === Direction.SystemToRelay) { + if (direction === Direction.SystemToRelay) { checkRelayAssetIdLength(assetIds); checkRelayAmountsLength(amounts); } - if (xcmDirection === Direction.SystemToPara) { + if (direction === Direction.SystemToPara) { if (isForeignAssetsTransfer) { checkMultiLocationIdLength(assetIds); checkMultiLocationAmountsLength(amounts); checkAssetsAmountMatch(assetIds, amounts); checkAssetsAmountMatch(assetIds, amounts); - checkMultiLocationsContainOnlyNativeOrForeignAssetsOfDestChain(xcmDirection, destChainId, assetIds); + checkMultiLocationsContainOnlyNativeOrForeignAssetsOfDestChain(direction, destChainId, assetIds); } checkAssetsAmountMatch(assetIds, amounts); } - if (xcmDirection === Direction.SystemToSystem) { + if (direction === Direction.SystemToSystem) { if (isForeignAssetsTransfer) { checkMultiLocationIdLength(assetIds); checkMultiLocationAmountsLength(amounts); checkAssetsAmountMatch(assetIds, amounts); - checkMultiLocationsContainOnlyNativeOrForeignAssetsOfDestChain(xcmDirection, destChainId, assetIds); + checkMultiLocationsContainOnlyNativeOrForeignAssetsOfDestChain(direction, destChainId, assetIds); } checkIfNativeRelayChainAssetPresentInMultiAssetIdList(assetIds, registry); } - if (xcmDirection === Direction.ParaToSystem || xcmDirection === Direction.ParaToPara) { - CheckXTokensPalletOriginIsNonForeignAssetTx(xcmDirection, xcmPallet, isForeignAssetsTransfer); - checkAssetsAmountMatch(assetIds, amounts, isParachainPrimaryNativeAsset); + if (direction === Direction.ParaToSystem || direction === Direction.ParaToPara) { + CheckXTokensPalletOriginIsNonForeignAssetTx(direction, xcmPallet, isForeignAssetsTransfer); + checkAssetsAmountMatch(assetIds, amounts, isPrimaryParachainNativeAsset); } - if (xcmDirection === Direction.ParaToRelay) { + if (direction === Direction.ParaToRelay) { checkRelayAssetIdLength(assetIds); checkRelayAmountsLength(amounts); } diff --git a/src/errors/types.ts b/src/errors/types.ts new file mode 100644 index 00000000..10d3dadc --- /dev/null +++ b/src/errors/types.ts @@ -0,0 +1,10 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. + +export interface CheckXcmTxInputsOpts { + isForeignAssetsTransfer: boolean; + isLiquidTokenTransfer: boolean; + isPrimaryParachainNativeAsset: boolean; + paysWithFeeDest?: string; + isLimited?: boolean; + weightLimit?: { refTime?: string; proofSize?: string }; +} diff --git a/src/types.ts b/src/types.ts index c49bb586..e7e282b5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,6 +6,8 @@ import type { InteriorMultiLocation } from '@polkadot/types/interfaces'; import type { ISubmittableResult } from '@polkadot/types/types'; import BN from 'bn.js'; +import { XcmPalletName } from './createXcmCalls/util/establishXcmPallet'; +import type { Registry } from './registry'; import type { ChainInfoRegistry } from './registry/types'; export type RequireOnlyOne = Pick> & @@ -301,6 +303,22 @@ export interface UnsignedTransaction extends SignerPayloadJSON { assetId: BN; } +export interface XcmBaseArgs { + api: ApiPromise; + direction: XcmDirection; + destAddr: string; + assetIds: string[]; + amounts: string[]; + destChainId: string; + xcmVersion: number; + specName: string; + registry: Registry; +} + +export interface XcmBaseArgsWithPallet extends XcmBaseArgs { + xcmPallet: XcmPalletName; +} + export interface LocalDest { Id: string; }