From eef67bab64cab879cc110dc0191322a11897cfb9 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 3 Sep 2024 03:56:38 -0400 Subject: [PATCH 1/6] Keep assetID hex as Option for toPayload --- packages/api/src/submittable/createClass.ts | 2 +- .../types/src/extrinsic/SignerPayload.spec.ts | 21 ++++++++++++------- packages/types/src/extrinsic/SignerPayload.ts | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/api/src/submittable/createClass.ts b/packages/api/src/submittable/createClass.ts index a6d05f84598..1c8b1088ad4 100644 --- a/packages/api/src/submittable/createClass.ts +++ b/packages/api/src/submittable/createClass.ts @@ -348,7 +348,7 @@ export function createClass ({ api, apiType, blockHas const ext = this.registry.createTypeUnsafe('Extrinsic', [result.signedTransaction]); const newSignerPayload = this.registry.createTypeUnsafe('SignerPayload', [objectSpread({}, { address, - assetId: ext.assetId && ext.assetId.isSome ? ext.assetId.unwrap().toHex() : null, + assetId: ext.assetId && ext.assetId.isSome ? ext.assetId.toHex() : null, blockHash: payload.blockHash, blockNumber: header ? header.number : 0, era: ext.era.toHex(), diff --git a/packages/types/src/extrinsic/SignerPayload.spec.ts b/packages/types/src/extrinsic/SignerPayload.spec.ts index 17ad0d63f25..962e3aa91e8 100644 --- a/packages/types/src/extrinsic/SignerPayload.spec.ts +++ b/packages/types/src/extrinsic/SignerPayload.spec.ts @@ -35,6 +35,11 @@ describe('SignerPayload', (): void => { withSignedTransaction: false }; + const TEST_WITH_ASSETID_HEX = { + ...TEST, + assetId: '0x010002043205ed01' + }; + it('creates a valid JSON output', (): void => { expect( new SignerPayload(registry, { @@ -57,7 +62,7 @@ describe('SignerPayload', (): void => { ).toEqual({ address: '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE', // eslint-disable-next-line sort-keys - assetId: '0x0002043205ed01', + assetId: '0x010002043205ed01', blockHash: '0xde8f69eeb5e065e18c6950ff708d7e551f68dc9bf59a07c52367c0280f805ec7', blockNumber: '0x00231d30', era: '0x0703', @@ -88,12 +93,12 @@ describe('SignerPayload', (): void => { expect( test.toPayload().assetId // eslint-disable-next-line sort-keys - ).toEqual('0x0002043205ed01'); + ).toEqual('0x010002043205ed01'); expect( new SignerPayload(registry, { assetId: 0 }).toPayload().assetId // eslint-disable-next-line sort-keys - ).toEqual('0x0000'); + ).toEqual('0x010000'); }); it('re-constructs from JSON', (): void => { @@ -102,7 +107,7 @@ describe('SignerPayload', (): void => { ...TEST, runtimeVersion: { specVersion: 0x06, transactionVersion: 0x07 } }).toPayload() - ).toEqual(TEST); + ).toEqual(TEST_WITH_ASSETID_HEX); }); it('re-constructs from itself', (): void => { @@ -114,7 +119,7 @@ describe('SignerPayload', (): void => { runtimeVersion: { specVersion: 0x06, transactionVersion: 0x07 } }) ).toPayload() - ).toEqual(TEST); + ).toEqual(TEST_WITH_ASSETID_HEX); }); it('can be used as a feed to ExtrinsicPayload', (): void => { @@ -130,11 +135,11 @@ describe('SignerPayload', (): void => { expect(payload.blockHash.toHex()).toEqual(TEST.blockHash); expect(payload.nonce.eq(TEST.nonce)).toBe(true); expect(payload.tip.eq(TEST.tip)).toBe(true); - expect(payload.assetId.isSome && payload.assetId - ?.eq(registry.createType('MultiLocation', { + expect(payload.assetId && payload.assetId.toJSON()) + .toEqual(registry.createType('MultiLocation', { // eslint-disable-next-line sort-keys parents: 0, interior: { X2: [{ palletInstance: 50 }, { generalIndex: 123 }] } - }))).toBe(true); + }).toHex()); }); const TEST_WITHOUT_CHECK = { diff --git a/packages/types/src/extrinsic/SignerPayload.ts b/packages/types/src/extrinsic/SignerPayload.ts index 6071bac41e7..b0ccee89207 100644 --- a/packages/types/src/extrinsic/SignerPayload.ts +++ b/packages/types/src/extrinsic/SignerPayload.ts @@ -159,7 +159,7 @@ export class GenericSignerPayload extends Struct implements ISignerPayload, Sign // the known defaults as managed explicitly and has different // formatting in cases, e.g. we mostly expose a hex format here address: this.address.toString(), - assetId: this.assetId && this.assetId.isSome ? this.assetId.unwrap().toHex() : null, + assetId: this.assetId && this.assetId.isSome ? this.assetId.toHex() : null, blockHash: this.blockHash.toHex(), blockNumber: this.blockNumber.toHex(), era: this.era.toHex(), From 0f0b3849f640eb871a57450b86cac2827b5b61d0 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 3 Sep 2024 15:44:35 -0400 Subject: [PATCH 2/6] Resolve last issues with hex and u8a conversion for assetId --- packages/types/src/extrinsic/ExtrinsicPayload.ts | 11 ++++++++++- packages/types/src/extrinsic/SignerPayload.spec.ts | 11 +++++------ .../types/src/extrinsic/signedExtensions/statemint.ts | 2 +- packages/types/src/types/extrinsic.ts | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/types/src/extrinsic/ExtrinsicPayload.ts b/packages/types/src/extrinsic/ExtrinsicPayload.ts index d23252cfbc9..e7a7a6b4d41 100644 --- a/packages/types/src/extrinsic/ExtrinsicPayload.ts +++ b/packages/types/src/extrinsic/ExtrinsicPayload.ts @@ -11,7 +11,7 @@ import type { ExtrinsicPayloadValue, ICompact, IKeyringPair, INumber, IOption } import type { GenericExtrinsicEra } from './ExtrinsicEra.js'; import { AbstractBase } from '@polkadot/types-codec'; -import { u8aToHex } from '@polkadot/util'; +import { hexToU8a, isHex, u8aToHex } from '@polkadot/util'; import { DEFAULT_VERSION } from './constants.js'; @@ -36,6 +36,15 @@ function decodeExtrinsicPayload (registry: Registry, value?: GenericExtrinsicPay return value.unwrap(); } + if (value && (value as ExtrinsicPayloadValue).assetId && isHex((value as ExtrinsicPayloadValue).assetId)) { + const adjustedPayload = { + ...(value as ExtrinsicPayloadValue), + assetId: registry.createType('TAssetConversion', hexToU8a((value as ExtrinsicPayloadValue).assetId)).toJSON() + }; + + return registry.createTypeUnsafe(VERSIONS[version] || VERSIONS[0], [adjustedPayload, { version }]); + } + return registry.createTypeUnsafe(VERSIONS[version] || VERSIONS[0], [value, { version }]); } diff --git a/packages/types/src/extrinsic/SignerPayload.spec.ts b/packages/types/src/extrinsic/SignerPayload.spec.ts index 962e3aa91e8..2bcf90fc227 100644 --- a/packages/types/src/extrinsic/SignerPayload.spec.ts +++ b/packages/types/src/extrinsic/SignerPayload.spec.ts @@ -4,6 +4,7 @@ /// import rpcMetadata from '@polkadot/types-support/metadata/static-substrate'; +import { u8aToHex } from '@polkadot/util'; import { TypeRegistry } from '../create/index.js'; import { Metadata } from '../metadata/index.js'; @@ -124,9 +125,7 @@ describe('SignerPayload', (): void => { it('can be used as a feed to ExtrinsicPayload', (): void => { const signer = new SignerPayload(registry, { - ...TEST, - // eslint-disable-next-line sort-keys - assetId: { parents: 0, interior: { x2: [{ palletInstance: 50 }, { generalIndex: 123 }] } } + ...TEST }).toPayload(); const payload = registry.createType('ExtrinsicPayload', signer, { version: signer.version }); @@ -135,11 +134,11 @@ describe('SignerPayload', (): void => { expect(payload.blockHash.toHex()).toEqual(TEST.blockHash); expect(payload.nonce.eq(TEST.nonce)).toBe(true); expect(payload.tip.eq(TEST.tip)).toBe(true); - expect(payload.assetId && payload.assetId.toJSON()) - .toEqual(registry.createType('MultiLocation', { + expect(payload.assetId?.toHex()) + .toEqual(u8aToHex(registry.createType('Option', { // eslint-disable-next-line sort-keys parents: 0, interior: { X2: [{ palletInstance: 50 }, { generalIndex: 123 }] } - }).toHex()); + }).toU8a())); }); const TEST_WITHOUT_CHECK = { diff --git a/packages/types/src/extrinsic/signedExtensions/statemint.ts b/packages/types/src/extrinsic/signedExtensions/statemint.ts index b567bcbe5e0..a9bd8fb780c 100644 --- a/packages/types/src/extrinsic/signedExtensions/statemint.ts +++ b/packages/types/src/extrinsic/signedExtensions/statemint.ts @@ -8,7 +8,7 @@ export const statemint: ExtDef = { extrinsic: { tip: 'Compact', // eslint-disable-next-line sort-keys - assetId: 'TAssetConversion' + assetId: 'Option' }, payload: {} } diff --git a/packages/types/src/types/extrinsic.ts b/packages/types/src/types/extrinsic.ts index 6fea5886999..6a0fe33cdd4 100644 --- a/packages/types/src/types/extrinsic.ts +++ b/packages/types/src/types/extrinsic.ts @@ -220,7 +220,7 @@ export interface ExtrinsicPayloadValue { specVersion: AnyNumber; tip: AnyNumber; transactionVersion: AnyNumber; - assetId?: AnyNumber | object; + assetId?: HexString; mode?: AnyNumber; metadataHash?: AnyU8a; } From 14b795aa53ceff2c31d6d16c81415d98118cf841 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 3 Sep 2024 16:27:14 -0400 Subject: [PATCH 3/6] Inline comment --- packages/types/src/extrinsic/ExtrinsicPayload.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/types/src/extrinsic/ExtrinsicPayload.ts b/packages/types/src/extrinsic/ExtrinsicPayload.ts index e7a7a6b4d41..c5b38fbe25e 100644 --- a/packages/types/src/extrinsic/ExtrinsicPayload.ts +++ b/packages/types/src/extrinsic/ExtrinsicPayload.ts @@ -36,6 +36,15 @@ function decodeExtrinsicPayload (registry: Registry, value?: GenericExtrinsicPay return value.unwrap(); } + /** + * HACK: In order to change the assetId from `number | object` to HexString (While maintaining the true type ie Option), + * to allow for easier generalization of the SignerPayloadJSON interface the below check is necessary. The ExtrinsicPayloadV4 class does not like + * a value passed in as an Option, and can't decode it properly. Therefore, we ensure to convert the following below, and then pass the option as a unwrapped + * JSON value. + * + * ref: https://github.com/polkadot-js/api/pull/5968 + * ref: https://github.com/polkadot-js/api/pull/5967 + */ if (value && (value as ExtrinsicPayloadValue).assetId && isHex((value as ExtrinsicPayloadValue).assetId)) { const adjustedPayload = { ...(value as ExtrinsicPayloadValue), From 324e8225f2c2f6afbc9a502037ff610999fb4219 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 3 Sep 2024 18:33:49 -0400 Subject: [PATCH 4/6] Fix types --- packages/types/src/extrinsic/signedExtensions/statemint.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/extrinsic/signedExtensions/statemint.ts b/packages/types/src/extrinsic/signedExtensions/statemint.ts index a9bd8fb780c..b567bcbe5e0 100644 --- a/packages/types/src/extrinsic/signedExtensions/statemint.ts +++ b/packages/types/src/extrinsic/signedExtensions/statemint.ts @@ -8,7 +8,7 @@ export const statemint: ExtDef = { extrinsic: { tip: 'Compact', // eslint-disable-next-line sort-keys - assetId: 'Option' + assetId: 'TAssetConversion' }, payload: {} } From e09aa64525f4ce9ec35c7bbd32efe23f75d79842 Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 3 Sep 2024 20:16:52 -0400 Subject: [PATCH 5/6] Fix test --- packages/types/src/extrinsic/SignerPayload.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/extrinsic/SignerPayload.spec.ts b/packages/types/src/extrinsic/SignerPayload.spec.ts index 2bcf90fc227..12964ee8fdf 100644 --- a/packages/types/src/extrinsic/SignerPayload.spec.ts +++ b/packages/types/src/extrinsic/SignerPayload.spec.ts @@ -135,7 +135,7 @@ describe('SignerPayload', (): void => { expect(payload.nonce.eq(TEST.nonce)).toBe(true); expect(payload.tip.eq(TEST.tip)).toBe(true); expect(payload.assetId?.toHex()) - .toEqual(u8aToHex(registry.createType('Option', { + .toEqual(u8aToHex(registry.createType('MultiLocation', { // eslint-disable-next-line sort-keys parents: 0, interior: { X2: [{ palletInstance: 50 }, { generalIndex: 123 }] } }).toU8a())); From 26203217487c07dd645b54750ff4329cc41986ed Mon Sep 17 00:00:00 2001 From: tarikgul Date: Tue, 3 Sep 2024 20:19:55 -0400 Subject: [PATCH 6/6] adjust merit of test --- packages/types/src/extrinsic/SignerPayload.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/types/src/extrinsic/SignerPayload.spec.ts b/packages/types/src/extrinsic/SignerPayload.spec.ts index 12964ee8fdf..2920c6438d6 100644 --- a/packages/types/src/extrinsic/SignerPayload.spec.ts +++ b/packages/types/src/extrinsic/SignerPayload.spec.ts @@ -134,8 +134,8 @@ describe('SignerPayload', (): void => { expect(payload.blockHash.toHex()).toEqual(TEST.blockHash); expect(payload.nonce.eq(TEST.nonce)).toBe(true); expect(payload.tip.eq(TEST.tip)).toBe(true); - expect(payload.assetId?.toHex()) - .toEqual(u8aToHex(registry.createType('MultiLocation', { + expect(u8aToHex(payload.assetId?.toU8a())) + .toEqual(u8aToHex(registry.createType('Option', { // eslint-disable-next-line sort-keys parents: 0, interior: { X2: [{ palletInstance: 50 }, { generalIndex: 123 }] } }).toU8a()));