diff --git a/sonar-project.properties b/sonar-project.properties index e1b36ad21a..3833c9bcac 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ sonar.organization=polymeshassociation sonar.projectKey=PolymeshAssociation_polymesh-sdk sonar.sources=src -sonar.coverage.exclusions=**/testUtils/**,**/polkadot/**,**/__tests__/**,**/generated/**,src/utils/typeguards.ts,src/types/internal.ts,src/middleware/* +sonar.coverage.exclusions=**/testUtils/**,**/polkadot/**,**/__tests__/**,**/generated/**,src/utils/typeguards.ts,src/types/internal.ts,src/middleware/** sonar.cpd.exclusions=**/__tests__/**,**/polkadot/** sonar.exclusions=**/polkadot/augment-** sonar.javascript.environments=node diff --git a/src/api/entities/Instruction/__tests__/index.ts b/src/api/entities/Instruction/__tests__/index.ts index 543309a4b5..4a194d22c0 100644 --- a/src/api/entities/Instruction/__tests__/index.ts +++ b/src/api/entities/Instruction/__tests__/index.ts @@ -7,20 +7,8 @@ import BigNumber from 'bignumber.js'; import { when } from 'jest-when'; import { Context, Entity, Instruction, PolymeshTransaction } from '~/internal'; -import { - instructionAffirmationsQuery, - instructionEventsQuery, - instructionsQuery, - legsQuery, - offChainAffirmationsQuery, -} from '~/middleware/queries/settlements'; -import { - AffirmStatusEnum, - InstructionEventEnum, - InstructionStatusEnum, - InstructionTypeEnum, - LegTypeEnum, -} from '~/middleware/types'; +import { instructionEventsQuery } from '~/middleware/queries/settlements'; +import { InstructionEventEnum } from '~/middleware/types'; import { dsMockUtils, entityMockUtils, procedureMockUtils } from '~/testUtils/mocks'; import { createMockAssetId, @@ -359,176 +347,6 @@ describe('Instruction class', () => { queryMultiMock = dsMockUtils.getQueryMultiMock(); }); - it('should throw an error if an Instruction does not exists', () => { - dsMockUtils.createQueryMock('settlement', 'instructionCounter', { - returnValue: dsMockUtils.createMockU64(new BigNumber(0)), - }); - return expect(instruction.details()).rejects.toThrow('Instruction does not exists'); - }); - - describe('querying from middleware', () => { - it('should return the Instruction details from middleware', async () => { - const status = InstructionStatus.Pending; - const createdAt = new Date('10/14/1987'); - const valueDate = new Date('11/17/1987'); - const tradeDate = new Date('11/17/1987'); - const venueId = new BigNumber(1); - const type = InstructionType.SettleOnAffirmation; - const owner = 'someDid'; - const blockNumber = new BigNumber(100); - const memo = 'someMemo'; - - entityMockUtils.configureMocks({ identityOptions: { did: owner } }); - - const middlewareInstruction = { - id: new BigNumber(1), - type: InstructionTypeEnum.SettleOnAffirmation, - status: InstructionStatusEnum.Created, - venueId, - createdBlock: { - datetime: createdAt, - }, - tradeDate, - valueDate, - memo, - }; - dsMockUtils.createApolloQueryMock( - instructionsQuery(false, { - id: id.toString(), - }), - { - instructions: { - nodes: [middlewareInstruction], - }, - } - ); - - const expectedDetails = { - status, - createdAt, - tradeDate, - valueDate, - type, - memo, - venue: expect.objectContaining({ - id: venueId, - }), - }; - let result = await instruction.details(); - - expect(result).toEqual(expect.objectContaining(expectedDetails)); - - dsMockUtils.createApolloQueryMock( - instructionsQuery(false, { - id: id.toString(), - }), - { - instructions: { - nodes: [ - { - ...middlewareInstruction, - type: InstructionTypeEnum.SettleOnBlock, - endBlock: blockNumber.toNumber(), - }, - ], - }, - } - ); - result = await instruction.details(); - - expect(result).toEqual( - expect.objectContaining({ - ...expectedDetails, - type: InstructionType.SettleOnBlock, - endBlock: blockNumber, - }) - ); - - dsMockUtils.createApolloQueryMock( - instructionsQuery(false, { - id: id.toString(), - }), - { - instructions: { - nodes: [ - { - ...middlewareInstruction, - type: InstructionTypeEnum.SettleManual, - endAfterBlock: blockNumber.toNumber(), - }, - ], - }, - } - ); - - result = await instruction.details(); - - expect(result).toEqual( - expect.objectContaining({ - ...expectedDetails, - type: InstructionType.SettleManual, - endAfterBlock: blockNumber, - }) - ); - - dsMockUtils.createApolloQueryMock( - instructionsQuery(false, { - id: id.toString(), - }), - { - instructions: { - nodes: [ - { - ...middlewareInstruction, - status: InstructionStatusEnum.Failed, - }, - ], - }, - } - ); - - result = await instruction.details(); - - expect(result).toEqual( - expect.objectContaining({ - ...expectedDetails, - status: InstructionStatus.Failed, - }) - ); - - dsMockUtils.createApolloQueryMock( - instructionsQuery(false, { - id: id.toString(), - }), - { - instructions: { - nodes: [ - { - ...middlewareInstruction, - venueId: undefined, - memo: undefined, - }, - ], - }, - } - ); - result = await instruction.details(); - - expect(result.venue).toBeNull(); - expect(result.memo).toBeNull(); - }); - - it('should throw an error if an Instruction is not yet processed by middleware', () => { - dsMockUtils.createApolloQueryMock(instructionsQuery(false, { id: id.toString() }), { - instructions: { nodes: [] }, - }); - - return expect(instruction.details()).rejects.toThrow( - 'Instruction is not yet processed by the middleware' - ); - }); - }); - describe('querying from chain', () => { beforeEach(() => { dsMockUtils.configureMocks({ @@ -783,12 +601,6 @@ describe('Instruction class', () => { dsMockUtils.createQueryMock('settlement', 'affirmsReceived'); }); - it('should throw an error if the start value is passed as a number when querying from chain', () => { - return expect( - instruction.getAffirmations({ start: new BigNumber(2), size: new BigNumber(1) }) - ).rejects.toThrow('`start` should be of type string to query the data from chain'); - }); - it('should throw an error if the instruction is not pending when querying from chain', () => { instructionStatusesMock.mockResolvedValue(dsMockUtils.createMockInstructionStatus('Success')); @@ -804,160 +616,9 @@ describe('Instruction class', () => { expect(data[0].identity.did).toEqual(did); expect(data[0].status).toEqual(status); }); - - describe('querying from middleware', () => { - beforeEach(() => { - dsMockUtils.configureMocks({ contextOptions: { middlewareAvailable: true } }); - }); - it('should throw an error if the start value is passed as a string', () => { - return expect( - instruction.getAffirmations({ start: 'IncorrectValue', size: new BigNumber(1) }) - ).rejects.toThrow('`start` should be of type BigNumber to query the data from middleware'); - }); - - it('should return a list of Affirmation Statuses', async () => { - const start = new BigNumber(0); - const size = new BigNumber(1); - dsMockUtils.createApolloQueryMock( - instructionAffirmationsQuery({ instructionId: id.toString() }, size, start), - { - instructionAffirmations: { - nodes: [ - { - identity: did, - status: AffirmStatusEnum.Affirmed, - }, - ], - totalCount: new BigNumber(1), - }, - } - ); - let { data, next, count } = await instruction.getAffirmations({ - start, - size, - }); - - expect(data).toHaveLength(1); - expect(data[0].identity.did).toEqual(did); - expect(data[0].status).toEqual(status); - - expect(next).toBeNull(); - expect(count).toEqual(new BigNumber(1)); - - dsMockUtils.createApolloQueryMock( - instructionAffirmationsQuery({ instructionId: id.toString() }), - { - instructionAffirmations: { - nodes: [], - totalCount: new BigNumber(0), - }, - } - ); - - ({ data, next, count } = await instruction.getAffirmations()); - - expect(data).toEqual([]); - expect(next).toBeNull(); - expect(count).toEqual(new BigNumber(0)); - }); - }); }); describe('method: getLegs', () => { - describe('querying from middleware', () => { - it('should throw an error if the start value is passed as a string', () => { - return expect( - instruction.getLegs({ start: 'IncorrectValue', size: new BigNumber(1) }) - ).rejects.toThrow('`start` should be of type BigNumber to query the data from middleware'); - }); - - it("should return the instruction's legs", async () => { - const fromDid = 'fromDid'; - const toDid = 'toDid'; - const assetId = '0x11111111111181111111111111111111'; - const assetId2 = '0x22222222222222222222222222222222'; - const amount = new BigNumber(1000); - - entityMockUtils.configureMocks({ fungibleAssetOptions: { assetId } }); - - const mockLeg1 = { - legType: LegTypeEnum.Fungible, - from: fromDid, - fromPortfolio: new BigNumber(0), - to: toDid, - toPortfolio: new BigNumber(0), - assetId, - amount: amount.shiftedBy(6), - legIndex: new BigNumber(0), - }; - - const mockLeg2 = { - legType: LegTypeEnum.Fungible, - from: fromDid, - fromPortfolio: new BigNumber(0), - to: toDid, - toPortfolio: new BigNumber(0), - assetId: assetId2, - amount: amount.shiftedBy(6), - legIndex: new BigNumber(1), - }; - - dsMockUtils.createApolloQueryMock( - legsQuery({ - instructionId: id.toString(), - }), - { - legs: { - nodes: [mockLeg1, mockLeg2], - totalCount: new BigNumber(2), - }, - } - ); - - let { data, count, next } = await instruction.getLegs(); - - expect(count).toEqual(new BigNumber(2)); - expect(next).toBeNull(); - - const resultLeg1 = data[0] as FungibleLeg; - expect(resultLeg1.amount).toEqual(amount); - expect(resultLeg1.asset.id).toBe(hexToUuid(assetId)); - expect(resultLeg1.from.owner.did).toBe(fromDid); - expect(resultLeg1.to.owner.did).toBe(toDid); - - const resultLeg2 = data[1] as FungibleLeg; - expect(resultLeg2.amount).toEqual(amount); - expect(resultLeg2.asset.id).toBe(hexToUuid(assetId2)); - expect(resultLeg2.from.owner.did).toBe(fromDid); - expect(resultLeg2.to.owner.did).toBe(toDid); - - dsMockUtils.createApolloQueryMock( - legsQuery( - { - instructionId: id.toString(), - }, - new BigNumber(2), - new BigNumber(2) - ), - { - legs: { - nodes: [], - totalCount: new BigNumber(2), - }, - } - ); - - ({ data, next, count } = await instruction.getLegs({ - size: new BigNumber(2), - start: new BigNumber(2), - })); - - expect(data).toEqual([]); - expect(next).toBeNull(); - expect(count).toEqual(new BigNumber(2)); - }); - }); - describe('querying from chain', () => { let instructionStatusMock: jest.Mock; @@ -1459,25 +1120,6 @@ describe('Instruction class', () => { query: instructionEventsQuery( false, { -<<<<<<< HEAD -======= - event: InstructionEventEnum.FailedToExecuteInstruction, - instructionId: id.toString(), - }, - new BigNumber(1), - new BigNumber(0) - ), - returnData: { - instructionEvents: { - nodes: [], - }, - }, - }, - { - query: instructionEventsQuery( - false, - { ->>>>>>> 5ce3a3809 (feat: 🎸 add support for padded IDs in subquery) event: InstructionEventEnum.InstructionRejected, instructionId: id.toString(), }, @@ -1564,25 +1206,6 @@ describe('Instruction class', () => { query: instructionEventsQuery( false, { -<<<<<<< HEAD -======= - event: InstructionEventEnum.FailedToExecuteInstruction, - instructionId: id.toString(), - }, - new BigNumber(1), - new BigNumber(0) - ), - returnData: { - instructionEvents: { - nodes: [], - }, - }, - }, - { - query: instructionEventsQuery( - false, - { ->>>>>>> 5ce3a3809 (feat: 🎸 add support for padded IDs in subquery) event: InstructionEventEnum.InstructionRejected, instructionId: id.toString(), }, @@ -1597,84 +1220,7 @@ describe('Instruction class', () => { }, ]); -<<<<<<< HEAD const result = await instruction.getStatus(); -======= - let result = await instruction.getStatus(); - expect(result).toMatchObject({ - status: InstructionStatus.Failed, - eventIdentifier: fakeEventIdentifierResult, - }); - - dsMockUtils.createApolloMultipleQueriesMock([ - { - query: instructionEventsQuery( - false, - { - event: InstructionEventEnum.InstructionExecuted, - instructionId: id.toString(), - }, - new BigNumber(1), - new BigNumber(0) - ), - returnData: { - instructionEvents: { - nodes: [], - }, - }, - }, - { - query: instructionEventsQuery( - false, - { - event: InstructionEventEnum.InstructionFailed, - instructionId: id.toString(), - }, - new BigNumber(1), - new BigNumber(0) - ), - returnData: { - instructionEvents: { - nodes: [], - }, - }, - }, - { - query: instructionEventsQuery( - false, - { - event: InstructionEventEnum.FailedToExecuteInstruction, - instructionId: id.toString(), - }, - new BigNumber(1), - new BigNumber(0) - ), - returnData: { - instructionEvents: { - nodes: [fakeQueryResult], - }, - }, - }, - { - query: instructionEventsQuery( - false, - { - event: InstructionEventEnum.InstructionRejected, - instructionId: id.toString(), - }, - new BigNumber(1), - new BigNumber(0) - ), - returnData: { - instructionEvents: { - nodes: [], - }, - }, - }, - ]); - - result = await instruction.getStatus(); ->>>>>>> 5ce3a3809 (feat: 🎸 add support for padded IDs in subquery) expect(result).toMatchObject({ status: InstructionStatus.Failed, eventIdentifier: fakeEventIdentifierResult, @@ -1746,25 +1292,6 @@ describe('Instruction class', () => { query: instructionEventsQuery( false, { -<<<<<<< HEAD -======= - event: InstructionEventEnum.FailedToExecuteInstruction, - instructionId: id.toString(), - }, - new BigNumber(1), - new BigNumber(0) - ), - returnData: { - instructionEvents: { - nodes: [], - }, - }, - }, - { - query: instructionEventsQuery( - false, - { ->>>>>>> 5ce3a3809 (feat: 🎸 add support for padded IDs in subquery) event: InstructionEventEnum.InstructionRejected, instructionId: id.toString(), }, @@ -1843,25 +1370,6 @@ describe('Instruction class', () => { query: instructionEventsQuery( false, { -<<<<<<< HEAD -======= - event: InstructionEventEnum.FailedToExecuteInstruction, - instructionId: id.toString(), - }, - new BigNumber(1), - new BigNumber(0) - ), - returnData: { - instructionEvents: { - nodes: [], - }, - }, - }, - { - query: instructionEventsQuery( - false, - { ->>>>>>> 5ce3a3809 (feat: 🎸 add support for padded IDs in subquery) event: InstructionEventEnum.InstructionRejected, instructionId: id.toString(), }, @@ -1945,58 +1453,6 @@ describe('Instruction class', () => { describe('method: getMediators', () => { const mediatorDid1 = 'mediatorDid1'; - const mediatorDid2 = 'mediatorDid2'; - - describe('querying the middleware', () => { - it('should return the instruction mediators', async () => { - dsMockUtils.createApolloQueryMock( - instructionsQuery(false, { - id: id.toString(), - }), - { - instructions: { - nodes: [ - { - mediators: [mediatorDid1, mediatorDid2], - }, - ], - }, - } - ); - const expiry = new Date('2050/01/01'); - dsMockUtils.createApolloQueryMock( - instructionAffirmationsQuery({ - instructionId: id.toString(), - isMediator: true, - }), - { - instructionAffirmations: { - nodes: [ - { - identity: mediatorDid2, - status: AffirmStatusEnum.Affirmed, - expiry, - }, - ], - }, - } - ); - - const result = await instruction.getMediators(); - - expect(result).toEqual([ - { - identity: expect.objectContaining({ did: mediatorDid1 }), - status: AffirmationStatus.Pending, - }, - { - identity: expect.objectContaining({ did: mediatorDid2 }), - status: AffirmationStatus.Affirmed, - expiry, - }, - ]); - }); - }); describe('querying the chain', () => { it('should return the instruction mediators', async () => { @@ -2026,39 +1482,6 @@ describe('Instruction class', () => { describe('method: getOffChainAffirmations', () => { const legId = new BigNumber(2); - describe('querying the middleware', () => { - it('should return the affirmation status of offchain legs', async () => { - dsMockUtils.createApolloQueryMock( - offChainAffirmationsQuery({ - instructionId: id.toString(), - }), - { - instructionAffirmations: { - nodes: [ - { - status: AffirmStatusEnum.Affirmed, - offChainReceipt: { - leg: { - legIndex: legId.toString(), - }, - }, - }, - ], - }, - } - ); - - const result = await instruction.getOffChainAffirmations(); - - expect(result).toEqual([ - expect.objectContaining({ - legId, - status: AffirmationStatus.Affirmed, - }), - ]); - }); - }); - describe('querying the chain', () => { it('should return the affirmation status of offchain legs', async () => { dsMockUtils.configureMocks({ contextOptions: { middlewareAvailable: false } }); @@ -2086,77 +1509,6 @@ describe('Instruction class', () => { describe('method: getOffChainAffirmationForLeg', () => { const legId = new BigNumber(2); - describe('querying the middleware', () => { - it('should return the affirmation status of given offchain leg', async () => { - dsMockUtils.createApolloQueryMock( - legsQuery({ - instructionId: id.toString(), - legIndex: legId.toNumber(), - legType: LegTypeEnum.OffChain, - }), - { - legs: { - nodes: [ - { - offChainReceipts: { - nodes: [ - { - uid: '1', - }, - ], - }, - }, - ], - }, - } - ); - - let result = await instruction.getOffChainAffirmationForLeg({ legId }); - - expect(result).toEqual(AffirmationStatus.Affirmed); - - dsMockUtils.createApolloQueryMock( - legsQuery({ - instructionId: id.toString(), - legIndex: legId.toNumber(), - legType: LegTypeEnum.OffChain, - }), - { - legs: { - nodes: [ - { - offChainReceipts: { - nodes: [], - }, - }, - ], - }, - } - ); - result = await instruction.getOffChainAffirmationForLeg({ legId }); - - expect(result).toEqual(AffirmationStatus.Pending); - }); - - it('should throw an error if no leg is found', () => { - dsMockUtils.createApolloQueryMock( - legsQuery({ - instructionId: id.toString(), - legIndex: legId.toNumber(), - legType: LegTypeEnum.OffChain, - }), - { - legs: { - nodes: [], - }, - } - ); - return expect(instruction.getOffChainAffirmationForLeg({ legId })).rejects.toThrow( - 'The given leg ID is not an off-chain leg' - ); - }); - }); - describe('querying the chain', () => { it('should return the affirmation status for a specific leg', async () => { dsMockUtils.configureMocks({ contextOptions: { middlewareAvailable: false } }); diff --git a/src/utils/__tests__/internal.ts b/src/utils/__tests__/internal.ts index 7790af1f4a..ffb92443ea 100644 --- a/src/utils/__tests__/internal.ts +++ b/src/utils/__tests__/internal.ts @@ -1183,7 +1183,7 @@ describe('warnUnexpectedSqVersion', () => { subqueryVersions: { nodes: [ { - version: '16.2.0-alpha.2', + version: '18.0.2', }, ], }, diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 986deea43e..94c6ef109d 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -150,7 +150,7 @@ export const DEFAULT_CDD_ID = '0x00000000000000000000000000000000000000000000000 /** * Minimum version of Middleware V2 GraphQL Service (SubQuery) that is compatible with this version of the SDK */ -export const MINIMUM_SQ_VERSION = '16.1.0'; +export const MINIMUM_SQ_VERSION = '18.0.2'; /** * The first version of Subquery that pads IDs for proper lexical order diff --git a/src/utils/conversion.ts b/src/utils/conversion.ts index 69942f7a84..6a8ce3b0fd 100644 --- a/src/utils/conversion.ts +++ b/src/utils/conversion.ts @@ -265,11 +265,13 @@ import { CorporateActionIdentifier, CustomTypeData, ExemptKey, + ExtrinsicGroup, ExtrinsicIdentifier, InstructionStatus, InternalAssetType, InternalNftType, MeshTickerOrAssetId, + MiddlewarePermissions, PalletPermissions, PalletPermissionsV6, PalletPermissionsV7, @@ -304,13 +306,14 @@ import { getAssetIdAndTicker, getAssetIdForMiddleware, getAssetIdFromMiddleware, + isMiddlewareV6Extrinsic, isModuleOrTagMatch, optionize, padString, removePadding, requestMulti, } from '~/utils/internal'; -import { uuidToHex } from '~/utils/strings'; +import { isSnakeCase, startsWithCapital, uuidToHex } from '~/utils/strings'; import { isIdentityCondition, isMultiClaimCondition, @@ -1231,6 +1234,10 @@ const formatTxTag = (dispatchable: string, moduleName: string): TxTag => { return `${moduleName}.${camelCase(dispatchable)}` as TxTag; }; +const processDispatchName = (dispatch: BTreeSet): string[] => { + return [...dispatch].map(name => textToString(name)).filter(name => isSnakeCase(name)); +}; + /** * @hidden */ @@ -1284,21 +1291,22 @@ export function extrinsicPermissionsToTransactionPermissions( return exceptions.length ? { ...result, exceptions } : result; } else { + // Note if a pallet or extrinsic has incorrect casing it will get filtered here pallets.forEach(({ extrinsics: dispatchableNames }, palletName) => { - const moduleName = stringLowerFirst(textToString(palletName)); + const pallet = textToString(palletName); + if (!startsWithCapital(pallet)) { + return; // skip incorrect cased pallets + } + const moduleName = stringLowerFirst(pallet); + if (dispatchableNames.isExcept) { - const dispatchables = [...dispatchableNames.asExcept]; - exceptions = [ - ...exceptions, - ...dispatchables.map(name => formatTxTag(textToString(name), moduleName)), - ]; + const dispatchables = processDispatchName(dispatchableNames.asExcept); + + exceptions = [...exceptions, ...dispatchables.map(name => formatTxTag(name, moduleName))]; txValues = [...txValues, moduleName as ModuleName]; } else if (dispatchableNames.isThese) { - const dispatchables = [...dispatchableNames.asThese]; - txValues = [ - ...txValues, - ...dispatchables.map(name => formatTxTag(textToString(name), moduleName)), - ]; + const dispatchables = processDispatchName(dispatchableNames.asThese); + txValues = [...txValues, ...dispatchables.map(name => formatTxTag(name, moduleName))]; } else { txValues = [...txValues, moduleName as ModuleName]; } @@ -5130,58 +5138,72 @@ export function middlewareAgentGroupDataToPermissionGroup( * @hidden */ function middlewareExtrinsicPermissionsDataToTransactionPermissions( - permissions: Record< - string, - { - palletName: string; - dispatchableNames: Record; - }[] - > + permissions: MiddlewarePermissions ): TransactionPermissions | null { - let extrinsicType: PermissionType; - let pallets; + const isLegacy = isMiddlewareV6Extrinsic(permissions); + + let extrinsicType: PermissionType = 'nullish' as unknown as PermissionType; + let rawPallets; if ('these' in permissions) { extrinsicType = PermissionType.Include; - pallets = permissions.these; + rawPallets = permissions.these; } else if ('except' in permissions) { extrinsicType = PermissionType.Exclude; - pallets = permissions.except; + rawPallets = permissions.except; } - let txValues: (ModuleName | TxTag)[] = []; - let exceptions: TxTag[] = []; + if (!rawPallets) { + return null; + } - if (pallets) { - pallets.forEach(({ palletName, dispatchableNames }) => { - const moduleName = stringLowerFirst(coerceHexToString(palletName)); - if ('except' in dispatchableNames) { - const dispatchables = [...dispatchableNames.except]; - exceptions = [ - ...exceptions, - ...dispatchables.map(name => formatTxTag(coerceHexToString(name), moduleName)), - ]; - txValues = [...txValues, moduleName as ModuleName]; - } else if ('these' in dispatchableNames) { - const dispatchables = [...dispatchableNames.these]; - txValues = [ - ...txValues, - ...dispatchables.map(name => formatTxTag(coerceHexToString(name), moduleName)), - ]; - } else { - txValues = [...txValues, moduleName as ModuleName]; - } - }); + let pallets: { + palletName: string; + dispatchableNames: Record; + }[] = rawPallets; - const result = { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - type: extrinsicType!, - values: txValues, - }; + if (!isLegacy) { + pallets = []; + + for (const [key, rawBody] of Object.entries(rawPallets)) { + const body = rawBody as unknown as { extrinsics: ExtrinsicGroup }; - return exceptions.length ? { ...result, exceptions } : result; + if ('these' in body.extrinsics && body.extrinsics.these) { + pallets.push({ palletName: key, dispatchableNames: { these: body.extrinsics.these } }); + } + } } - return null; + let txValues: (ModuleName | TxTag)[] = []; + let exceptions: TxTag[] = []; + + pallets.forEach(({ palletName, dispatchableNames }) => { + const moduleName = stringLowerFirst(coerceHexToString(palletName)); + if ('except' in dispatchableNames) { + const dispatchables = [...dispatchableNames.except]; + exceptions = [ + ...exceptions, + ...dispatchables.map(name => formatTxTag(coerceHexToString(name), moduleName)), + ]; + txValues = [...txValues, moduleName as ModuleName]; + } else if ('these' in dispatchableNames) { + const dispatchables = [...dispatchableNames.these]; + txValues = [ + ...txValues, + ...dispatchables.map(name => formatTxTag(coerceHexToString(name), moduleName)), + ]; + } else { + txValues = [...txValues, moduleName as ModuleName]; + } + }); + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const result = { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + type: extrinsicType!, + values: txValues, + }; + + return exceptions.length ? { ...result, exceptions } : result; } /**