Skip to content

Commit 98c8efa

Browse files
committed
fix: enhance address lookup functionality in transaction decoding
1 parent 0ccb117 commit 98c8efa

1 file changed

Lines changed: 75 additions & 4 deletions

File tree

packages/extension/src/providers/solana/ui/libs/decode-tx.ts

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
PublicKey,
1111
Transaction,
1212
TransactionVersion,
13+
AddressLookupTableProgram,
14+
AddressLookupTableAccount,
1315
} from '@solana/web3.js';
1416
import SolanaAPI from '@/providers/solana/libs/api';
1517
import { SolanaNetwork } from '../../types/sol-network';
@@ -48,6 +50,47 @@ const assetFetch = (
4850
}).then(res => res.json());
4951
};
5052

53+
export async function fetchRelevantAddresses(
54+
solAPI: SolanaAPI,
55+
lookupTableKeys: PublicKey[],
56+
relevantIndexes: Set<number>,
57+
): Promise<PublicKey[]> {
58+
const relevantAddresses: PublicKey[] = [];
59+
for (const key of lookupTableKeys) {
60+
const accountInfo = await solAPI.web3.getAccountInfo(key);
61+
if (
62+
accountInfo?.data &&
63+
accountInfo.owner.equals(AddressLookupTableProgram.programId)
64+
) {
65+
try {
66+
const lookupTableAccount = AddressLookupTableAccount.deserialize(
67+
accountInfo.data,
68+
);
69+
if (lookupTableAccount && lookupTableAccount.addresses) {
70+
lookupTableAccount.addresses.forEach(async (address, index) => {
71+
if (relevantIndexes.has(index)) {
72+
const addressInfo = await solAPI.web3.getAccountInfo(address);
73+
if (
74+
(addressInfo?.owner.toBase58() ===
75+
TOKEN_PROGRAM_ID.toBase58() ||
76+
addressInfo?.owner.toBase58() ===
77+
TOKEN_2022_PROGRAM_ID.toBase58()) &&
78+
addressInfo.data.length >= ACCOUNT_SIZE
79+
) {
80+
relevantAddresses.push(address);
81+
}
82+
}
83+
});
84+
}
85+
} catch {
86+
console.error('Failed to deserialize address lookup table account');
87+
}
88+
}
89+
}
90+
91+
return relevantAddresses;
92+
}
93+
5194
const decodeTransaction = async (
5295
tx: VersionedTransaction | Transaction,
5396
from: PublicKey,
@@ -57,22 +100,50 @@ const decodeTransaction = async (
57100
const solAPI = (await network.api()).api as SolanaAPI;
58101
const allBalances = await network.getAllTokenInfo(from.toBase58());
59102
const marketData = new MarketData();
103+
let accounts: string[] = [];
104+
if (version !== 'legacy') {
105+
const relevantIndexes = new Set<number>();
106+
107+
// Retrieve addresses from the LUTs and the message
108+
const addressTableLookupKeys = (
109+
tx as VersionedTransaction
110+
).message.addressTableLookups.map(
111+
lookup => new PublicKey(lookup.accountKey),
112+
);
113+
114+
(tx as VersionedTransaction).message.addressTableLookups.forEach(lookup => {
115+
lookup.writableIndexes.forEach(index => relevantIndexes.add(index));
116+
lookup.readonlyIndexes.forEach(index => relevantIndexes.add(index));
117+
});
118+
119+
const lookupTableAccounts = await fetchRelevantAddresses(
120+
solAPI,
121+
addressTableLookupKeys,
122+
relevantIndexes,
123+
);
124+
125+
accounts = [
126+
...(tx as VersionedTransaction).message.staticAccountKeys.map(k =>
127+
k.toBase58(),
128+
),
129+
...lookupTableAccounts.map(k => k.toBase58()),
130+
];
131+
}
60132
return (
61133
version !== 'legacy'
62134
? solAPI.web3.simulateTransaction(tx as VersionedTransaction, {
63135
accounts: {
64-
addresses: (
65-
tx as VersionedTransaction
66-
).message.staticAccountKeys.map(k => k.toBase58()),
136+
addresses: accounts,
67137
encoding: 'base64',
68138
},
69139
})
70140
: solAPI.web3.simulateTransaction(tx as Transaction, undefined, true)
71141
).then(async result => {
72142
if (result.value.err) return null;
143+
console.log(result.value);
73144
const nativeChange = {
74145
contract: NATIVE_TOKEN_ADDRESS,
75-
amount: BigInt(result.value.accounts![0]!.lamports),
146+
amount: BigInt(result.value.accounts![1]!.lamports),
76147
};
77148
const balanceChanges = result.value
78149
.accounts!.filter(a => {

0 commit comments

Comments
 (0)