Skip to content

Commit 34af528

Browse files
committed
Dashboard: Remove Moralis API usage from contract/balances, UI improvements
1 parent 710ac32 commit 34af528

File tree

18 files changed

+203
-723
lines changed

18 files changed

+203
-723
lines changed

.changeset/thin-days-add.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Fix `thirdweb/insight` import typescript error

apps/dashboard/.env.example

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,6 @@ DASHBOARD_SECRET_KEY="<replace_me_with_your_secret_key>"
5353
# Client id for api routes
5454
API_ROUTES_CLIENT_ID=
5555

56-
# <moralis.io API key (used for api routes for token balances and wallet NFTs)
57-
# - not required to build (unless using wallet NFTs and token balances)>
58-
MORALIS_API_KEY=
59-
60-
# alchemy.com API key (used for wallet NFTS)
61-
# - cannot be restricted to IP/domain because vercel has no stable IPs and it happens during build & runtime api route call
62-
# - not required to build (unless testing wallet NFTs)>
63-
SSR_ALCHEMY_KEY=
6456

6557

6658
# Hubspot Access Token (used for contact us form)

apps/dashboard/src/@/actions/getBalancesFromMoralis.ts

Lines changed: 0 additions & 89 deletions
This file was deleted.

apps/dashboard/src/@/actions/getWalletNFTs.ts

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
11
"use server";
22

33
import { NEXT_PUBLIC_DASHBOARD_CLIENT_ID } from "@/constants/public-envs";
4-
import { MORALIS_API_KEY } from "@/constants/server-envs";
5-
import {
6-
generateAlchemyUrl,
7-
transformAlchemyResponseToNFT,
8-
} from "@/lib/wallet/nfts/alchemy";
9-
import {
10-
generateMoralisUrl,
11-
transformMoralisResponseToNFT,
12-
} from "@/lib/wallet/nfts/moralis";
134
import type { WalletNFT } from "@/lib/wallet/nfts/types";
145
import { getVercelEnv } from "@/utils/vercel";
15-
import { isAlchemySupported } from "../lib/wallet/nfts/isAlchemySupported";
16-
import { isMoralisSupported } from "../lib/wallet/nfts/isMoralisSupported";
176

187
type WalletNFTApiReturn =
198
| { result: WalletNFT[]; error?: undefined }
@@ -38,60 +27,6 @@ export async function getWalletNFTs(params: {
3827
return { result: response.data };
3928
}
4029

41-
if (isAlchemySupported(chainId)) {
42-
const url = generateAlchemyUrl({ chainId, owner });
43-
44-
const response = await fetch(url, {
45-
next: {
46-
revalidate: 10, // cache for 10 seconds
47-
},
48-
});
49-
if (response.status >= 400) {
50-
return { error: response.statusText };
51-
}
52-
try {
53-
const parsedResponse = await response.json();
54-
const result = await transformAlchemyResponseToNFT(parsedResponse, owner);
55-
56-
return { error: undefined, result };
57-
} catch (err) {
58-
console.error("Error fetching NFTs", err);
59-
return { error: "error parsing response" };
60-
}
61-
}
62-
63-
if (isMoralisSupported(chainId) && MORALIS_API_KEY) {
64-
const url = generateMoralisUrl({ chainId, owner });
65-
66-
const response = await fetch(url, {
67-
headers: {
68-
"X-API-Key": MORALIS_API_KEY,
69-
},
70-
method: "GET",
71-
next: {
72-
revalidate: 10, // cache for 10 seconds
73-
},
74-
});
75-
76-
if (response.status >= 400) {
77-
return { error: response.statusText };
78-
}
79-
80-
try {
81-
const parsedResponse = await response.json();
82-
const result = await transformMoralisResponseToNFT(
83-
await parsedResponse,
84-
owner,
85-
chainId,
86-
);
87-
88-
return { result };
89-
} catch (err) {
90-
console.error("Error fetching NFTs", err);
91-
return { error: "error parsing response" };
92-
}
93-
}
94-
9530
return { error: "unsupported chain" };
9631
}
9732

apps/dashboard/src/@/constants/server-envs.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,6 @@ if (isProd && INSIGHT_SERVICE_API_KEY) {
5858
);
5959
}
6060

61-
export const MORALIS_API_KEY = process.env.MORALIS_API_KEY || "";
62-
63-
if (MORALIS_API_KEY) {
64-
experimental_taintUniqueValue(
65-
"Do not pass MORALIS_API_KEY to the client",
66-
process,
67-
MORALIS_API_KEY,
68-
);
69-
}
70-
7161
export const ANALYTICS_SERVICE_URL = process.env.ANALYTICS_SERVICE_URL || "";
7262

7363
export const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY || "";

apps/dashboard/src/@/hooks/useSplit.ts

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,62 +5,85 @@ import {
55
useQueryClient,
66
} from "@tanstack/react-query";
77
import { toast } from "sonner";
8-
import { sendAndConfirmTransaction, type ThirdwebContract } from "thirdweb";
8+
import {
9+
type Chain,
10+
sendAndConfirmTransaction,
11+
type ThirdwebClient,
12+
type ThirdwebContract,
13+
} from "thirdweb";
914
import { distribute, distributeByToken } from "thirdweb/extensions/split";
15+
import { getOwnedTokens } from "thirdweb/insight";
1016
import { useActiveAccount } from "thirdweb/react";
1117
import invariant from "tiny-invariant";
12-
import { getTokenBalancesFromMoralis } from "@/actions/getBalancesFromMoralis";
18+
import { parseError } from "../utils/errorParser";
1319

14-
function getTokenBalancesQuery(contract: ThirdwebContract) {
20+
function getTokenBalancesQuery(params: {
21+
ownerAddress: string;
22+
client: ThirdwebClient;
23+
chain: Chain;
24+
}) {
1525
return queryOptions({
1626
queryFn: async () => {
17-
const res = await getTokenBalancesFromMoralis({
18-
chainId: contract.chain.id,
19-
contractAddress: contract.address,
27+
return getOwnedTokens({
28+
client: params.client,
29+
chains: [params.chain],
30+
ownerAddress: params.ownerAddress,
31+
queryOptions: {
32+
include_native: "true",
33+
},
2034
});
21-
22-
if (!res.data) {
23-
throw new Error(res.error);
24-
}
25-
return res.data;
2635
},
27-
queryKey: ["split-balances", contract.chain.id, contract.address],
36+
queryKey: ["getOwnedTokens", params.chain.id, params.ownerAddress],
2837
retry: false,
2938
});
3039
}
3140

32-
export function useSplitBalances(contract: ThirdwebContract) {
33-
return useQuery(getTokenBalancesQuery(contract));
41+
export function useOwnedTokenBalances(params: {
42+
ownerAddress: string;
43+
client: ThirdwebClient;
44+
chain: Chain;
45+
}) {
46+
return useQuery(getTokenBalancesQuery(params));
3447
}
3548

3649
export function useSplitDistributeFunds(contract: ThirdwebContract) {
3750
const account = useActiveAccount();
3851
const queryClient = useQueryClient();
3952

53+
const params = {
54+
ownerAddress: contract.address, // because we want to fetch the balance of split contract
55+
client: contract.client,
56+
chain: contract.chain,
57+
};
58+
4059
return useMutation({
4160
mutationFn: async () => {
4261
invariant(account, "No active account");
62+
4363
const balances =
4464
// get the cached data if it exists, otherwise fetch it
45-
queryClient.getQueryData(getTokenBalancesQuery(contract).queryKey) ||
46-
(await queryClient.fetchQuery(getTokenBalancesQuery(contract)));
65+
queryClient.getQueryData(getTokenBalancesQuery(params).queryKey) ||
66+
(await queryClient.fetchQuery(getTokenBalancesQuery(params)));
4767

4868
const distributions = balances
49-
.filter((token) => token.display_balance !== "0.0")
69+
.filter((token) => token.value !== 0n)
5070
.map(async (currency) => {
5171
const transaction =
5272
currency.name === "Native Token"
5373
? distribute({ contract })
5474
: distributeByToken({
5575
contract,
56-
tokenAddress: currency.token_address,
76+
tokenAddress: currency.tokenAddress,
5777
});
5878
const promise = sendAndConfirmTransaction({
5979
account,
6080
transaction,
6181
});
6282
toast.promise(promise, {
63-
error: `Error distributing ${currency.name}`,
83+
error: (err) => ({
84+
message: `Error distributing ${currency.name}`,
85+
description: parseError(err),
86+
}),
6487
loading: `Distributing ${currency.name}`,
6588
success: `Successfully distributed ${currency.name}`,
6689
});
@@ -69,7 +92,7 @@ export function useSplitDistributeFunds(contract: ThirdwebContract) {
6992
return await Promise.all(distributions);
7093
},
7194
onSettled: () => {
72-
queryClient.invalidateQueries(getTokenBalancesQuery(contract));
95+
queryClient.invalidateQueries(getTokenBalancesQuery(params));
7396
},
7497
});
7598
}

0 commit comments

Comments
 (0)