import { Connection, PublicKey } from '@solana/web3.js' import { DriftClient, convertToNumber, QUOTE_PRECISION, BASE_PRECISION, PRICE_PRECISION } from '@drift-labs/sdk' import { Wallet } from '@coral-xyz/anchor' import dotenv from 'dotenv' async function testAccountDataDecoding() { console.log('šŸ” Testing account data decoding at correct PDA...') const connection = new Connection(process.env.SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com') // The PDA that the SDK found const correctPDA = new PublicKey('7LonnWut5i3h36xyMA5jbwnGFbnzXUPY2dsPfNaSsrTk') console.log(`šŸ“ Examining account at: ${correctPDA.toString()}`) try { // Get account info const accountInfo = await connection.getAccountInfo(correctPDA) if (!accountInfo) { console.log('āŒ Account not found') return } console.log(`šŸ“Š Account data length: ${accountInfo.data.length} bytes`) console.log(`šŸ“Š Account owner: ${accountInfo.owner.toString()}`) const walletPublicKey = new PublicKey('3dG7wayp7b9NBMo92D2qL2sy1curSC4TTmskFpaGDrtA') // Hardcode for now const wallet = new Wallet({ publicKey: walletPublicKey, signTransaction: async (tx) => tx, signAllTransactions: async (txs) => txs }) const driftClient = new DriftClient({ connection, wallet, env: 'mainnet-beta', opts: { commitment: 'confirmed' } }) console.log('šŸ” Attempting to decode account data...') try { // Try to decode the account data using Drift's UserAccount structure const userAccount = driftClient.program.account.user.coder.accounts.decode( 'user', accountInfo.data ) console.log('āœ… Successfully decoded user account data!') // Log basic account info console.log(`šŸ‘¤ Authority: ${userAccount.authority.toString()}`) console.log(`šŸ†” Sub Account ID: ${userAccount.subAccountId}`) // Check spot positions console.log('\\nšŸ’° Spot Positions:') if (userAccount.spotPositions && Array.isArray(userAccount.spotPositions)) { let totalSpotValue = 0 for (let i = 0; i < Math.min(userAccount.spotPositions.length, 10); i++) { const spotPosition = userAccount.spotPositions[i] if (spotPosition.scaledBalance && !spotPosition.scaledBalance.isZero()) { const balance = convertToNumber(spotPosition.scaledBalance, QUOTE_PRECISION) totalSpotValue += balance console.log(` Market ${i}: $${balance.toFixed(2)}`) } } console.log(`šŸ“Š Total spot value: $${totalSpotValue.toFixed(2)}`) } // Check perp positions console.log('\\nšŸ“ˆ Perp Positions:') if (userAccount.perpPositions && Array.isArray(userAccount.perpPositions)) { let totalPerpValue = 0 for (let i = 0; i < Math.min(userAccount.perpPositions.length, 10); i++) { const perpPosition = userAccount.perpPositions[i] if (perpPosition.baseAssetAmount && !perpPosition.baseAssetAmount.isZero()) { const size = convertToNumber(perpPosition.baseAssetAmount, BASE_PRECISION) const quoteAmount = convertToNumber(perpPosition.quoteEntryAmount, QUOTE_PRECISION) console.log(` Market ${i}: Size ${size.toFixed(4)}, Quote ${quoteAmount.toFixed(2)}`) totalPerpValue += Math.abs(quoteAmount) } } console.log(`šŸ“Š Total perp value: $${totalPerpValue.toFixed(2)}`) } // Check if we can calculate total collateral console.log('\\nšŸ’Ž Account Metrics:') console.log(` Name: ${userAccount.name ? Buffer.from(userAccount.name).toString().replace(/\\0/g, '') : 'Unnamed'}`) console.log(` Max Margin Ratio: ${userAccount.maxMarginRatio}`) console.log(` Next Order ID: ${userAccount.nextOrderId}`) console.log(` Last Active Slot: ${userAccount.lastActiveSlot}`) } catch (decodeError) { console.error('āŒ Failed to decode account data:', decodeError) // Try to extract raw data console.log('šŸ” Examining raw account data...') const data = accountInfo.data console.log(`First 32 bytes: ${data.slice(0, 32).toString('hex')}`) console.log(`Last 32 bytes: ${data.slice(-32).toString('hex')}`) } } catch (error) { console.error('āŒ Error examining account:', error) } } // Load environment dotenv.config() // Run the test testAccountDataDecoding() .then(() => console.log('āœ… Test completed')) .catch(error => console.error('āŒ Test failed:', error))