mango-web/utils/tokens.tsx

105 lines
2.8 KiB
TypeScript

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<T> = {
publicKey: PublicKey
account: T
}
export async function getOwnedTokenAccounts(
connection: Connection,
publicKey: PublicKey
): Promise<ProgramAccount<TokenAccount>[]> {
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<ProgramAccount<MintAccount>> {
const result = await connection.getAccountInfo(publicKey)
const data = Buffer.from(result.data)
const account = parseMintAccountData(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()
} 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
}