| null = useMemo(() => {
+ if (!idl) return null;
+ try {
+ return new Program(idl, new PublicKey(programAddress), getProvider(url));
+ } catch (e) {
+ return null;
+ }
+ }, [idl, programAddress, url]);
+ return { idl, program };
+}
+
export type AnchorAccount = {
layout: string;
account: object;
diff --git a/app/providers/compressed-nft.tsx b/app/providers/compressed-nft.tsx
index db584847..7405926f 100644
--- a/app/providers/compressed-nft.tsx
+++ b/app/providers/compressed-nft.tsx
@@ -1,60 +1,14 @@
-type CacheType = Record<
- string,
- void | { __type: 'promise'; promise: Promise } | { __type: 'result'; result: P }
->;
+import useSWRImmutable from 'swr/immutable';
-const cachedNftPromises: CacheType = {};
-
-const cachedPromises = {
- compressedNft: {} as CacheType,
- compressedNftProof: {} as CacheType,
- nftMetadataJson: {} as CacheType,
-};
-
-function makeCache(
- cacheName: keyof typeof cachedPromises,
- keygen: (params: Params) => string,
- action: (params: Params) => Promise
-): (params: Params) => CacheValueType {
- return (params: Params) => {
- const key = keygen(params);
- const cacheEntry = cachedPromises[cacheName][key];
-
- if (cacheEntry === undefined) {
- const promise = action(params)
- .then((value: CacheValueType) => {
- cachedPromises[cacheName][key] = {
- __type: 'result',
- result: value,
- };
- })
- .catch(_ => {
- cachedNftPromises[key] = { __type: 'result', result: null };
- });
- cachedPromises[cacheName][key] = {
- __type: 'promise',
- promise,
- };
- throw promise;
- } else if (cacheEntry.__type === 'promise') {
- throw cacheEntry.promise;
- }
- return cacheEntry.result;
- };
-}
-
-export const useMetadataJsonLink = makeCache(
- 'nftMetadataJson',
- (url: string) => url,
- async (url: string) => {
+export function useMetadataJsonLink(url: string) {
+ const { data, error } = useSWRImmutable(url, async (url: string) => {
return fetch(url).then(response => response.json());
- }
-);
+ });
+ return error ? null : data;
+}
-export const useCompressedNft = makeCache<{ address: string; url: string }, CompressedNft | null>(
- 'compressedNft',
- ({ address, url }) => `${address}-${url}`,
- async ({ address, url }) => {
+export function useCompressedNft({ address, url }: { address: string; url: string }): CompressedNft | null {
+ const { data, error } = useSWRImmutable([address, url], async ([address, url]): Promise => {
return fetch(`${url}`, {
body: JSON.stringify({
id: address,
@@ -72,18 +26,17 @@ export const useCompressedNft = makeCache<{ address: string; url: string }, Comp
.then(response => response.json())
.then((response: DasApiResponse) => {
if ('error' in response) {
- throw new Error(response.error.message);
+ return null;
}
return response.result;
});
- }
-);
+ });
+ return error ? null : data ?? null;
+}
-export const useCompressedNftProof = makeCache<{ address: string; url: string }, CompressedNftProof | null>(
- 'compressedNftProof',
- ({ address, url }) => `proof-${address}-${url}`,
- async ({ address, url }) => {
+export function useCompressedNftProof({ address, url }: { address: string; url: string }): CompressedNftProof | null {
+ const { data, error } = useSWRImmutable([address, url], async ([address, url]) => {
return fetch(`${url}`, {
body: JSON.stringify({
id: address,
@@ -103,8 +56,9 @@ export const useCompressedNftProof = makeCache<{ address: string; url: string },
return response.result;
});
- }
-);
+ });
+ return error ? null : data ?? null;
+}
type DasResponseTypes = CompressedNft | CompressedNftProof;
export type DasApiResponse =
diff --git a/app/utils/anchor.tsx b/app/utils/anchor.tsx
index ecb692fb..5d3e54f2 100644
--- a/app/utils/anchor.tsx
+++ b/app/utils/anchor.tsx
@@ -23,7 +23,7 @@ export function AnchorProgramName({
url: string;
defaultName?: string;
}) {
- const program = useAnchorProgram(programId.toString(), url);
+ const { program } = useAnchorProgram(programId.toString(), url);
const programName = getAnchorProgramName(program) || defaultName;
return <>{programName}>;
}
diff --git a/app/utils/types/elfy.d.ts b/app/utils/types/elfy.d.ts
new file mode 100644
index 00000000..c09b228c
--- /dev/null
+++ b/app/utils/types/elfy.d.ts
@@ -0,0 +1,4 @@
+declare module 'elfy' {
+ const elfy: any;
+ export = elfy;
+}
diff --git a/package.json b/package.json
index 37a75fac..2850db7e 100644
--- a/package.json
+++ b/package.json
@@ -34,12 +34,14 @@
"chart.js": "^4.3.0",
"classnames": "^2.3.1",
"cross-fetch": "^3.1.5",
+ "elfy": "^1.0.0",
"eslint": "8.39.0",
"eslint-config-next": "13.4.0",
"humanize-duration-ts": "^2.1.1",
"moment": "^2.29.4",
"next": "13.4.0",
"p-limit": "^3.1.0",
+ "pako": "^2.1.0",
"react": "18.2.0",
"react-chartjs-2": "^5.2.0",
"react-content-loader": "^6.1.0",
@@ -68,6 +70,7 @@
"@types/bs58": "4.0.1",
"@types/chart.js": "^2.9.34",
"@types/node": "18.16.3",
+ "@types/pako": "^2.0.3",
"@types/react": "18.2.0",
"@types/react-dom": "18.2.1",
"@types/react-select": "3.1.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0ab74795..cbb36c7b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -80,6 +80,9 @@ dependencies:
cross-fetch:
specifier: ^3.1.5
version: 3.1.5
+ elfy:
+ specifier: ^1.0.0
+ version: 1.0.0
eslint:
specifier: 8.39.0
version: 8.39.0
@@ -98,6 +101,9 @@ dependencies:
p-limit:
specifier: ^3.1.0
version: 3.1.0
+ pako:
+ specifier: ^2.1.0
+ version: 2.1.0
react:
specifier: 18.2.0
version: 18.2.0
@@ -178,6 +184,9 @@ devDependencies:
'@types/node':
specifier: 18.16.3
version: 18.16.3
+ '@types/pako':
+ specifier: ^2.0.3
+ version: 2.0.3
'@types/react':
specifier: 18.2.0
version: 18.2.0
@@ -3537,6 +3546,10 @@ packages:
/@types/node@18.16.3:
resolution: {integrity: sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==}
+ /@types/pako@2.0.3:
+ resolution: {integrity: sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q==}
+ dev: true
+
/@types/parse-json@4.0.0:
resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
dev: false
@@ -4880,6 +4893,12 @@ packages:
/electron-to-chromium@1.4.382:
resolution: {integrity: sha512-czMavlW52VIPgutbVL9JnZIZuFijzsG1ww/1z2Otu1r1q+9Qe2bTsH3My3sZarlvwyqHM6+mnZfEnt2Vr4dsIg==}
+ /elfy@1.0.0:
+ resolution: {integrity: sha512-4Kp3AA94jC085IJox+qnvrZ3PudqTi4gQNvIoTZfJJ9IqkRuCoqP60vCVYlIg00c5aYusi5Wjh2bf0cHYt+6gQ==}
+ dependencies:
+ endian-reader: 0.3.0
+ dev: false
+
/elliptic@6.5.4:
resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==}
dependencies:
@@ -4904,6 +4923,10 @@ packages:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
dev: false
+ /endian-reader@0.3.0:
+ resolution: {integrity: sha512-zPlHN59VLEjeJtpEU41ti/i7ZvTbwclvUN2M8anCsI3tOC/3mq6WNTJEKi49A5eLGvDkA0975LZb67Xwp7u4xQ==}
+ dev: false
+
/enhanced-resolve@5.13.0:
resolution: {integrity: sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg==}
engines: {node: '>=10.13.0'}