Skip to content

Commit

Permalink
Merge pull request #294 from nifty-oss/febo/nifty-asset
Browse files Browse the repository at this point in the history
Add nifty asset pages
  • Loading branch information
0xIchigo authored Apr 16, 2024
2 parents 6a231ca + e25de44 commit 967f689
Show file tree
Hide file tree
Showing 11 changed files with 1,213 additions and 11 deletions.
72 changes: 72 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"dependencies": {
"@coral-xyz/anchor": "^0.29.0",
"@lottiefiles/svelte-lottie-player": "^0.3.0",
"@nifty-oss/asset": "^0.3.0",
"@onsol/tldparser": "^0.5.3",
"@solana/spl-account-compression": "^0.1.8",
"@solana/spl-token-registry": "^0.2.4574",
Expand Down
98 changes: 98 additions & 0 deletions src/lib/components/providers/nifty-asset-provider.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<script lang="ts">
import type { UINiftyAsset, UITokenMetadata } from "$lib/types";
import { SOL } from "$lib/xray";
import { page } from "$app/stores";
import { trpcWithQuery } from "$lib/trpc/client";
import IntersectionObserver from "svelte-intersection-observer";
import { ExtensionType, getExtension } from "@nifty-oss/asset";
export let address: string | undefined = undefined;
export let asset: UINiftyAsset | undefined = undefined;
export let status: { isLoading: boolean; isError: boolean } = {
isError: false,
isLoading: true,
};
let intersecting = false;
const params = new URLSearchParams(window.location.search);
const network = params.get("network");
const isMainnetValue = network !== "devnet";
const client = trpcWithQuery($page);
let account: any | undefined;
if (address) {
account = client.niftyAsset.createQuery([address, isMainnetValue], {
refetchOnMount: false,
refetchOnWindowFocus: false,
});
}
$: if ($account && $account.data) {
status = { isError: $account.isError, isLoading: $account.isLoading };
updateAsset($account.data[0]);
}
const updateAsset = (data: UINiftyAsset) => {
asset = data;
if (asset) {
const metadata = getExtension(asset, ExtensionType.Metadata);
if (metadata && metadata.uri) {
(async () => {
try {
asset.json = await fetchJsonMetadata(metadata.uri);
} catch (error) {
// eslint-disable-next-line no-console
console.error("Error in fetchJsonMetadata:", error);
}
})();
}
}
};
const fetchJsonMetadata = async (jsonUri: string) => {
try {
const response = await fetch(jsonUri);
if (!response.ok) {
throw new Error(`Status ${response.status}`);
}
const contentType = response.headers.get("content-type");
if (!contentType || !contentType.includes("application/json")) {
throw new TypeError("Received non-JSON content type");
}
return await response.json();
} catch (error) {
// eslint-disable-next-line no-console
console.error("Error fetching or parsing JSON metadata:", error);
return "";
}
};
let element: HTMLDivElement;
$: loading = address !== SOL && status.isLoading;
$: failed = status.isError;
</script>

<div>
<IntersectionObserver
once={true}
{element}
bind:intersecting
>
<div bind:this={element} />

{#if intersecting}
<slot
{asset}
{loading}
{failed}
/>
{/if}
</IntersectionObserver>
</div>
2 changes: 2 additions & 0 deletions src/lib/trpc/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { balances } from "$lib/trpc/routes/balances";
import { concurrentMerkleTree } from "$lib/trpc/routes/concurrent-merkle-tree";
import { currentSlot } from "$lib/trpc/routes/current-slot";
import { deprecatedImage } from "./routes/deprecated-image";
import { niftyAsset } from "$lib/trpc/routes/nifty-asset";
import { price } from "$lib/trpc/routes/price";
import { rawTransaction } from "$lib/trpc/routes/raw-transaction";
import { searchAssets } from "./routes/search-assets";
Expand All @@ -33,6 +34,7 @@ export const router = t.router({
concurrentMerkleTree,
currentSlot,
deprecatedImage,
niftyAsset,
price,
rawTransaction,
searchAssets,
Expand Down
32 changes: 32 additions & 0 deletions src/lib/trpc/routes/nifty-asset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { z } from "zod";

import { t } from "$lib/trpc/t";

import { connect } from "$lib/xray";
import { LAMPORTS_PER_SOL, PublicKey, Connection } from "@solana/web3.js";
import { getRPCUrl } from "$lib/util/get-rpc-url";

import { HELIUS_API_KEY } from "$env/static/private";
import { getAssetAccountDataSerializer } from "@nifty-oss/asset";

export const niftyAsset = t.procedure
.input(z.tuple([z.string(), z.boolean()]))
.query(async ({ input }) => {
const [address, isMainnet] = input;
const connection = new Connection(
getRPCUrl(`?api-key=${HELIUS_API_KEY}`, isMainnet),
"confirmed"
);

const pubKey = new PublicKey(address);

const accountInfo = await connection.getAccountInfo(pubKey);

if (accountInfo) {
return getAssetAccountDataSerializer().deserialize(
accountInfo.data
);
}

return null;
});
6 changes: 6 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import type { EnrichedTransaction } from "helius-sdk";
import type { ProtonTransaction, ProtonTransactionAction } from "$lib/xray";

import type { IconPaths, modals } from "$lib/config";

import type { SOL } from "$lib/xray";

import type { Asset } from "@nifty-oss/asset";

export * from "$lib/config";

export interface UIConfig {
Expand Down Expand Up @@ -143,3 +146,6 @@ export type UISolAccountToken = {
balanceInUSD: number;
price: number;
};

/** Used in the Nifty Asset pages. */
export type UINiftyAsset = Asset & { json: any };
4 changes: 4 additions & 0 deletions src/lib/util/stores/nifty-asset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { UINiftyAsset } from "$lib/types";
import { writable } from "svelte/store";

export const niftyAssetStore = writable<UINiftyAsset | null>(null);
23 changes: 14 additions & 9 deletions src/lib/xray/lib/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { TldParser } from "@onsol/tldparser";
import { browser } from "$app/environment";

import getJupiterTokens from "$lib/util/get-tokens";
import { ASSET_PROGRAM_ID } from "@nifty-oss/asset";

export interface SearchResult {
url: string;
Expand All @@ -23,6 +24,7 @@ type SearchResultType =
| "transaction"
| "bonfida-domain"
| "ans-domain"
| "nifty-asset"
| null;

const searchDefaults: SearchResult = {
Expand Down Expand Up @@ -60,16 +62,19 @@ export const search = async (
const pubkey = new PublicKey(query);
const account = await connection.getAccountInfo(pubkey);
const program = account?.owner.toString();

const probablyToken =
program === "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" ||
program === "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" ||
account === null;

let addressType!: "token" | "account";
if (probablyToken) {
addressType = "token";
let addressType!: "token" | "account" | "nifty-asset";

if (account) {
if (
program === "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" ||
program === "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
) {
addressType = "token";
} else if (program === ASSET_PROGRAM_ID) {
addressType = "nifty-asset";
}
}

addressType ??= "account";

return {
Expand Down
6 changes: 4 additions & 2 deletions src/routes/account/[account]/assets/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,17 @@

{#if asset.burnt !== true}
<a
href="/token/{asset.id}?network={isMainnetValue ? 'mainnet' : 'devnet'}"
href="/token/{asset.id}?network={isMainnetValue
? 'mainnet'
: 'devnet'}"
>
<Image
src={image?.uri}
className="aspect-square w-full rounded-lg"
alt=""
/>
</a>
{/if}
{/if}
{/each}
{/each}
</div>
Expand Down
Loading

0 comments on commit 967f689

Please sign in to comment.