Skip to content

Commit 99c2af5

Browse files
authored
Add ecosystem-specific chain config support (#8147)
1 parent 7495f46 commit 99c2af5

File tree

6 files changed

+86
-7
lines changed

6 files changed

+86
-7
lines changed

apps/wallet-ui/src/app/[ecosystem]/(authed)/wallet/[address]/layout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { shortenAddress } from "thirdweb/utils";
44
import { ChainCombobox } from "@/components/ChainCombobox";
55
import { getChains } from "@/lib/chains";
66
import { client } from "@/lib/client";
7+
import { getEcosystemChainIds } from "@/lib/ecosystemConfig";
78
import { getEcosystemInfo } from "@/lib/ecosystems";
89
import { SIMPLEHASH_NFT_SUPPORTED_CHAIN_IDS } from "@/util/simplehash";
910

@@ -45,8 +46,11 @@ export default async function Layout(props: {
4546
thirdwebChainsPromise,
4647
]);
4748

49+
const specialChainIds = getEcosystemChainIds(params.ecosystem);
50+
const allowedChainIds = specialChainIds ?? SIMPLEHASH_NFT_SUPPORTED_CHAIN_IDS;
51+
4852
const simpleHashChains = thirdwebChains.filter((chain) =>
49-
SIMPLEHASH_NFT_SUPPORTED_CHAIN_IDS.includes(chain.chainId),
53+
allowedChainIds.includes(chain.chainId),
5054
);
5155

5256
return (
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { getAddress } from "thirdweb";
22
import { AutoConnectWalletConnect } from "@/components/AutoConnectWalletConnect";
33
import NftGallery from "@/components/NftGallery";
4+
import { getEcosystemChainIds } from "@/lib/ecosystemConfig";
45

56
export default async function Page(props: {
6-
params: Promise<{ address: string }>;
7+
params: Promise<{ ecosystem: string; address: string }>;
78
searchParams: Promise<{ chainId?: string; uri?: string }>;
89
}) {
910
const [searchParams, params] = await Promise.all([
@@ -12,12 +13,18 @@ export default async function Page(props: {
1213
]);
1314

1415
const { chainId, uri } = searchParams;
15-
const { address } = params;
16+
const { address, ecosystem } = params;
17+
const allowedChainIds = getEcosystemChainIds(ecosystem);
18+
const parsedChainId = chainId ? Number(chainId) : undefined;
1619

1720
return (
1821
<>
1922
<AutoConnectWalletConnect uri={uri} />
20-
<NftGallery chainId={Number(chainId)} owner={getAddress(address)} />
23+
<NftGallery
24+
allowedChainIds={allowedChainIds}
25+
chainId={parsedChainId}
26+
owner={getAddress(address)}
27+
/>
2128
</>
2229
);
2330
}

apps/wallet-ui/src/components/ConnectButton.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
"use client";
22
import { useTheme } from "next-themes";
3+
import { useMemo } from "react";
34
import { ConnectButton as ThirdwebConnectButton } from "thirdweb/react";
45
import { ecosystemWallet } from "thirdweb/wallets";
56
import { client } from "@/lib/client";
7+
import { getEcosystemChains } from "@/lib/ecosystemConfig";
68

79
export default function ConnectButton({
810
ecosystem,
911
}: {
1012
ecosystem: `ecosystem.${string}`;
1113
}) {
1214
const { theme } = useTheme();
15+
const chains = useMemo(() => getEcosystemChains(ecosystem), [ecosystem]);
1316

1417
return (
1518
<ThirdwebConnectButton
19+
chain={chains?.[0]}
20+
chains={chains}
1621
client={client}
1722
theme={theme === "light" ? "light" : "dark"}
1823
wallets={[ecosystemWallet(ecosystem)]}

apps/wallet-ui/src/components/ConnectEmbed.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,33 @@
22
import { useQuery } from "@tanstack/react-query";
33
import { useParams, useSearchParams } from "next/navigation";
44
import { useTheme } from "next-themes";
5+
import { useMemo } from "react";
56
import type { VerifyLoginPayloadParams } from "thirdweb/auth";
67
import { ConnectEmbed as ThirdwebConnectEmbed } from "thirdweb/react";
78
import { ecosystemWallet } from "thirdweb/wallets";
89
import { useRouter } from "@/hooks/useRouter";
910
import { generatePayload, getCurrentUser, login, logout } from "@/lib/auth";
1011
import { client } from "@/lib/client";
12+
import { getEcosystemChains } from "@/lib/ecosystemConfig";
1113

1214
export function ConnectEmbed() {
1315
const { theme } = useTheme();
1416
const router = useRouter();
1517
const params = useParams();
1618
const searchParams = useSearchParams();
19+
const ecosystemParam = params.ecosystem;
20+
const ecosystemSlug = Array.isArray(ecosystemParam)
21+
? ecosystemParam[0]
22+
: ecosystemParam;
23+
24+
const chains = useMemo(
25+
() => getEcosystemChains(ecosystemSlug),
26+
[ecosystemSlug],
27+
);
28+
29+
const ecosystemId = ecosystemSlug
30+
? (`ecosystem.${ecosystemSlug}` as `ecosystem.${string}`)
31+
: undefined;
1732

1833
const { data: userAddress } = useQuery({
1934
queryFn: getCurrentUser,
@@ -29,6 +44,8 @@ export function ConnectEmbed() {
2944

3045
return (
3146
<ThirdwebConnectEmbed
47+
chain={chains?.[0]}
48+
chains={chains}
3249
auth={{
3350
doLogin: async (loginParams: VerifyLoginPayloadParams) => {
3451
const success = await login(loginParams);
@@ -46,7 +63,7 @@ export function ConnectEmbed() {
4663
autoConnect={true}
4764
client={client}
4865
theme={theme === "light" ? "light" : "dark"}
49-
wallets={[ecosystemWallet(`ecosystem.${params.ecosystem}`)]}
66+
wallets={ecosystemId ? [ecosystemWallet(ecosystemId)] : undefined}
5067
/>
5168
);
5269
}

apps/wallet-ui/src/components/NftGallery.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,31 @@ export function NftGalleryLoading() {
2020
export default async function NftGallery({
2121
owner,
2222
chainId,
23+
allowedChainIds,
2324
}: {
2425
owner: Address;
2526
chainId?: number;
2627
page?: number;
28+
allowedChainIds?: number[];
2729
}) {
30+
const resolvedChainId =
31+
chainId && allowedChainIds && !allowedChainIds.includes(chainId)
32+
? undefined
33+
: chainId;
34+
35+
const chainIdsToQuery =
36+
resolvedChainId !== undefined
37+
? [Number(resolvedChainId)]
38+
: (allowedChainIds ?? SIMPLEHASH_NFT_SUPPORTED_CHAIN_IDS);
39+
2840
const erc721TokensResult = await getErc721Tokens({
29-
chainIds: chainId ? [Number(chainId)] : SIMPLEHASH_NFT_SUPPORTED_CHAIN_IDS,
41+
chainIds: chainIdsToQuery,
3042
limit: 36,
3143
owner,
3244
});
3345

3446
if (erc721TokensResult.tokens.length === 0) {
35-
return <NftGalleryEmpty chainId={chainId} />;
47+
return <NftGalleryEmpty chainId={resolvedChainId} />;
3648
}
3749

3850
return (
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import type { Chain } from "thirdweb";
2+
import { defineChain } from "thirdweb";
3+
4+
type EcosystemIdentifier = `ecosystem.${string}` | string | undefined;
5+
6+
const SPECIAL_ECOSYSTEM_CHAIN_IDS: Record<string, readonly number[]> = {
7+
"mon-id": [1, 43114] as const,
8+
};
9+
10+
function normalizeEcosystemSlug(ecosystem?: string) {
11+
if (!ecosystem) {
12+
return undefined;
13+
}
14+
if (ecosystem.startsWith("ecosystem.")) {
15+
const [, slug] = ecosystem.split(".");
16+
return slug;
17+
}
18+
return ecosystem;
19+
}
20+
21+
export function getEcosystemChainIds(
22+
ecosystem?: EcosystemIdentifier,
23+
): number[] | undefined {
24+
const slug = normalizeEcosystemSlug(ecosystem);
25+
const chainIds = slug ? SPECIAL_ECOSYSTEM_CHAIN_IDS[slug] : undefined;
26+
return chainIds ? [...chainIds] : undefined;
27+
}
28+
29+
export function getEcosystemChains(
30+
ecosystem?: EcosystemIdentifier,
31+
): Chain[] | undefined {
32+
const chainIds = getEcosystemChainIds(ecosystem);
33+
return chainIds?.map((chainId) => defineChain(chainId));
34+
}

0 commit comments

Comments
 (0)