From ddb2fbca1649f99f80b5e08b023243047d6c8f51 Mon Sep 17 00:00:00 2001 From: juan Date: Tue, 19 Jan 2021 13:12:03 -0500 Subject: [PATCH] Allow use token name in URL along with reserve account's pubkey --- src/hooks/useLendingReserves.ts | 19 ++++- src/utils/utils.ts | 126 ++++++++++++++++++++++---------- 2 files changed, 105 insertions(+), 40 deletions(-) diff --git a/src/hooks/useLendingReserves.ts b/src/hooks/useLendingReserves.ts index 897b63d..caf8b7b 100644 --- a/src/hooks/useLendingReserves.ts +++ b/src/hooks/useLendingReserves.ts @@ -2,6 +2,8 @@ import { PublicKey } from "@solana/web3.js"; import { useEffect, useMemo, useState } from "react"; import { LendingReserve, LendingReserveParser } from "../models/lending"; import { cache, ParsedAccount } from "./../contexts/accounts"; +import { useConnectionConfig } from "../contexts/connection"; +import { getTokenByName, KnownToken } from "../utils/utils"; export const getLendingReserves = () => { return cache @@ -33,7 +35,22 @@ export function useLendingReserves() { } export function useLendingReserve(address?: string | PublicKey) { - const id = useMemo(() => typeof address === "string" ? address : address?.toBase58(), [address]); + const { tokens } = useConnectionConfig(); + let addressName = address; + let token: KnownToken; + if (typeof address === "string") { + token = getTokenByName(tokens, address); + if (token) { + addressName = getLendingReserves().filter( + (acc) => acc.info.liquidityMint.toBase58() === token.mintAddress + )[0]?.pubkey; + } + } + const id = useMemo( + () => + typeof addressName === "string" ? addressName : addressName?.toBase58(), + [addressName] + ); const [reserveAccount, setReserveAccount] = useState< ParsedAccount >(cache.get(id || "") as ParsedAccount); diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 29821f3..0b3e6c0 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,10 +1,10 @@ -import { useCallback, useState } from 'react'; -import { MintInfo } from '@solana/spl-token'; +import { useCallback, useState } from "react"; +import { MintInfo } from "@solana/spl-token"; -import { PoolInfo, TokenAccount } from './../models'; -import { PublicKey } from '@solana/web3.js'; -import BN from 'bn.js'; -import { WAD, ZERO } from '../constants'; +import { PoolInfo, TokenAccount } from "./../models"; +import { PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { WAD, ZERO } from "../constants"; export interface KnownToken { tokenSymbol: string; @@ -15,8 +15,8 @@ export interface KnownToken { export type KnownTokenMap = Map; -export const formatPriceNumber = new Intl.NumberFormat('en-US', { - style: 'decimal', +export const formatPriceNumber = new Intl.NumberFormat("en-US", { + style: "decimal", minimumFractionDigits: 2, maximumFractionDigits: 8, }); @@ -55,11 +55,15 @@ export function shortenAddress(address: string, chars = 4): string { return `${address.slice(0, chars)}...${address.slice(-chars)}`; } -export function getTokenName(map: KnownTokenMap, mint?: string | PublicKey, shorten = true): string { - const mintAddress = typeof mint === 'string' ? mint : mint?.toBase58(); +export function getTokenName( + map: KnownTokenMap, + mint?: string | PublicKey, + shorten = true +): string { + const mintAddress = typeof mint === "string" ? mint : mint?.toBase58(); if (!mintAddress) { - return 'N/A'; + return "N/A"; } const knownSymbol = map.get(mintAddress)?.tokenSymbol; @@ -70,8 +74,27 @@ export function getTokenName(map: KnownTokenMap, mint?: string | PublicKey, shor return shorten ? `${mintAddress.substring(0, 5)}...` : mintAddress; } -export function getTokenIcon(map: KnownTokenMap, mintAddress?: string | PublicKey): string | undefined { - const address = typeof mintAddress === 'string' ? mintAddress : mintAddress?.toBase58(); +export function getTokenByName(tokens: KnownToken[], name: string) { + let token = null; + const nameToToken = tokens.reduce((map, item) => { + map.set(item.tokenSymbol, item); + return map; + }, new Map()); + + if (name) { + if (nameToToken.has(name)) { + token = nameToToken.get(name); + } + } + return token; +} + +export function getTokenIcon( + map: KnownTokenMap, + mintAddress?: string | PublicKey +): string | undefined { + const address = + typeof mintAddress === "string" ? mintAddress : mintAddress?.toBase58(); if (!address) { return; } @@ -83,20 +106,25 @@ export function isKnownMint(map: KnownTokenMap, mintAddress: string) { return !!map.get(mintAddress); } -export const STABLE_COINS = new Set(['USDC', 'wUSDC', 'USDT']); +export const STABLE_COINS = new Set(["USDC", "wUSDC", "USDT"]); export function chunks(array: T[], size: number): T[][] { - return Array.apply(0, new Array(Math.ceil(array.length / size))).map((_, index) => - array.slice(index * size, (index + 1) * size) - ); + return Array.apply( + 0, + new Array(Math.ceil(array.length / size)) + ).map((_, index) => array.slice(index * size, (index + 1) * size)); } -export function toLamports(account?: TokenAccount | number, mint?: MintInfo): number { +export function toLamports( + account?: TokenAccount | number, + mint?: MintInfo +): number { if (!account) { return 0; } - const amount = typeof account === 'number' ? account : account.info.amount?.toNumber(); + const amount = + typeof account === "number" ? account : account.info.amount?.toNumber(); const precision = Math.pow(10, mint?.decimals || 0); return Math.floor(amount * precision); @@ -106,20 +134,28 @@ export function wadToLamports(amount?: BN): BN { return amount?.div(WAD) || ZERO; } -export function fromLamports(account?: TokenAccount | number | BN, mint?: MintInfo, rate: number = 1.0): number { +export function fromLamports( + account?: TokenAccount | number | BN, + mint?: MintInfo, + rate: number = 1.0 +): number { if (!account) { return 0; } const amount = Math.floor( - typeof account === 'number' ? account : BN.isBN(account) ? account.toNumber() : account.info.amount.toNumber() + typeof account === "number" + ? account + : BN.isBN(account) + ? account.toNumber() + : account.info.amount.toNumber() ); const precision = Math.pow(10, mint?.decimals || 0); return (amount / precision) * rate; } -var SI_SYMBOL = ['', 'k', 'M', 'G', 'T', 'P', 'E']; +var SI_SYMBOL = ["", "k", "M", "G", "T", "P", "E"]; const abbreviateNumber = (number: number, precision: number) => { let tier = (Math.log10(number) / 3) | 0; @@ -133,20 +169,23 @@ const abbreviateNumber = (number: number, precision: number) => { return scaled.toFixed(precision) + suffix; }; -export const formatAmount = (val: number, precision: number = 6, abbr: boolean = true) => - abbr ? abbreviateNumber(val, precision) : val.toFixed(precision); +export const formatAmount = ( + val: number, + precision: number = 6, + abbr: boolean = true +) => (abbr ? abbreviateNumber(val, precision) : val.toFixed(precision)); export function formatTokenAmount( account?: TokenAccount, mint?: MintInfo, rate: number = 1.0, - prefix = '', - suffix = '', + prefix = "", + suffix = "", precision = 6, abbr = false ): string { if (!account) { - return ''; + return ""; } return `${[prefix]}${formatAmount( @@ -156,13 +195,13 @@ export function formatTokenAmount( )}${suffix}`; } -export const formatUSD = new Intl.NumberFormat('en-US', { - style: 'currency', - currency: 'USD', +export const formatUSD = new Intl.NumberFormat("en-US", { + style: "currency", + currency: "USD", }); -const numberFormater = new Intl.NumberFormat('en-US', { - style: 'decimal', +const numberFormater = new Intl.NumberFormat("en-US", { + style: "decimal", minimumFractionDigits: 2, maximumFractionDigits: 2, }); @@ -170,25 +209,30 @@ const numberFormater = new Intl.NumberFormat('en-US', { export const formatNumber = { format: (val?: number) => { if (!val) { - return '--'; + return "--"; } return numberFormater.format(val); }, }; -export const formatPct = new Intl.NumberFormat('en-US', { - style: 'percent', +export const formatPct = new Intl.NumberFormat("en-US", { + style: "percent", minimumFractionDigits: 2, maximumFractionDigits: 2, }); -export function convert(account?: TokenAccount | number, mint?: MintInfo, rate: number = 1.0): number { +export function convert( + account?: TokenAccount | number, + mint?: MintInfo, + rate: number = 1.0 +): number { if (!account) { return 0; } - const amount = typeof account === 'number' ? account : account.info.amount?.toNumber(); + const amount = + typeof account === "number" ? account : account.info.amount?.toNumber(); const precision = Math.pow(10, mint?.decimals || 0); let result = (amount / precision) * rate; @@ -196,7 +240,11 @@ export function convert(account?: TokenAccount | number, mint?: MintInfo, rate: return result; } -export function getPoolName(map: KnownTokenMap, pool: PoolInfo, shorten = true) { +export function getPoolName( + map: KnownTokenMap, + pool: PoolInfo, + shorten = true +) { const sorted = pool.pubkeys.holdingMints.map((a) => a.toBase58()).sort(); - return sorted.map((item) => getTokenName(map, item, shorten)).join('/'); + return sorted.map((item) => getTokenName(map, item, shorten)).join("/"); }