1+ const { Connection, PublicKey } = require ( '@solana/web3.js' ) ;
2+
3+ const PROGRAM_ID = "Rou1svrgkcuo1rBNkP1XaESrD9xRpukx2uLY5MsgK14" ;
4+ const VAULT_ACCOUNT_SIZE = 120 ;
5+ const VAULT_DISCRIMINATOR = Buffer . from ( 'e6fbf1538bca5d1c' , 'hex' ) ;
6+
7+ function decodeVaultAccount ( data ) {
8+ const tokenMintBuffer = data . slice ( 0 , 32 ) ;
9+ const totalLiquidity = data . readBigUInt64LE ( 64 ) ;
10+
11+ const tokenMint = new PublicKey ( tokenMintBuffer ) . toString ( ) ;
12+
13+ return {
14+ tokenMint,
15+ totalLiquidity : totalLiquidity . toString ( ) ,
16+ } ;
17+ }
18+
19+ async function tvl ( _ , _2 , _3 , { api } ) {
20+ const connection = new Connection ( "https://api.mainnet-beta.solana.com" ) ;
21+ const programId = new PublicKey ( PROGRAM_ID ) ;
22+
23+ const accounts = await connection . getProgramAccounts ( programId , {
24+ filters : [ { dataSize : VAULT_ACCOUNT_SIZE } ] ,
25+ } ) ;
26+
27+ for ( const { account } of accounts ) {
28+ if ( account . data . slice ( 0 , 8 ) . equals ( VAULT_DISCRIMINATOR ) ) {
29+ const decoded = decodeVaultAccount ( account . data . slice ( 8 ) ) ;
30+ api . add ( decoded . tokenMint , decoded . totalLiquidity ) ;
31+ }
32+ }
33+ }
34+
35+ module . exports = {
36+ timetravel : false ,
37+ misrepresentedTokens : false ,
38+ methodology :
39+ "TVL is calculated by fetching all program accounts using @solana/web3.js. " +
40+ "Filters for vaults by account size (120 bytes) and discriminator. " +
41+ "Raw token balances are passed to the SDK for USD conversion." ,
42+ solana : {
43+ tvl,
44+ } ,
45+ } ;
0 commit comments