Skip to content

Commit de22377

Browse files
committed
Add ecosystem-specific chain config support (#8147)
Introduces ecosystemConfig utility to define allowed chains per ecosystem. Updates ConnectButton, ConnectEmbed, NftGallery, and wallet pages to use ecosystem-specific chain lists, enabling dynamic filtering and selection of chains based on the current ecosystem context. <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces ecosystem-specific chain handling in the wallet UI, allowing for dynamic chain selection based on the ecosystem parameter. It enhances components to utilize ecosystem chains and improves the overall functionality of NFT galleries and connection buttons. ### Detailed summary - Added `getEcosystemChainIds` and `getEcosystemChains` functions in `ecosystemConfig.ts`. - Updated `Layout` to use `allowedChainIds` based on the ecosystem. - Modified `NftGallery` to accept `allowedChainIds` and handle resolved chain IDs. - Enhanced `ConnectButton` to utilize ecosystem-specific chains. - Adjusted `Page` to retrieve and pass `allowedChainIds` for NFT galleries. - Updated `ConnectEmbed` to manage ecosystem chains and wallet connections dynamically. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Ecosystem-aware chain selection across wallet pages, with automatic filtering to supported chains. * NFT Gallery now respects ecosystem-specific allowed chains and selects the most relevant chain for queries and empty states. * Connect Button and Connect Embed preselect and display chains based on the current ecosystem, improving onboarding. * Ecosystem-aware wallet option shown when applicable. * Wallet page routing now supports ecosystem in the URL, enabling context-aware views. * **Refactor** * Centralized ecosystem-to-chain mapping to ensure consistent behavior across components. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 7495f46 commit de22377

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)