fetch mints and correctly display decimals
This commit is contained in:
parent
c362ebf233
commit
37b3c9d627
|
@ -0,0 +1,33 @@
|
|||
import BN from 'bn.js'
|
||||
|
||||
import useWalletStore from '../stores/useWalletStore'
|
||||
|
||||
const Balances = () => {
|
||||
var { tokenAccounts, mints } = useWalletStore((state) => state)
|
||||
|
||||
function fixedPointNumber(value, decimals) {
|
||||
const divisor = new BN(10).pow(new BN(decimals))
|
||||
const quotient = value.div(divisor)
|
||||
const remainder = value.mod(divisor)
|
||||
return quotient.toNumber() + remainder.toNumber() / divisor.toNumber()
|
||||
}
|
||||
|
||||
function calculateBalance(a) {
|
||||
const mint = mints[a.account.mint.toBase58()]
|
||||
return mint ? fixedPointNumber(a.account.amount, mint.decimals) : 0
|
||||
}
|
||||
|
||||
const displayedBalances = tokenAccounts
|
||||
.map((a) => `${a.publicKey.toBase58()}: ${calculateBalance(a)}`)
|
||||
.sort()
|
||||
|
||||
return (
|
||||
<ul>
|
||||
{displayedBalances.map((b, i) => (
|
||||
<li key={i}>{b}</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
export default Balances
|
|
@ -19,8 +19,6 @@ const NotificationList = () => {
|
|||
})
|
||||
}, 5000)
|
||||
|
||||
console.log('notifications', notifications)
|
||||
|
||||
return () => {
|
||||
clearInterval(id)
|
||||
}
|
||||
|
|
|
@ -104,12 +104,14 @@ export default function useWallet() {
|
|||
'...' +
|
||||
wallet.publicKey.toString().substr(-5),
|
||||
})
|
||||
actions.fetchWalletBalances()
|
||||
await actions.fetchWalletTokenAccounts()
|
||||
await actions.fetchWalletMints()
|
||||
})
|
||||
wallet.on('disconnect', () => {
|
||||
setWalletStore((state) => {
|
||||
state.connected = false
|
||||
state.balances = []
|
||||
state.tokenAccounts = []
|
||||
state.mints = {}
|
||||
})
|
||||
notify({
|
||||
type: 'info',
|
||||
|
@ -126,8 +128,9 @@ export default function useWallet() {
|
|||
}
|
||||
}, [wallet, setWalletStore])
|
||||
|
||||
useInterval(() => {
|
||||
actions.fetchWalletBalances()
|
||||
useInterval(async () => {
|
||||
await actions.fetchWalletTokenAccounts()
|
||||
await actions.fetchWalletMints()
|
||||
}, 20 * SECONDS)
|
||||
|
||||
return { connected, wallet }
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import Notifications from '../components/Notification'
|
||||
import Balances from '../components/Balances'
|
||||
import TopBar from '../components/TopBar'
|
||||
|
||||
const Index = () => {
|
||||
return (
|
||||
<div className={`bg-th-bkg-1 text-th-fgd-1 transition-all `}>
|
||||
<TopBar />
|
||||
<Balances />
|
||||
<Notifications />
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -3,7 +3,13 @@ import produce from 'immer'
|
|||
import { Connection, PublicKey } from '@solana/web3.js'
|
||||
|
||||
import { EndpointInfo, WalletAdapter } from '../@types/types'
|
||||
import { getOwnedTokenAccounts } from '../utils/tokens'
|
||||
import {
|
||||
getOwnedTokenAccounts,
|
||||
getMint,
|
||||
ProgramAccount,
|
||||
TokenAccount,
|
||||
MintAccount,
|
||||
} from '../utils/tokens'
|
||||
|
||||
export const ENDPOINTS: EndpointInfo[] = [
|
||||
{
|
||||
|
@ -33,7 +39,8 @@ interface WalletStore extends State {
|
|||
}
|
||||
current: WalletAdapter | undefined
|
||||
providerUrl: string
|
||||
balances: Array<{ account: any; publicKey: PublicKey }>
|
||||
tokenAccounts: ProgramAccount<TokenAccount>[]
|
||||
mints: { [pubkey: string]: MintAccount }
|
||||
set: (x: any) => void
|
||||
actions: any
|
||||
}
|
||||
|
@ -48,9 +55,10 @@ const useWalletStore = create<WalletStore>((set, get) => ({
|
|||
},
|
||||
current: null,
|
||||
providerUrl: null,
|
||||
balances: [],
|
||||
tokenAccounts: [],
|
||||
mints: {},
|
||||
actions: {
|
||||
async fetchWalletBalances() {
|
||||
async fetchWalletTokenAccounts() {
|
||||
const connection = get().connection.current
|
||||
const connected = get().connected
|
||||
const wallet = get().current
|
||||
|
@ -63,14 +71,39 @@ const useWalletStore = create<WalletStore>((set, get) => ({
|
|||
walletOwner
|
||||
)
|
||||
|
||||
console.log('fetched wallet balances', ownedTokenAccounts)
|
||||
|
||||
set((state) => {
|
||||
state.balances = ownedTokenAccounts
|
||||
state.tokenAccounts = ownedTokenAccounts
|
||||
})
|
||||
} else {
|
||||
set((state) => {
|
||||
state.balances = []
|
||||
state.tokenAccounts = []
|
||||
})
|
||||
}
|
||||
},
|
||||
async fetchWalletMints() {
|
||||
const connection = get().connection.current
|
||||
const connected = get().connected
|
||||
const tokenAccounts = get().tokenAccounts
|
||||
const mints = get().mints
|
||||
const set = get().set
|
||||
|
||||
if (connected) {
|
||||
var fetchMints = tokenAccounts.map((a) =>
|
||||
getMint(connection, a.account.mint)
|
||||
)
|
||||
const mintResults = await Promise.all(fetchMints)
|
||||
|
||||
const newMints: { [pubkey: string]: MintAccount } = {}
|
||||
mintResults.forEach(
|
||||
(m) => (newMints[m.publicKey.toBase58()] = m.account)
|
||||
)
|
||||
|
||||
set((state) => {
|
||||
state.mints = newMints
|
||||
})
|
||||
} else {
|
||||
set((state) => {
|
||||
state.mints = {}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,27 +1,26 @@
|
|||
import { Connection, PublicKey } from '@solana/web3.js'
|
||||
import * as bs58 from 'bs58'
|
||||
import {
|
||||
AccountLayout as TokenLayout,
|
||||
AccountInfo as TokenAccount,
|
||||
} from '@solana/spl-token'
|
||||
|
||||
export const TOKEN_PROGRAM_ID = new PublicKey(
|
||||
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
|
||||
)
|
||||
import { Connection, ParsedAccountData, PublicKey } from '@solana/web3.js'
|
||||
import { AccountLayout, AccountInfo, MintInfo, u64 } from '@solana/spl-token'
|
||||
|
||||
export type TokenAccount = AccountInfo
|
||||
export type MintAccount = MintInfo
|
||||
export type ProgramAccount<T> = {
|
||||
publicKey: PublicKey
|
||||
account: T
|
||||
}
|
||||
|
||||
export const TOKEN_PROGRAM_ID = new PublicKey(
|
||||
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
|
||||
)
|
||||
|
||||
export function parseTokenAccountData(
|
||||
data: Buffer
|
||||
): { mint: PublicKey; owner: PublicKey; amount: number } {
|
||||
const { mint, owner, amount } = TokenLayout.decode(data)
|
||||
): { mint: PublicKey; owner: PublicKey; amount: u64 } {
|
||||
const { mint, owner, amount } = AccountLayout.decode(data)
|
||||
return {
|
||||
mint: new PublicKey(mint),
|
||||
owner: new PublicKey(owner),
|
||||
amount,
|
||||
amount: u64.fromBuffer(amount),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,12 +58,28 @@ export function getOwnedAccountsFilters(publicKey: PublicKey) {
|
|||
return [
|
||||
{
|
||||
memcmp: {
|
||||
offset: TokenLayout.offsetOf('owner'),
|
||||
offset: AccountLayout.offsetOf('owner'),
|
||||
bytes: publicKey.toBase58(),
|
||||
},
|
||||
},
|
||||
{
|
||||
dataSize: TokenLayout.span,
|
||||
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)
|
||||
return {
|
||||
publicKey,
|
||||
account,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue