Skip to content

Commit

Permalink
feat: add paysWithFeeOrigin support for MultiLocations (#333)
Browse files Browse the repository at this point in the history
Co-authored-by: bee344 <[email protected]>
  • Loading branch information
TarikGul and bee344 authored Nov 29, 2023
1 parent 0404b7b commit 401a45c
Show file tree
Hide file tree
Showing 14 changed files with 404 additions and 538 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"typescript": "4.9.4"
},
"dependencies": {
"@polkadot/api": "^10.9.1",
"@polkadot/api": "^10.11.1",
"@substrate/asset-transfer-api-registry": "^0.2.11"
}
}
28 changes: 5 additions & 23 deletions src/AssetTransferApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe('AssetTransferAPI', () => {
direction: 'SystemToPara',
format: 'payload',
method: 'limitedReserveTransferAssets',
tx: '0xf81f0801010100411f0100010100c224aad9c6f3bbd784120e9fceee5bfd22a62c69144ee673f76d6a34d280de160104000002043205040091010000000000450228000100000000cc240000040000000000000000000000000000000000000000000000000000000000000000000000be2554aa8a0151eb4d706308c47d16996af391e4c5e499c7cbef24259b7d4503',
tx: '0xf81f0801010100411f0100010100c224aad9c6f3bbd784120e9fceee5bfd22a62c69144ee673f76d6a34d280de16010400000204320504009101000000000045022800010000cc240000040000000000000000000000000000000000000000000000000000000000000000000000be2554aa8a0151eb4d706308c47d16996af391e4c5e499c7cbef24259b7d4503',
xcmVersion: 2,
});
});
Expand Down Expand Up @@ -713,14 +713,15 @@ describe('AssetTransferAPI', () => {
});
describe('paysWithFeeOrigin', () => {
it('Should correctly assign the assedId field to an unsigned transaction when a valid sufficient paysWithFeeOrigin option is provided', async () => {
const expected = '1,984';
const expected = { parents: '0', interior: { X2: [{ PalletInstance: '50' }, { GeneralIndex: '1,984' }] } };
const payload = await systemAssetsApi.createTransferTransaction(
'2023',
'0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b',
['1984', 'usdc'],
['5000000', '4000000000'],
{
paysWithFeeOrigin: '1984',
paysWithFeeOrigin:
'{"parents": "0", "interior": { "X2": [{"PalletInstance": "50"},{"GeneralIndex": "1984"}]}}',
format: 'payload',
keepAlive: true,
paysWithFeeDest: 'USDC',
Expand All @@ -734,26 +735,7 @@ describe('AssetTransferAPI', () => {
});
const unsigned = result.toHuman() as unknown as UnsignedTransaction;

expect(unsigned.assetId).toEqual(expected);
});

it('Should error during payload construction when a paysWithFeeOrigin is provided that is not a number', async () => {
await expect(async () => {
await systemAssetsApi.createTransferTransaction(
'2023',
'0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b',
['1984', 'usdc'],
['5000000', '4000000000'],
{
paysWithFeeOrigin: 'hello there',
format: 'payload',
keepAlive: true,
paysWithFeeDest: 'USDC',
xcmVersion: 3,
sendersAddr: 'FBeL7DanUDs5SZrxZY1CizMaPgG9vZgJgvr52C2dg81SsF1',
}
);
}).rejects.toThrowError('paysWithFeeOrigin value must be a valid number. Received: hello there');
expect(unsigned.assetId).toStrictEqual(expected);
});

it('Should error during payload construction when a paysWithFeeOrigin is provided that matches a non sufficient asset', async () => {
Expand Down
38 changes: 22 additions & 16 deletions src/AssetTransferApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { ApiPromise } from '@polkadot/api';
import type { SubmittableExtrinsic } from '@polkadot/api/submittable/types';
import { EXTRINSIC_VERSION } from '@polkadot/types/extrinsic/v4/Extrinsic';
import type { RuntimeDispatchInfo, RuntimeDispatchInfoV1 } from '@polkadot/types/interfaces';
import type { ISubmittableResult } from '@polkadot/types/types';
import type { AnyJson, ISubmittableResult } from '@polkadot/types/types';
import BN from 'bn.js';

import { CDN_URL, RELAY_CHAIN_IDS, RELAY_CHAIN_NAMES, SYSTEM_PARACHAINS_NAMES } from './consts';
Expand Down Expand Up @@ -736,7 +736,7 @@ export class AssetTransferApi {
opts: { paysWithFeeOrigin?: string; sendersAddr: string }
): Promise<`0x${string}`> => {
const { paysWithFeeOrigin, sendersAddr } = opts;
let assetId = new BN(0);
let assetId: BN | AnyJson = new BN(0);

// if a paysWithFeeOrigin is provided and the chain is of system origin
// we assign the assetId to the value of paysWithFeeOrigin
Expand All @@ -745,21 +745,27 @@ export class AssetTransferApi {
if (paysWithFeeOrigin && isOriginSystemParachain) {
const isValidInt = validateNumber(paysWithFeeOrigin);

if (!isValidInt) {
throw new BaseError(
`paysWithFeeOrigin value must be a valid number. Received: ${paysWithFeeOrigin}`,
BaseErrorsEnum.InvalidInput
);
}

assetId = new BN(paysWithFeeOrigin);
const isSufficient = await this.checkAssetIsSufficient(assetId);
if (isValidInt) {
assetId = new BN(paysWithFeeOrigin);
const isSufficient = await this.checkAssetIsSufficient(assetId);

if (!isSufficient) {
throw new BaseError(
`asset with assetId ${assetId.toString()} is not a sufficient asset to pay for fees`,
BaseErrorsEnum.InvalidAsset
);
if (!isSufficient) {
throw new BaseError(
`asset with assetId ${assetId.toString()} is not a sufficient asset to pay for fees`,
BaseErrorsEnum.InvalidAsset
);
}
} else {
try {
assetId = JSON.parse(paysWithFeeOrigin) as AnyJson;
} catch (e) {
throw new BaseError(
`paysWithFeeOrigin is an invalid asset. The asset must be a valid integer or multiLocation depending on the runtime: ${
e as string
}`,
BaseErrorsEnum.InvalidAsset
);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/config/disabledOpts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export const disabledOpts: DisabledOptions = {
error: (opt: string, chain: string) => callError(opt, chain),
},
paysWithFeeOrigin: {
disabled: true,
chains: ['westmint'],
disabled: false,
chains: [],
error: (opt: string, chain: string) => callError(opt, chain),
},
paysWithFeeDest: {
Expand Down
2 changes: 1 addition & 1 deletion src/createCalls/balances/transfer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import { transfer } from './transfer';
describe('transfer', () => {
it('Should construct a valid transfer extrinsic', () => {
const res = transfer(mockSystemApi, '0xf5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b', '10000');
expect(res.toHex()).toEqual('0x98040a0700f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b419c');
expect(res.toHex()).toEqual('0x98040a0000f5d5714c084c112843aca74f8c498da06cc5a2d63153b825189baa51043b1f0b419c');
});
});
6 changes: 5 additions & 1 deletion src/createCalls/balances/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ export const transfer = (
destAddr: string,
amount: string
): SubmittableExtrinsic<'promise', ISubmittableResult> => {
return api.tx.balances.transfer(destAddr, amount);
if (api.tx.balances.transferAllowDeath) {
return api.tx.balances.transferAllowDeath(destAddr, amount);
} else {
return api.tx.balances.transfer(destAddr, amount);
}
};
10 changes: 0 additions & 10 deletions src/errors/disableOpts.spec.ts

This file was deleted.

Loading

0 comments on commit 401a45c

Please sign in to comment.