cleanup token handling code
This commit is contained in:
parent
37b3c9d627
commit
6ad0e4eb16
|
@ -5,7 +5,7 @@ import useWalletStore from '../stores/useWalletStore'
|
|||
const Balances = () => {
|
||||
var { tokenAccounts, mints } = useWalletStore((state) => state)
|
||||
|
||||
function fixedPointNumber(value, decimals) {
|
||||
function fixedPointToNumber(value: BN, decimals: number) {
|
||||
const divisor = new BN(10).pow(new BN(decimals))
|
||||
const quotient = value.div(divisor)
|
||||
const remainder = value.mod(divisor)
|
||||
|
@ -14,7 +14,7 @@ const Balances = () => {
|
|||
|
||||
function calculateBalance(a) {
|
||||
const mint = mints[a.account.mint.toBase58()]
|
||||
return mint ? fixedPointNumber(a.account.amount, mint.decimals) : 0
|
||||
return mint ? fixedPointToNumber(a.account.amount, mint.decimals) : 0
|
||||
}
|
||||
|
||||
const displayedBalances = tokenAccounts
|
139
utils/tokens.tsx
139
utils/tokens.tsx
|
@ -1,6 +1,11 @@
|
|||
import * as bs58 from 'bs58'
|
||||
import { Connection, ParsedAccountData, PublicKey } from '@solana/web3.js'
|
||||
import { AccountLayout, AccountInfo, MintInfo, u64 } from '@solana/spl-token'
|
||||
import {
|
||||
AccountInfo,
|
||||
AccountLayout,
|
||||
MintInfo,
|
||||
MintLayout,
|
||||
u64,
|
||||
} from '@solana/spl-token'
|
||||
|
||||
export type TokenAccount = AccountInfo
|
||||
export type MintAccount = MintInfo
|
||||
|
@ -9,77 +14,91 @@ export type ProgramAccount<T> = {
|
|||
account: T
|
||||
}
|
||||
|
||||
export const TOKEN_PROGRAM_ID = new PublicKey(
|
||||
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
|
||||
)
|
||||
|
||||
export function parseTokenAccountData(
|
||||
data: Buffer
|
||||
): { mint: PublicKey; owner: PublicKey; amount: u64 } {
|
||||
const { mint, owner, amount } = AccountLayout.decode(data)
|
||||
return {
|
||||
mint: new PublicKey(mint),
|
||||
owner: new PublicKey(owner),
|
||||
amount: u64.fromBuffer(amount),
|
||||
}
|
||||
}
|
||||
|
||||
export async function getOwnedTokenAccounts(
|
||||
connection: Connection,
|
||||
publicKey: PublicKey
|
||||
): Promise<ProgramAccount<TokenAccount>[]> {
|
||||
const filters = getOwnedAccountsFilters(publicKey)
|
||||
// @ts-ignore
|
||||
const resp = await connection._rpcRequest('getProgramAccounts', [
|
||||
TOKEN_PROGRAM_ID.toBase58(),
|
||||
{
|
||||
commitment: connection.commitment,
|
||||
filters,
|
||||
},
|
||||
])
|
||||
if (resp.error) {
|
||||
throw new Error(
|
||||
'failed to get token accounts owned by ' +
|
||||
publicKey.toBase58() +
|
||||
': ' +
|
||||
resp.error.message
|
||||
)
|
||||
}
|
||||
return resp.result.map(({ pubkey, account: { data } }) => {
|
||||
data = bs58.decode(data)
|
||||
return {
|
||||
publicKey: new PublicKey(pubkey),
|
||||
account: parseTokenAccountData(data),
|
||||
}
|
||||
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 function getOwnedAccountsFilters(publicKey: PublicKey) {
|
||||
return [
|
||||
{
|
||||
memcmp: {
|
||||
offset: AccountLayout.offsetOf('owner'),
|
||||
bytes: publicKey.toBase58(),
|
||||
},
|
||||
},
|
||||
{
|
||||
dataSize: AccountLayout.span,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export async function getMint(
|
||||
connection: Connection,
|
||||
publicKey: PublicKey
|
||||
): Promise<ProgramAccount<MintAccount>> {
|
||||
const result = await connection.getParsedAccountInfo(publicKey)
|
||||
const account = (result.value.data as ParsedAccountData).parsed.info
|
||||
account.freezeAuthority =
|
||||
account.freezeAuthority && new PublicKey(account.freezeAuthority)
|
||||
account.mintAuthority =
|
||||
account.mintAuthority && new PublicKey(account.mintAuthority)
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue