From daa0990e1b68c9b49dd1d3b658cc4ac5a03ecdb2 Mon Sep 17 00:00:00 2001 From: Zamiel Chia Date: Wed, 29 May 2024 19:10:28 +0800 Subject: [PATCH] fix: fix token extension mapping for account keys (#35) * fix: fix test cases failing * docs(changeset): wq * chore: update changelog --- .changeset/silent-keys-teach.md | 5 +++++ .../src/helpers/multisig-checker.ts | 22 ++++++++++++------- .../token-2022-extensions/transfer-fee.ts | 16 +++++++------- 3 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 .changeset/silent-keys-teach.md diff --git a/.changeset/silent-keys-teach.md b/.changeset/silent-keys-teach.md new file mode 100644 index 0000000..f23c4be --- /dev/null +++ b/.changeset/silent-keys-teach.md @@ -0,0 +1,5 @@ +--- +"@solanafm/explorer-kit": patch +--- + +fix: patch token extensions account key mapping diff --git a/packages/explorerkit-translator/src/helpers/multisig-checker.ts b/packages/explorerkit-translator/src/helpers/multisig-checker.ts index 305aadc..5da12c9 100644 --- a/packages/explorerkit-translator/src/helpers/multisig-checker.ts +++ b/packages/explorerkit-translator/src/helpers/multisig-checker.ts @@ -1,6 +1,6 @@ import { IdlInstructionAccount, IdlType } from "@solanafm/kinobi-lite"; -import { extractIdlIxAccountName } from "./idl"; +import { extractIdlIxAccountName, IdlAccountName } from "./idl"; export type DataWithMappedType = { [name: string]: { @@ -18,16 +18,20 @@ export type DataWithMappedType = { * @returns An object containing the mapped account keys and their corresponding names. */ export const mapMultisigAccountKeysToName = ( - accountKeys?: string[], + accountKeys?: IdlAccountName[], idlIxAccounts?: IdlInstructionAccount[], accountName?: string ): DataWithMappedType => { if (idlIxAccounts && accountKeys) { - const names: (string | string[])[] = []; + const names: (IdlAccountName | IdlAccountName[])[] = []; // Populate the names array with the account names idlIxAccounts.forEach((idlIxAccount) => { - names.push(extractIdlIxAccountName(idlIxAccount) ?? "Unknown"); + names.push( + extractIdlIxAccountName(idlIxAccount) ?? { + name: "Unknown", + } + ); }); // Flatten the names array and create an empty object to store the translated account keys @@ -39,9 +43,11 @@ export const mapMultisigAccountKeysToName = ( // This means that there's no multisig and it's most probably a Single owner/delegate scenario if (flattenNames.length === accountKeys.length) { accountKeys.forEach((accountKey, index) => { - const objectKey = flattenNames[index] ?? ("Unknown" as string); + const objectKey = flattenNames[index] ?? { + name: "Unknown", + }; const object: DataWithMappedType = { - [objectKey]: { data: accountKey, type: "publicKey" }, + [objectKey.name]: { data: accountKey, type: "publicKey" }, }; translatedAccountKeysObj = Object.assign(translatedAccountKeysObj, object); @@ -59,9 +65,9 @@ export const mapMultisigAccountKeysToName = ( else { const signers = accountKeys.splice(names.length - 1); accountKeys.forEach((accountKey, index) => { - const objectKey = flattenNames[index] ?? ("Unknown" as string); + const objectKey = flattenNames[index] ?? { name: "Unknown" }; const object: DataWithMappedType = { - [objectKey]: { data: accountKey, type: "publicKey" }, + [objectKey.name]: { data: accountKey, type: "publicKey" }, }; translatedAccountKeysObj = Object.assign(translatedAccountKeysObj, object); diff --git a/packages/explorerkit-translator/src/parsers/v2/instruction/token-2022-extensions/transfer-fee.ts b/packages/explorerkit-translator/src/parsers/v2/instruction/token-2022-extensions/transfer-fee.ts index 675f966..2b1cb05 100644 --- a/packages/explorerkit-translator/src/parsers/v2/instruction/token-2022-extensions/transfer-fee.ts +++ b/packages/explorerkit-translator/src/parsers/v2/instruction/token-2022-extensions/transfer-fee.ts @@ -1,7 +1,7 @@ import { Idl } from "@solanafm/kinobi-lite"; import { convertBNToNumberInObject } from "@solanafm/utils"; -import { extractIdlIxAccountName, mapDataTypeToName } from "../../../../helpers/idl"; +import { extractIdlIxAccountName, IdlAccountName, mapDataTypeToName } from "../../../../helpers/idl"; import { KinobiTreeGenerator } from "../../../../helpers/KinobiTreeGenerator"; import { DataWithMappedType, mapMultisigAccountKeysToName } from "../../../../helpers/multisig-checker"; import { ExtensionTypes } from "../token-v2"; @@ -19,7 +19,7 @@ export const serializeTransferFeeExt = ( extensionIDL: Idl, dataBuffer: Uint8Array, mapTypes?: boolean, - accountKeys?: string[] + accountKeys?: IdlAccountName[] ): ExtensionTypes | null => { const extensionSerializerLayout = new KinobiTreeGenerator(extensionIDL).constructLayout(); const extensionIxDiscriminant = Buffer.from(dataBuffer).readUint8(1); @@ -71,8 +71,8 @@ export const serializeTransferFeeExt = ( const numberOfTokenAccounts = decodedShankData[0].numTokenAccounts.data; const [tokenMint, destination, authority] = [accountKeys[0], accountKeys[1], accountKeys[2]]; const sources = accountKeys.splice(-1 * numberOfTokenAccounts); - const names: (string | string[])[] = []; - let signers: string[] = []; + const names: (IdlAccountName | IdlAccountName[])[] = []; + let signers: IdlAccountName[] = []; // So if account keys still has more than 3 keys, this means that there's more than // 1 signers since token account sources has been spliced @@ -82,16 +82,16 @@ export const serializeTransferFeeExt = ( // Populate the names array with the account names instructionAccounts.forEach((idlIxAccount) => { - names.push(extractIdlIxAccountName(idlIxAccount) ?? "Unknown"); + names.push(extractIdlIxAccountName(idlIxAccount) ?? { name: "Unknown" }); }); // Flatten the names array and create an empty object to store the translated account keys // This is flatten due to the fact that there's a possibility of nested arrays such as Zeta Program const flattenNames = names.flat(5); let toCopy: DataWithMappedType = { - [flattenNames[0] as string]: { data: tokenMint ?? accountKeys[0]!, type: "publicKey" }, - [flattenNames[1] as string]: { data: destination ?? accountKeys[1]!, type: "publicKey" }, - [flattenNames[2] as string]: { data: authority ?? accountKeys[2]!, type: "publicKey" }, + [flattenNames[0]?.name as string]: { data: tokenMint ?? accountKeys[0]!, type: "publicKey" }, + [flattenNames[1]?.name as string]: { data: destination ?? accountKeys[1]!, type: "publicKey" }, + [flattenNames[2]?.name as string]: { data: authority ?? accountKeys[2]!, type: "publicKey" }, }; signers.forEach((signerAccountKey, index) => {