import { Connection, PublicKey } from '@solana/web3.js' import { AccountInfo, AccountLayout, MintInfo, MintLayout, u64, } from '@solana/spl-token' export type TokenAccount = AccountInfo export type MintAccount = MintInfo export type ProgramAccount = { publicKey: PublicKey account: T } export async function getOwnedTokenAccounts( connection: Connection, publicKey: PublicKey ): Promise[]> { const results = await connection.getTokenAccountsByOwner(publicKey, { programId: TOKEN_PROGRAM_ID, }) return results.value.map((r) => { const publicKey = r.pubkey const data = Buffer.from(r.account.data) const account = parseTokenAccountData(publicKey, data) return { publicKey, account } }) } export async function getMint( connection: Connection, publicKey: PublicKey ): Promise> { const result = await connection.getAccountInfo(publicKey) const data = Buffer.from(result.data) const account = parseMintAccountData(data) return { publicKey, account, } } export async function getTokenAccount( connection: Connection, publicKey: PublicKey ): Promise> { const result = await connection.getAccountInfo(publicKey) const data = Buffer.from(result.data) const account = parseTokenAccountData(publicKey, data) return { publicKey, account, } } // copied from @solana/spl-token const TOKEN_PROGRAM_ID = new PublicKey( 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' ) function parseTokenAccountData(account: PublicKey, data: Buffer): TokenAccount { const accountInfo = AccountLayout.decode(data) accountInfo.address = account accountInfo.mint = new PublicKey(accountInfo.mint) accountInfo.owner = new PublicKey(accountInfo.owner) accountInfo.amount = u64.fromBuffer(accountInfo.amount) if (accountInfo.delegateOption === 0) { accountInfo.delegate = null accountInfo.delegatedAmount = new u64(0) } else { accountInfo.delegate = new PublicKey(accountInfo.delegate) accountInfo.delegatedAmount = u64.fromBuffer(accountInfo.delegatedAmount) } accountInfo.isInitialized = accountInfo.state !== 0 accountInfo.isFrozen = accountInfo.state === 2 if (accountInfo.isNativeOption === 1) { accountInfo.rentExemptReserve = u64.fromBuffer(accountInfo.isNative) accountInfo.isNative = true } else { accountInfo.rentExemptReserve = null accountInfo.isNative = false } if (accountInfo.closeAuthorityOption === 0) { accountInfo.closeAuthority = null } else { accountInfo.closeAuthority = new PublicKey(accountInfo.closeAuthority) } return accountInfo } function parseMintAccountData(data: Buffer) { const mintInfo = MintLayout.decode(data) if (mintInfo.mintAuthorityOption === 0) { mintInfo.mintAuthority = null } else { mintInfo.mintAuthority = new PublicKey(mintInfo.mintAuthority) } mintInfo.supply = u64.fromBuffer(mintInfo.supply) mintInfo.isInitialized = mintInfo.isInitialized != 0 if (mintInfo.freezeAuthorityOption === 0) { mintInfo.freezeAuthority = null } else { mintInfo.freezeAuthority = new PublicKey(mintInfo.freezeAuthority) } return mintInfo }