Skip to content

Commit

Permalink
fix: xcm decode (#2881)
Browse files Browse the repository at this point in the history
  • Loading branch information
Asmadek authored Dec 20, 2024
1 parent 753fc3f commit a0a1278
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/renderer/pages/Operations/components/Operation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ const Operation = ({ tx, account }: Props) => {
const approvals = events?.filter((e) => e.status === 'SIGNED') || [];
const initEvent = approvals.find((e) => e.accountId === tx.depositor);
const date = new Date(tx.dateCreated || initEvent?.dateCreated || Date.now());
const assetId = tx.transaction && (tx.transaction.args.assetId || tx.transaction.args.asset);

const assetId = tx.transaction?.args.assetId || tx.transaction?.args.asset;
const asset = getAssetById(assetId, chainsService.getChainById(tx.chainId)?.assets);
const amount = tx.transaction && getTransactionAmount(tx.transaction);

Expand Down
45 changes: 45 additions & 0 deletions src/renderer/shared/api/xcm/__tests__/mock/xcmData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,51 @@ export const XCMPALLET_TRANSFER_HUB_ASTAR = {
},
};

export const XCMPALLET_TRANSFER_PAH_MYTH = {
dest: {
V2: {
parents: '1',
interior: {
X1: {
Parachain: '3,369',
},
},
},
},
beneficiary: {
V2: {
parents: '0',
interior: {
X1: {
AccountKey20: {
network: 'Any',
key: '0x3da9ea1622ee74cf87144e3d2c7f7cce4d167d9c',
},
},
},
},
},
assets: {
V2: [
{
id: {
Concrete: {
parents: '1',
interior: {
X1: {
Parachain: '3,369',
},
},
},
},
fun: {
Fungible: '1327680000000000065',
},
},
],
},
};

export const XTOKENS_ACA_DOT = {
asset: {
V2: {
Expand Down
18 changes: 18 additions & 0 deletions src/renderer/shared/api/xcm/__tests__/xcm-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
CONFIG,
XCMPALLET_TRANSFER_HUB_ASTAR,
XCMPALLET_TRANSFER_KSM_BIFROST,
XCMPALLET_TRANSFER_PAH_MYTH,
XTOKENS_ACA_DOT,
XTOKENS_ACA_PARALLEL,
} from './mock/xcmData';
Expand All @@ -17,12 +18,28 @@ describe('shared/api/xcm/service/xcm-service', () => {
amount: '10070392000',
destParachain: 2001,
destAccountId: '0x7a28037947ecebe0dd86dc0e910911cb33185fd0714b37b75943f67dcf9b6e7c',
assetParachain: 0,
assetGeneralIndex: '',
toRelayChain: false,
type: 'xcmPallet',
});
});

test('should parse xcmPallet parachain > eth parachain', () => {
const result = xcmService.parseXcmPalletExtrinsic(XCMPALLET_TRANSFER_PAH_MYTH);

expect(result).toEqual({
isRelayToken: false,
amount: '1327680000000000065',
assetGeneralIndex: '',
assetParachain: 3369,
destAccountId: '0x3da9ea1622ee74cf87144e3d2c7f7cce4d167d9c',
destParachain: 3369,
toRelayChain: false,
type: 'xcmPallet',
});
});

test('should parse xcmPallet parachain > parachain', () => {
const result = xcmService.parseXcmPalletExtrinsic(XCMPALLET_TRANSFER_HUB_ASTAR);

Expand All @@ -32,6 +49,7 @@ describe('shared/api/xcm/service/xcm-service', () => {
destParachain: 2006,
destAccountId: '0x4d081065a791aaabf8c4c9ec8ed87dce10145c86869c66e80286645730d70c44',
assetGeneralIndex: '1984',
assetParachain: 0,
toRelayChain: false,
type: 'xcmPallet',
});
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/shared/api/xcm/lib/xcm-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ function getSiblingLocation(parachainId: number, accountId?: AccountId) {
}

function getJunctionCols<T>(interior: Record<string, object>, path: string): T {
if (path === 'X1') {
return get(interior, path) as T;
}

return Object.values(get(interior, path)).reduce((acc, item) => {
return { ...acc, ...item };
}, {});
Expand Down
24 changes: 18 additions & 6 deletions src/renderer/shared/api/xcm/service/xcmService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ type ParsedPayload = {

type XcmPalletPayload = ParsedPayload & {
assetGeneralIndex: string;
assetParachain?: number;
type: 'xcmPallet';
};

Expand All @@ -208,20 +209,25 @@ function parseXcmPalletExtrinsic(args: Omit<XcmPalletTransferArgs, 'feeAssetItem
destParachain: 0,
destAccountId: '',
assetGeneralIndex: '',
assetParachain: 0,
toRelayChain: destInterior === 'Here',
type: 'xcmPallet' as const,
};

const beneficiaryJunction = Object.keys(beneficiaryInterior)[0];
parsedPayload.destAccountId = get(beneficiaryInterior, `${beneficiaryJunction}.AccountId32.id`) as unknown as string;
const substrateAccountId = get(beneficiaryInterior, `${beneficiaryJunction}.AccountId32.id`) as unknown as string;
const ethAccountId = get(beneficiaryInterior, `${beneficiaryJunction}.AccountKey20.key`) as unknown as string;
parsedPayload.destAccountId = substrateAccountId || ethAccountId;

const destJunction = Object.keys(destInterior)[0];
parsedPayload.destParachain = Number(xcmUtils.toRawString(get(destInterior, `${destJunction}.Parachain`)));

if (!parsedPayload.isRelayToken) {
const assetJunction = Object.keys(assetInterior)[0];
const cols = xcmUtils.getJunctionCols<{ GeneralIndex: string }>(assetInterior, assetJunction);
parsedPayload.assetGeneralIndex = xcmUtils.toRawString(cols.GeneralIndex);
const cols = xcmUtils.getJunctionCols<{ GeneralIndex: string; Parachain: number }>(assetInterior, assetJunction);

parsedPayload.assetGeneralIndex = xcmUtils.toRawString(cols?.GeneralIndex);
parsedPayload.assetParachain = cols?.Parachain ? Number(xcmUtils.toRawString(cols.Parachain.toString())) : 0;
}

return parsedPayload;
Expand Down Expand Up @@ -255,14 +261,17 @@ function parseXTokensExtrinsic(args: Omit<XTokenPalletTransferArgs, 'destWeight'
parsedPayload.toRelayChain = destJunction === 'X1';

if (parsedPayload.toRelayChain) {
parsedPayload.destAccountId = get(destInterior, 'X1.AccountId32.id') as unknown as string;
const substrateAccountId = get(destInterior, `X1.AccountId32.id`) as unknown as string;
const ethAccountId = get(destInterior, `X1.AccountKey20.key`) as unknown as string;

parsedPayload.destAccountId = substrateAccountId || ethAccountId;
} else {
const cols = xcmUtils.getJunctionCols<{ Parachain?: number }>(destInterior, destJunction);
if (cols.Parachain) {
parsedPayload.destParachain = Number(xcmUtils.toRawString(cols.Parachain.toString()));
parsedPayload.toRelayChain = false;
}
parsedPayload.destAccountId = get(cols, 'AccountId32.id') as unknown as string;
parsedPayload.destAccountId = (get(cols, 'AccountId32.id') || get(cols, 'AccountKey20.key')) as unknown as string;
}

return parsedPayload;
Expand Down Expand Up @@ -301,7 +310,10 @@ function decodeXcm(chainId: ChainId, data: XcmPalletPayload | XTokensPayload): D
}, []);

const assetKeyVal = filteredAssetLocations.find(([_, { multiLocation }]) => {
const xcmPalletMatch = data.type === 'xcmPallet' && multiLocation.generalIndex === data.assetGeneralIndex;
const xcmPalletMatch =
data.type === 'xcmPallet' &&
(!data.assetParachain || multiLocation.parachainId === data.assetParachain) &&
(multiLocation.generalIndex === data.assetGeneralIndex || data.assetGeneralIndex.length === 0);

const xTokensMatch =
data.type === 'xTokens' &&
Expand Down

0 comments on commit a0a1278

Please sign in to comment.