diff --git a/src/lib/components/modals/help.svelte b/src/lib/components/modals/help.svelte index e6cd6ba5..2b7ce24e 100644 --- a/src/lib/components/modals/help.svelte +++ b/src/lib/components/modals/help.svelte @@ -5,11 +5,12 @@ ["globe", ".sol, .abc, .poor, .bonk domains"], ["person", "Wallet/Account addresses"], ["coins", "Token addresses"], + ["dots", "Token symbols (case sensitive)"], ["lightning", "Transaction signatures"], ]; -

Use the search bar to look up any of the following.

+

Use the search bar to look up any of the following:

Supported Searches diff --git a/src/lib/types.ts b/src/lib/types.ts index 0c278405..472b3c1b 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -107,3 +107,19 @@ export interface Modal { export type Modals = keyof typeof modals; export type NullableProp = T | null | undefined; + +export interface JupiterToken { + name: string; + symbol: string; + address: string; + decimals: number; + logoURI: string; +} + +export interface TokenMap { + [symbol: string]: string; +} + +export type RecognizedTokens = { + [key: string]: string; +}; diff --git a/src/lib/util/get-tokens.ts b/src/lib/util/get-tokens.ts new file mode 100644 index 00000000..a2369435 --- /dev/null +++ b/src/lib/util/get-tokens.ts @@ -0,0 +1,33 @@ +import type { JupiterToken, TokenMap } from "$lib/types"; +import { recognizedTokens } from "./recognized-tokens"; + +const getJupiterTokens = async (): Promise => { + try { + const data = await fetch(`https://token.jup.ag/all`); + const jsonData = await data.json(); + + if (!Array.isArray(jsonData)) { + throw new Error("Unexpected data format from Jupiter API"); + } + + const tokens: JupiterToken[] = jsonData as JupiterToken[]; + const tokenMap = tokens.reduce((acc: TokenMap, token: JupiterToken) => { + if ( + (recognizedTokens[token.symbol] && + recognizedTokens[token.symbol] === token.address) || + !recognizedTokens[token.symbol] + ) { + acc[token.symbol] = token.address; + } + return acc; + }, {}); + + return tokenMap; + } catch (error: any) { + throw new Error( + `Failed to fetch tokens from Jupiter with error: ${error}` + ); + } +}; + +export default getJupiterTokens; diff --git a/src/lib/util/recognized-tokens.ts b/src/lib/util/recognized-tokens.ts new file mode 100644 index 00000000..26995290 --- /dev/null +++ b/src/lib/util/recognized-tokens.ts @@ -0,0 +1,6 @@ +import type { RecognizedTokens } from "$lib/types"; + +export const recognizedTokens: RecognizedTokens = { + FOXY: "FoXyMu5xwXre7zEoSvzViRk3nGawHUp9kUh97y2NDhcq", + USDC: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", +}; diff --git a/src/lib/xray/lib/search.ts b/src/lib/xray/lib/search.ts index 94b343a8..108740b2 100644 --- a/src/lib/xray/lib/search.ts +++ b/src/lib/xray/lib/search.ts @@ -7,6 +7,8 @@ import { PublicKey } from "@solana/web3.js"; import { TldParser } from "@onsol/tldparser"; import { browser } from "$app/environment"; +import getJupiterTokens from "$lib/util/get-tokens"; + export interface SearchResult { url: string; address: string; @@ -52,6 +54,9 @@ export const search = async ( } const isMainnetValue = network !== "devnet"; + // For token symbols + const tokenSymbols = await getJupiterTokens(); + if (isValidPublicKey(query)) { const pubkey = new PublicKey(query); const account = await connection.getParsedAccountInfo(pubkey); @@ -118,6 +123,14 @@ export const search = async ( url: `/account/${owner}`, valid: true, }; + } else if (Object.keys(tokenSymbols).find((key) => key === query)) { + return { + address: tokenSymbols[query], + search: query, + type: "token", + url: `/token/${tokenSymbols[query]}`, + valid: true, + }; } return searchDefaults;