Skip to content

Commit

Permalink
fix: fix token extension mapping for account keys (#35)
Browse files Browse the repository at this point in the history
* fix: fix test cases failing

* docs(changeset): wq

* chore: update changelog
  • Loading branch information
doodoo-aihc authored May 29, 2024
1 parent d833b78 commit daa0990
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/silent-keys-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@solanafm/explorer-kit": patch
---

fix: patch token extensions account key mapping
22 changes: 14 additions & 8 deletions packages/explorerkit-translator/src/helpers/multisig-checker.ts
Original file line number Diff line number Diff line change
@@ -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]: {
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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) => {
Expand Down

0 comments on commit daa0990

Please sign in to comment.