Allow use token name in URL along with reserve account's pubkey
This commit is contained in:
parent
7c0401a1fd
commit
ddb2fbca16
|
@ -2,6 +2,8 @@ import { PublicKey } from "@solana/web3.js";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { LendingReserve, LendingReserveParser } from "../models/lending";
|
import { LendingReserve, LendingReserveParser } from "../models/lending";
|
||||||
import { cache, ParsedAccount } from "./../contexts/accounts";
|
import { cache, ParsedAccount } from "./../contexts/accounts";
|
||||||
|
import { useConnectionConfig } from "../contexts/connection";
|
||||||
|
import { getTokenByName, KnownToken } from "../utils/utils";
|
||||||
|
|
||||||
export const getLendingReserves = () => {
|
export const getLendingReserves = () => {
|
||||||
return cache
|
return cache
|
||||||
|
@ -33,7 +35,22 @@ export function useLendingReserves() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useLendingReserve(address?: string | PublicKey) {
|
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<
|
const [reserveAccount, setReserveAccount] = useState<
|
||||||
ParsedAccount<LendingReserve>
|
ParsedAccount<LendingReserve>
|
||||||
>(cache.get(id || "") as ParsedAccount<LendingReserve>);
|
>(cache.get(id || "") as ParsedAccount<LendingReserve>);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from "react";
|
||||||
import { MintInfo } from '@solana/spl-token';
|
import { MintInfo } from "@solana/spl-token";
|
||||||
|
|
||||||
import { PoolInfo, TokenAccount } from './../models';
|
import { PoolInfo, TokenAccount } from "./../models";
|
||||||
import { PublicKey } from '@solana/web3.js';
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import BN from 'bn.js';
|
import BN from "bn.js";
|
||||||
import { WAD, ZERO } from '../constants';
|
import { WAD, ZERO } from "../constants";
|
||||||
|
|
||||||
export interface KnownToken {
|
export interface KnownToken {
|
||||||
tokenSymbol: string;
|
tokenSymbol: string;
|
||||||
|
@ -15,8 +15,8 @@ export interface KnownToken {
|
||||||
|
|
||||||
export type KnownTokenMap = Map<string, KnownToken>;
|
export type KnownTokenMap = Map<string, KnownToken>;
|
||||||
|
|
||||||
export const formatPriceNumber = new Intl.NumberFormat('en-US', {
|
export const formatPriceNumber = new Intl.NumberFormat("en-US", {
|
||||||
style: 'decimal',
|
style: "decimal",
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 8,
|
maximumFractionDigits: 8,
|
||||||
});
|
});
|
||||||
|
@ -55,11 +55,15 @@ export function shortenAddress(address: string, chars = 4): string {
|
||||||
return `${address.slice(0, chars)}...${address.slice(-chars)}`;
|
return `${address.slice(0, chars)}...${address.slice(-chars)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTokenName(map: KnownTokenMap, mint?: string | PublicKey, shorten = true): string {
|
export function getTokenName(
|
||||||
const mintAddress = typeof mint === 'string' ? mint : mint?.toBase58();
|
map: KnownTokenMap,
|
||||||
|
mint?: string | PublicKey,
|
||||||
|
shorten = true
|
||||||
|
): string {
|
||||||
|
const mintAddress = typeof mint === "string" ? mint : mint?.toBase58();
|
||||||
|
|
||||||
if (!mintAddress) {
|
if (!mintAddress) {
|
||||||
return 'N/A';
|
return "N/A";
|
||||||
}
|
}
|
||||||
|
|
||||||
const knownSymbol = map.get(mintAddress)?.tokenSymbol;
|
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;
|
return shorten ? `${mintAddress.substring(0, 5)}...` : mintAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTokenIcon(map: KnownTokenMap, mintAddress?: string | PublicKey): string | undefined {
|
export function getTokenByName(tokens: KnownToken[], name: string) {
|
||||||
const address = typeof mintAddress === 'string' ? mintAddress : mintAddress?.toBase58();
|
let token = null;
|
||||||
|
const nameToToken = tokens.reduce((map, item) => {
|
||||||
|
map.set(item.tokenSymbol, item);
|
||||||
|
return map;
|
||||||
|
}, new Map<string, any>());
|
||||||
|
|
||||||
|
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) {
|
if (!address) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -83,20 +106,25 @@ export function isKnownMint(map: KnownTokenMap, mintAddress: string) {
|
||||||
return !!map.get(mintAddress);
|
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<T>(array: T[], size: number): T[][] {
|
export function chunks<T>(array: T[], size: number): T[][] {
|
||||||
return Array.apply<number, T[], T[][]>(0, new Array(Math.ceil(array.length / size))).map((_, index) =>
|
return Array.apply<number, T[], T[][]>(
|
||||||
array.slice(index * size, (index + 1) * size)
|
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) {
|
if (!account) {
|
||||||
return 0;
|
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);
|
const precision = Math.pow(10, mint?.decimals || 0);
|
||||||
return Math.floor(amount * precision);
|
return Math.floor(amount * precision);
|
||||||
|
@ -106,20 +134,28 @@ export function wadToLamports(amount?: BN): BN {
|
||||||
return amount?.div(WAD) || ZERO;
|
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) {
|
if (!account) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const amount = Math.floor(
|
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);
|
const precision = Math.pow(10, mint?.decimals || 0);
|
||||||
return (amount / precision) * rate;
|
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) => {
|
const abbreviateNumber = (number: number, precision: number) => {
|
||||||
let tier = (Math.log10(number) / 3) | 0;
|
let tier = (Math.log10(number) / 3) | 0;
|
||||||
|
@ -133,20 +169,23 @@ const abbreviateNumber = (number: number, precision: number) => {
|
||||||
return scaled.toFixed(precision) + suffix;
|
return scaled.toFixed(precision) + suffix;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const formatAmount = (val: number, precision: number = 6, abbr: boolean = true) =>
|
export const formatAmount = (
|
||||||
abbr ? abbreviateNumber(val, precision) : val.toFixed(precision);
|
val: number,
|
||||||
|
precision: number = 6,
|
||||||
|
abbr: boolean = true
|
||||||
|
) => (abbr ? abbreviateNumber(val, precision) : val.toFixed(precision));
|
||||||
|
|
||||||
export function formatTokenAmount(
|
export function formatTokenAmount(
|
||||||
account?: TokenAccount,
|
account?: TokenAccount,
|
||||||
mint?: MintInfo,
|
mint?: MintInfo,
|
||||||
rate: number = 1.0,
|
rate: number = 1.0,
|
||||||
prefix = '',
|
prefix = "",
|
||||||
suffix = '',
|
suffix = "",
|
||||||
precision = 6,
|
precision = 6,
|
||||||
abbr = false
|
abbr = false
|
||||||
): string {
|
): string {
|
||||||
if (!account) {
|
if (!account) {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${[prefix]}${formatAmount(
|
return `${[prefix]}${formatAmount(
|
||||||
|
@ -156,13 +195,13 @@ export function formatTokenAmount(
|
||||||
)}${suffix}`;
|
)}${suffix}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const formatUSD = new Intl.NumberFormat('en-US', {
|
export const formatUSD = new Intl.NumberFormat("en-US", {
|
||||||
style: 'currency',
|
style: "currency",
|
||||||
currency: 'USD',
|
currency: "USD",
|
||||||
});
|
});
|
||||||
|
|
||||||
const numberFormater = new Intl.NumberFormat('en-US', {
|
const numberFormater = new Intl.NumberFormat("en-US", {
|
||||||
style: 'decimal',
|
style: "decimal",
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
});
|
});
|
||||||
|
@ -170,25 +209,30 @@ const numberFormater = new Intl.NumberFormat('en-US', {
|
||||||
export const formatNumber = {
|
export const formatNumber = {
|
||||||
format: (val?: number) => {
|
format: (val?: number) => {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
return '--';
|
return "--";
|
||||||
}
|
}
|
||||||
|
|
||||||
return numberFormater.format(val);
|
return numberFormater.format(val);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const formatPct = new Intl.NumberFormat('en-US', {
|
export const formatPct = new Intl.NumberFormat("en-US", {
|
||||||
style: 'percent',
|
style: "percent",
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 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) {
|
if (!account) {
|
||||||
return 0;
|
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);
|
const precision = Math.pow(10, mint?.decimals || 0);
|
||||||
let result = (amount / precision) * rate;
|
let result = (amount / precision) * rate;
|
||||||
|
@ -196,7 +240,11 @@ export function convert(account?: TokenAccount | number, mint?: MintInfo, rate:
|
||||||
return result;
|
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();
|
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("/");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue