Skip to content

Commit

Permalink
Merge pull request #272 from helius-labs/feat/add-idls
Browse files Browse the repository at this point in the history
[Feat] Implement IDL Fetch
  • Loading branch information
0xIchigo committed Jan 9, 2024
2 parents 809636b + ba814e1 commit 18a4a44
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 8 deletions.
150 changes: 147 additions & 3 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 @@ -78,6 +78,7 @@
"vite": "^4.3.9"
},
"dependencies": {
"@coral-xyz/anchor": "^0.29.0",
"@lottiefiles/svelte-lottie-player": "^0.3.0",
"@onsol/tldparser": "^0.5.3",
"@solana/spl-account-compression": "^0.1.8",
Expand Down
56 changes: 56 additions & 0 deletions src/lib/util/grab-idl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
PublicKey,
Keypair,
Connection,
Transaction,
VersionedTransaction,
} from "@solana/web3.js";
import { AnchorProvider, Program, type Idl } from "@coral-xyz/anchor";
import { getRPCUrl } from "./get-rpc-url";
import { idlStore } from "./stores/idl";

type DummyTransaction = { dummy: true };

// Function to fetch IDL and update the store
export async function grabIdl(
accountAddress: string,
isMainnetValue: boolean,
apiKey: string
) {
try {
const connection = new Connection(
getRPCUrl(`?api-key=${apiKey}`, isMainnetValue),
"confirmed"
);

// In the future, look into ambiguous export errors for Anchor's Wallet class
// For now, we create a dummy wallet and use it with the provider
// This is enough since we aren't actually using the wallet to sign anything
const dummyKeypair = Keypair.generate();
const dummyWallet = {
publicKey: dummyKeypair.publicKey,
signAllTransactions: <T extends Transaction | VersionedTransaction>(
txs: T[]
): Promise<T[]> => Promise.resolve(txs),
signTransaction: <T extends Transaction | VersionedTransaction>(
tx: T
): Promise<T> => Promise.resolve(tx),
};

const provider = new AnchorProvider(
connection,
dummyWallet,
AnchorProvider.defaultOptions()
);

const accountPubkey = new PublicKey(accountAddress);
const idl = (await Program.fetchIdl(
accountPubkey,
provider
)) as Idl | null;

return idl;
} catch (error) {
return null;
}
}
4 changes: 4 additions & 0 deletions src/lib/util/stores/idl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { writable } from "svelte/store";
import type { Idl } from "@coral-xyz/anchor";

export const idlStore = writable<Idl | null>(null);
47 changes: 44 additions & 3 deletions src/routes/account/[account]/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<script lang="ts">
import { page } from "$app/stores";
// @ts-ignore
import { idlStore } from "$lib/util/stores/idl";
import type { Idl } from "@coral-xyz/anchor";
import Icon from "$lib/components/icon.svelte";
import { PROGRAM_ID as ACCOUNT_COMPRESSION_ID } from "@solana/spl-account-compression";
import Icon from "$lib/components/icon.svelte";
import AccountHeader from "$lib/components/account-header.svelte";
import { showModal } from "$lib/state/stores/modals";
import { trpcWithQuery } from "$lib/trpc/client";
import { PROGRAM_ID as ACCOUNT_COMPRESSION_ID } from "@solana/spl-account-compression";
import { onMount, onDestroy } from "svelte";
const client = trpcWithQuery($page);
Expand All @@ -27,6 +31,36 @@
$: endsWith = (str: string) => $page.url.pathname.endsWith(str);
$: hasAssets = $assets?.data?.total > 0;
let programIDL: Idl | null = null;
const unsubscribe = idlStore.subscribe((value) => {
programIDL = value;
});
onMount(async () => {
const response = await fetch(
`/api/fetchIdl?account=${account}&isMainnetValue=${isMainnetValue}`
);
if (response.ok) {
const data = await response.json();
if (data.idl) {
idlStore.set(data.idl);
} else {
// eslint-disable-next-line no-console
console.error("IDL not found for the provided account");
}
} else {
// eslint-disable-next-line no-console
console.error(`Failed to fetch IDL: ${response.status}`);
}
});
onDestroy(() => {
unsubscribe();
});
</script>

<div class="relative mx-auto w-full max-w-2xl pb-32">
Expand Down Expand Up @@ -66,8 +100,15 @@
>Concurrent Merkle Tree
</a>
{/if}
{#if programIDL}
<a
href={`/account/${account}/idl?${selectedNetwork}`}
class="tab-bordered tab"
class:tab-active={endsWith("/idl")}>IDL</a
>
{/if}
</div>
{#if !endsWith("/tokens") && !endsWith("/assets")}
{#if !endsWith("/tokens") && !endsWith("/assets") && !endsWith("/idl")}
<button
class="btn-ghost btn-sm btn"
on:click={() => showModal("TRANSACTION_FILTER")}
Expand Down
3 changes: 1 addition & 2 deletions src/routes/account/[account]/assets/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
$assets.data?.pages[$assets.data.pages.length - 1].total > 0;
$: isOnePage = $assets.data?.pages.length == 1;
</script>

<div class="grid grid-cols-3 gap-3 md:grid-cols-5">
Expand All @@ -57,7 +56,7 @@
{/each}
</div>

{#if $assets.hasNextPage && lastPageHadAssets &&!isOnePage}
{#if $assets.hasNextPage && lastPageHadAssets && !isOnePage}
<div class="flex justify-center">
<button
class="btn-outline btn"
Expand Down
Loading

0 comments on commit 18a4a44

Please sign in to comment.