Skip to content

Commit 06f29ec

Browse files
committed
fix tests
1 parent cc4d3b1 commit 06f29ec

File tree

6 files changed

+122
-68
lines changed

6 files changed

+122
-68
lines changed

lib/solana-rpc.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ function createProgramAddress(
217217
* Returns null if the derived address is on the curve (invalid PDA).
218218
* This version doesn't throw errors, making it suitable for bulk checking.
219219
*/
220-
function createProgramAddressUnchecked(
220+
function _createProgramAddressUnchecked(
221221
seeds: Uint8Array[],
222222
programId: Uint8Array,
223223
): Uint8Array | null {
@@ -1537,7 +1537,8 @@ export async function deriveMeteoraDlmmLpMetadata(
15371537
}
15381538

15391539
// Check if tokenXMint is the system program (all zeros = native SOL)
1540-
const isTokenXNativeSol = pool.tokenXMint === '11111111111111111111111111111111';
1540+
const isTokenXNativeSol =
1541+
pool.tokenXMint === '11111111111111111111111111111111';
15411542

15421543
// Get metadata for the tokens we need to fetch
15431544
const addressesToFetch: string[] = [];
@@ -1548,7 +1549,10 @@ export async function deriveMeteoraDlmmLpMetadata(
15481549
addressesToFetch.push(findMetadataPda(pool.tokenYMint));
15491550
addressesToFetch.push(pool.tokenYMint);
15501551

1551-
const accountInfos = await getMultipleAccountsInfo(addressesToFetch, retryOrOpts);
1552+
const accountInfos = await getMultipleAccountsInfo(
1553+
addressesToFetch,
1554+
retryOrOpts,
1555+
);
15521556

15531557
// Helper to get symbol from various sources
15541558
const getSymbol = (
@@ -1592,14 +1596,26 @@ export async function deriveMeteoraDlmmLpMetadata(
15921596
tokenXSymbol = 'SOL';
15931597
const tokenYMetaInfo = accountInfos[0];
15941598
const tokenYMintInfo = accountInfos[1];
1595-
tokenYSymbol = getSymbol(tokenYMetaInfo, tokenYMintInfo, pool.tokenYMint);
1599+
tokenYSymbol = getSymbol(
1600+
tokenYMetaInfo,
1601+
tokenYMintInfo,
1602+
pool.tokenYMint,
1603+
);
15961604
} else {
15971605
const tokenXMetaInfo = accountInfos[0];
15981606
const tokenXMintInfo = accountInfos[1];
15991607
const tokenYMetaInfo = accountInfos[2];
16001608
const tokenYMintInfo = accountInfos[3];
1601-
tokenXSymbol = getSymbol(tokenXMetaInfo, tokenXMintInfo, pool.tokenXMint);
1602-
tokenYSymbol = getSymbol(tokenYMetaInfo, tokenYMintInfo, pool.tokenYMint);
1609+
tokenXSymbol = getSymbol(
1610+
tokenXMetaInfo,
1611+
tokenXMintInfo,
1612+
pool.tokenXMint,
1613+
);
1614+
tokenYSymbol = getSymbol(
1615+
tokenYMetaInfo,
1616+
tokenYMintInfo,
1617+
pool.tokenYMint,
1618+
);
16031619
}
16041620

16051621
return {
@@ -1680,12 +1696,14 @@ export const RAYDIUM_CPMM_PROGRAM_ID =
16801696
* Raydium AMM V4 Authority PDA
16811697
* Derived from seeds [b"amm authority"] with bump 254
16821698
*/
1683-
export const RAYDIUM_AMM_AUTHORITY = '5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1';
1699+
export const RAYDIUM_AMM_AUTHORITY =
1700+
'5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1';
16841701

16851702
/**
16861703
* Raydium CPMM Authority - Fixed address for all CPMM pools
16871704
*/
1688-
export const RAYDIUM_CPMM_AUTHORITY = 'GpMZbSM2GgvTKHJirzeGfMFoaZ8UR2X7F4v8vHTvxFbL';
1705+
export const RAYDIUM_CPMM_AUTHORITY =
1706+
'GpMZbSM2GgvTKHJirzeGfMFoaZ8UR2X7F4v8vHTvxFbL';
16891707

16901708
/**
16911709
* Raydium AMM Pool (AmmInfo) Layout:
@@ -2006,11 +2024,14 @@ export async function isRaydiumAmmLpToken(
20062024
pools && pools.length > 0 ? pools[0].pubkey : null;
20072025
}
20082026
} catch (poolError) {
2009-
log.debug('Failed to find Raydium pool address (LP detection still valid)', {
2010-
mintAddress,
2011-
poolType,
2012-
error: (poolError as Error).message,
2013-
});
2027+
log.debug(
2028+
'Failed to find Raydium pool address (LP detection still valid)',
2029+
{
2030+
mintAddress,
2031+
poolType,
2032+
error: (poolError as Error).message,
2033+
},
2034+
);
20142035
// Pool search failed but authority matched, so it's still an LP token
20152036
}
20162037

scripts/check-mint.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getAccountInfo, base58Encode } from '../lib/solana-rpc.ts';
1+
import { base58Encode, getAccountInfo } from '../lib/solana-rpc.ts';
22

33
const mint = process.argv[2] || 'J73NU7ttijwcjgoMB7ejeZ47f8ZB48jdc3SkecoLLUTA';
44

scripts/check-raydium.ts

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,16 @@
33
*/
44

55
import { PublicKey } from '@solana/web3.js';
6-
import { getAccountInfo, getProgramAccounts, base58Encode, base58Decode } from '../lib/solana-rpc';
6+
import {
7+
base58Decode,
8+
base58Encode,
9+
getAccountInfo,
10+
getProgramAccounts,
11+
} from '../lib/solana-rpc';
712

8-
const RAYDIUM_AMM_PROGRAM_ID = new PublicKey('675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8');
13+
const RAYDIUM_AMM_PROGRAM_ID = new PublicKey(
14+
'675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8',
15+
);
916
const AUTHORITY_SEED = Buffer.from('amm authority');
1017

1118
// Test Raydium LP token
@@ -22,8 +29,10 @@ async function main() {
2229
}
2330
const buffer = Buffer.from(mintAccount.data, 'base64');
2431
const hasAuthority = buffer.readUInt32LE(0) === 1;
25-
const mintAuthority = hasAuthority ? base58Encode(buffer.subarray(4, 36)) : null;
26-
32+
const mintAuthority = hasAuthority
33+
? base58Encode(buffer.subarray(4, 36))
34+
: null;
35+
2736
if (!mintAuthority) {
2837
console.log('No mint authority');
2938
return;
@@ -33,13 +42,15 @@ async function main() {
3342
console.log('');
3443

3544
// Try to find the nonce that produces this authority
36-
console.log('Searching for matching PDA (v4 format: [amm authority, nonce])...');
45+
console.log(
46+
'Searching for matching PDA (v4 format: [amm authority, nonce])...',
47+
);
3748

3849
for (let nonce = 255; nonce >= 0; nonce--) {
3950
try {
4051
const pda = PublicKey.createProgramAddressSync(
4152
[AUTHORITY_SEED, Buffer.from([nonce])],
42-
RAYDIUM_AMM_PROGRAM_ID
53+
RAYDIUM_AMM_PROGRAM_ID,
4354
);
4455

4556
if (pda.toBase58() === mintAuthority) {
@@ -51,7 +62,7 @@ async function main() {
5162
if (nonce >= 252) {
5263
console.log(`Nonce ${nonce}: ${pda.toBase58()}`);
5364
}
54-
} catch (e) {
65+
} catch (_e) {
5566
// Invalid PDA for this nonce (point is on curve)
5667
if (nonce >= 252) {
5768
console.log(`Nonce ${nonce}: invalid (on curve)`);
@@ -66,7 +77,7 @@ async function main() {
6677
// Let's also try find_program_address
6778
const [standardPda, bump] = PublicKey.findProgramAddressSync(
6879
[AUTHORITY_SEED],
69-
RAYDIUM_AMM_PROGRAM_ID
80+
RAYDIUM_AMM_PROGRAM_ID,
7081
);
7182
console.log('');
7283
console.log('Standard PDA (single seed):');
@@ -77,33 +88,30 @@ async function main() {
7788
// Try to find the pool account that has this LP mint
7889
console.log('');
7990
console.log('Searching for pool account with this LP mint...');
80-
91+
8192
// LP mint is at offset 472 in the pool account
82-
const lpMintBytes = base58Decode(TEST_LP_MINT);
83-
const pools = await getProgramAccounts(
84-
RAYDIUM_AMM_PROGRAM_ID.toBase58(),
85-
{
86-
filters: [
87-
{
88-
memcmp: {
89-
offset: 472, // lpMint offset in AmmInfo struct
90-
bytes: TEST_LP_MINT,
91-
},
93+
const _lpMintBytes = base58Decode(TEST_LP_MINT);
94+
const pools = await getProgramAccounts(RAYDIUM_AMM_PROGRAM_ID.toBase58(), {
95+
filters: [
96+
{
97+
memcmp: {
98+
offset: 472, // lpMint offset in AmmInfo struct
99+
bytes: TEST_LP_MINT,
92100
},
93-
],
94-
dataSlice: {
95-
offset: 0,
96-
length: 600, // Get enough to see the nonce
97101
},
98-
}
99-
);
100-
102+
],
103+
dataSlice: {
104+
offset: 0,
105+
length: 600, // Get enough to see the nonce
106+
},
107+
});
108+
101109
console.log('Found pools:', pools.length);
102110
for (const pool of pools) {
103111
console.log('Pool:', pool.pubkey);
104112
const data = Buffer.from(pool.account.data, 'base64');
105113
console.log('Data length:', data.length);
106-
114+
107115
// In Raydium V4 AmmInfo, the nonce is at a specific offset
108116
// Let's dump some key offsets
109117
// status: u64 at 0
@@ -112,16 +120,16 @@ async function main() {
112120
const nonce = data.readBigUInt64LE(8);
113121
console.log('Status:', status);
114122
console.log('Nonce:', nonce);
115-
123+
116124
// Try deriving with this nonce
117125
try {
118126
const poolPda = PublicKey.createProgramAddressSync(
119127
[AUTHORITY_SEED, Buffer.from([Number(nonce)])],
120-
RAYDIUM_AMM_PROGRAM_ID
128+
RAYDIUM_AMM_PROGRAM_ID,
121129
);
122130
console.log('PDA with pool nonce:', poolPda.toBase58());
123131
console.log('Match:', poolPda.toBase58() === mintAuthority);
124-
} catch (e) {
132+
} catch (_e) {
125133
console.log('PDA with pool nonce: invalid');
126134
}
127135
}

services/metadata-solana/index.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ async function processSolanaMint(
204204
// Check Meteora DLMM LP token (if not already identified as LP)
205205
if (!isLpToken) {
206206
try {
207-
const meteoraCheck = await isMeteoraDlmmLpToken(data.contract);
207+
const meteoraCheck = await isMeteoraDlmmLpToken(
208+
data.contract,
209+
);
208210
if (meteoraCheck.isLpToken && meteoraCheck.poolAddress) {
209211
const lpMetadata = await deriveMeteoraDlmmLpMetadata(
210212
meteoraCheck.poolAddress,
@@ -233,7 +235,9 @@ async function processSolanaMint(
233235
// Check Raydium LP token - AMM V4 or CPMM (if not already identified as LP)
234236
if (!isLpToken) {
235237
try {
236-
const raydiumCheck = await isRaydiumAmmLpToken(data.contract);
238+
const raydiumCheck = await isRaydiumAmmLpToken(
239+
data.contract,
240+
);
237241
if (raydiumCheck.isLpToken && raydiumCheck.poolType) {
238242
// If we have a pool address, try to derive full metadata
239243
if (raydiumCheck.poolAddress) {
@@ -261,12 +265,15 @@ async function processSolanaMint(
261265
lpName = `Raydium ${raydiumCheck.poolType.toUpperCase()} LP`;
262266
lpSymbol = 'RAY-LP';
263267
lpSource = 'raydium';
264-
log.debug('Detected Raydium LP token (pool address not found)', {
265-
mint: data.contract,
266-
poolType: raydiumCheck.poolType,
267-
name: lpName,
268-
symbol: lpSymbol,
269-
});
268+
log.debug(
269+
'Detected Raydium LP token (pool address not found)',
270+
{
271+
mint: data.contract,
272+
poolType: raydiumCheck.poolType,
273+
name: lpName,
274+
symbol: lpSymbol,
275+
},
276+
);
270277
}
271278
}
272279
} catch (lpError) {

services/metadata-solana/query.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ describe('Solana metadata query service', () => {
7272
);
7373
mockDeriveMeteoraDlmmLpMetadata.mockReturnValue(Promise.resolve(null));
7474
mockIsRaydiumAmmLpToken.mockReturnValue(
75-
Promise.resolve({ isLpToken: false, poolAddress: null, poolType: null }),
75+
Promise.resolve({
76+
isLpToken: false,
77+
poolAddress: null,
78+
poolType: null,
79+
}),
7680
);
7781
mockDeriveRaydiumLpMetadata.mockReturnValue(Promise.resolve(null));
7882
});

services/metadata-solana/query.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import {
1414
isMeteoraDlmmLpToken,
1515
isPumpAmmLpToken,
1616
isRaydiumAmmLpToken,
17-
METEORA_DLMM_PROGRAM_ID,
1817
METAPLEX_PROGRAM_ID,
18+
METEORA_DLMM_PROGRAM_ID,
1919
PUMP_AMM_PROGRAM_ID,
2020
parseToken2022Extensions,
2121
RAYDIUM_AMM_PROGRAM_ID,
@@ -261,14 +261,19 @@ export async function queryMetadata(
261261

262262
if (lpCheck.isLpToken && lpCheck.poolType) {
263263
isRaydiumLp = true;
264-
success(`This is a Raydium ${lpCheck.poolType.toUpperCase()} LP token`, {
265-
poolAddress: lpCheck.poolAddress ?? 'Not found (pool search timed out)',
266-
poolType: lpCheck.poolType,
267-
raydiumProgram:
268-
lpCheck.poolType === 'amm-v4'
269-
? RAYDIUM_AMM_PROGRAM_ID
270-
: RAYDIUM_CPMM_PROGRAM_ID,
271-
});
264+
success(
265+
`This is a Raydium ${lpCheck.poolType.toUpperCase()} LP token`,
266+
{
267+
poolAddress:
268+
lpCheck.poolAddress ??
269+
'Not found (pool search timed out)',
270+
poolType: lpCheck.poolType,
271+
raydiumProgram:
272+
lpCheck.poolType === 'amm-v4'
273+
? RAYDIUM_AMM_PROGRAM_ID
274+
: RAYDIUM_CPMM_PROGRAM_ID,
275+
},
276+
);
272277

273278
// Derive LP metadata from pool (only if we found the pool address)
274279
if (lpCheck.poolAddress) {
@@ -290,7 +295,8 @@ export async function queryMetadata(
290295
}
291296
} else {
292297
info('Not a Raydium LP token', {
293-
message: 'Mint authority does not match any known Raydium authority',
298+
message:
299+
'Mint authority does not match any known Raydium authority',
294300
});
295301
}
296302
} catch (err) {
@@ -532,7 +538,13 @@ export async function queryMetadata(
532538
console.log();
533539

534540
// Final resolved values
535-
if (finalName || finalSymbol || isPumpAmmLp || isMeteoraDlmmLp || isRaydiumLp) {
541+
if (
542+
finalName ||
543+
finalSymbol ||
544+
isPumpAmmLp ||
545+
isMeteoraDlmmLp ||
546+
isRaydiumLp
547+
) {
536548
const isLpToken = isPumpAmmLp || isMeteoraDlmmLp || isRaydiumLp;
537549
const lpMetadata = isPumpAmmLp
538550
? pumpAmmLpMetadata
@@ -547,11 +559,13 @@ export async function queryMetadata(
547559
: isRaydiumLp && raydiumLpMetadata
548560
? 'Raydium AMM LP derived'
549561
: 'URI takes precedence';
550-
562+
551563
// Use LP-derived values if available, otherwise use standard metadata
552-
const displayName = isLpToken && lpMetadata ? lpMetadata.name : finalName;
553-
const displaySymbol = isLpToken && lpMetadata ? lpMetadata.symbol : finalSymbol;
554-
564+
const displayName =
565+
isLpToken && lpMetadata ? lpMetadata.name : finalName;
566+
const displaySymbol =
567+
isLpToken && lpMetadata ? lpMetadata.symbol : finalSymbol;
568+
555569
console.log(
556570
` ${BOLD}${CYAN}Final Values (${precedenceSource}):${RESET}`,
557571
);

0 commit comments

Comments
 (0)