|  | 
|  | 1 | +// projects/exotic-markets/index.js | 
|  | 2 | + | 
|  | 3 | +const { getProvider, sumTokens2 } = require('../helper/solana') | 
|  | 4 | +const { PublicKey } = require('@solana/web3.js') | 
|  | 5 | +const snapshot = require('./vaults.json') | 
|  | 6 | + | 
|  | 7 | +// ---- Config ---- | 
|  | 8 | +const PROGRAM_ID = new PublicKey('exomt54Csh4fvkUiyV5h6bjNqxDqLdpgHJmLd4eqynk') | 
|  | 9 | +const TOKEN_PROG = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA') | 
|  | 10 | +// scan this many recent signatures each run (tunable via env) | 
|  | 11 | +const TAIL_LIMIT = Number(process.env.TAIL_LIMIT || 200) | 
|  | 12 | +// ---------------- | 
|  | 13 | + | 
|  | 14 | +function keyAt(msg, i) { | 
|  | 15 | +  const k = msg.accountKeys?.[i] | 
|  | 16 | +  return typeof k?.toBase58 === 'function' ? k.toBase58() : String(k || '') | 
|  | 17 | +} | 
|  | 18 | + | 
|  | 19 | +async function getTailCandidates(conn) { | 
|  | 20 | +  // Fetch most-recent program txs | 
|  | 21 | +  const sigs = await conn.getSignaturesForAddress(PROGRAM_ID, { limit: TAIL_LIMIT }) | 
|  | 22 | +  const seen = new Set() | 
|  | 23 | + | 
|  | 24 | +  // Very cheap heuristics: | 
|  | 25 | +  //  - include every token account appearing in postTokenBalances (actually received/held tokens) | 
|  | 26 | +  //  - include initializeAccount* targets from Token Program CPIs (new vaults created) | 
|  | 27 | +  for (const s of sigs) { | 
|  | 28 | +    const tx = await conn.getTransaction(s.signature, { maxSupportedTransactionVersion: 0 }) | 
|  | 29 | +    if (!tx?.meta) continue | 
|  | 30 | +    const msg = tx.transaction.message | 
|  | 31 | + | 
|  | 32 | +    for (const b of tx.meta.postTokenBalances || []) { | 
|  | 33 | +      const ta = b.account ?? keyAt(msg, b.accountIndex) | 
|  | 34 | +      if (ta) seen.add(ta) | 
|  | 35 | +    } | 
|  | 36 | +    for (const inn of tx.meta.innerInstructions || []) { | 
|  | 37 | +      for (const instr of inn.instructions || []) { | 
|  | 38 | +        const prog = typeof instr.programIdIndex === 'number' ? keyAt(msg, instr.programIdIndex) : instr.programId | 
|  | 39 | +        if (prog !== TOKEN_PROG.toBase58()) continue | 
|  | 40 | +        const accs = (instr.accounts || []).map(a => typeof a === 'number' ? keyAt(msg, a) : a) | 
|  | 41 | +        if (accs[0]) seen.add(accs[0])   // initializeAccount3 target is account[0] | 
|  | 42 | +      } | 
|  | 43 | +    } | 
|  | 44 | +  } | 
|  | 45 | +  seen.delete('11111111111111111111111111111111') | 
|  | 46 | +  return [...seen] | 
|  | 47 | +} | 
|  | 48 | + | 
|  | 49 | +async function filterToSplTokenAccounts(conn, addrs) { | 
|  | 50 | +  if (!addrs.length) return [] | 
|  | 51 | +  // Use owner + data length to verify “is SPL token account” quickly | 
|  | 52 | +  const infos = await conn.getMultipleAccountsInfo(addrs.map(a => new PublicKey(a))) | 
|  | 53 | +  const out = [] | 
|  | 54 | +  for (let i = 0; i < infos.length; i++) { | 
|  | 55 | +    const info = infos[i] | 
|  | 56 | +    if (info && info.owner.equals(TOKEN_PROG) && info.data?.length === 165) out.push(addrs[i]) | 
|  | 57 | +  } | 
|  | 58 | +  return out | 
|  | 59 | +} | 
|  | 60 | + | 
|  | 61 | +async function tvl() { | 
|  | 62 | +  const { connection } = getProvider() | 
|  | 63 | + | 
|  | 64 | +  // 1) Backfilled snapshot | 
|  | 65 | +  const base = snapshot.tokenAccounts || [] | 
|  | 66 | + | 
|  | 67 | +  // 2) Small live tail discovery | 
|  | 68 | +  const tailCandidates = await getTailCandidates(connection) | 
|  | 69 | +  const tailVerified = await filterToSplTokenAccounts(connection, tailCandidates) | 
|  | 70 | + | 
|  | 71 | +  // 3) Union & sum | 
|  | 72 | +  const tokenAccounts = [...new Set([...base, ...tailVerified])] | 
|  | 73 | +  return sumTokens2({ tokenAccounts }) | 
|  | 74 | +} | 
|  | 75 | + | 
|  | 76 | +module.exports = { | 
|  | 77 | +  timetravel: false, // discovery uses recent live txs | 
|  | 78 | +  solana: { tvl }, | 
|  | 79 | +  methodology: | 
|  | 80 | +    'Sums balances of snapshot vault SPL token accounts and unions a small live scan of recent program transactions to discover newly created/funded vaults. The snapshot is updated weekly via a separate process.', | 
|  | 81 | +} | 
0 commit comments