Skip to content

Commit 3a20383

Browse files
committed
apply review
1 parent 577c2a4 commit 3a20383

6 files changed

Lines changed: 77 additions & 5 deletions

File tree

packages/ui/src/components/WalletContainer.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { PUB_CHAIN, PUB_CHAIN_NAME, TAIKO_L2_CHAIN_ID } from "@/constants";
1+
import { PUB_CHAIN, PUB_CHAIN_NAME } from "@/constants";
2+
import { useWalletChainPolicy } from "@/context/WalletChainPolicy";
23
import { config } from "@/context/Web3Modal";
34
import { formatHexString } from "@/utils/evm";
5+
import { shouldForcePrimaryChainSwitch } from "@/utils/wallet-chain-policy";
46
import { MemberAvatar } from "@aragon/ods";
57
import { useWeb3Modal } from "@web3modal/wagmi/react";
68
import classNames from "classnames";
@@ -16,6 +18,7 @@ const WalletContainer = () => {
1618
const { open } = useWeb3Modal();
1719
const { address, isConnected, chainId } = useAccount();
1820
const { switchChain } = useSwitchChain();
21+
const { allowedSecondaryChainIds } = useWalletChainPolicy();
1922

2023
const { data: ensName } = useEnsName({
2124
config,
@@ -32,11 +35,10 @@ const WalletContainer = () => {
3235
});
3336

3437
useEffect(() => {
35-
if (!chainId) return;
36-
else if (chainId === PUB_CHAIN.id || chainId === TAIKO_L2_CHAIN_ID ) return;
38+
if (!shouldForcePrimaryChainSwitch(chainId, PUB_CHAIN.id, allowedSecondaryChainIds)) return;
3739

3840
switchChain({ chainId: PUB_CHAIN.id });
39-
}, [chainId, switchChain]);
41+
}, [allowedSecondaryChainIds, chainId, switchChain]);
4042

4143
return (
4244
<button

packages/ui/src/components/l2Execution/ProposalL2Execution.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { useEffect } from "react";
12
import { AlertInline, Button, Spinner } from "@aragon/ods";
23
import { useWeb3Modal } from "@web3modal/wagmi/react";
34
import { type Hex } from "viem";
45
import { useAccount, useSwitchChain } from "wagmi";
56
import { PUB_TAIKO_BRIDGE_ADDRESS, TAIKO_L2_CHAIN_ID } from "@/constants";
7+
import { useWalletChainPolicy } from "@/context/WalletChainPolicy";
68
import { useL2AnchorSync } from "@/hooks/useL2AnchorSync";
79
import { useL2LegExecution } from "@/hooks/useL2LegExecution";
810
import { shouldRenderL2ExecutionCard } from "@/utils/l2-execution";
@@ -37,6 +39,7 @@ export function ProposalL2Execution({
3739
const { isConnected, chain } = useAccount();
3840
const { open } = useWeb3Modal();
3941
const { switchChain } = useSwitchChain();
42+
const { setAllowedSecondaryChainIds } = useWalletChainPolicy();
4043

4144
const l1BlockNumber = executionBlockNumber ? BigInt(executionBlockNumber) : undefined;
4245
const l1TxHash = executorTxHash as Hex | undefined;
@@ -69,6 +72,15 @@ export function ProposalL2Execution({
6972
const detectedFromTx = !!message;
7073

7174
const hasL2Leg = detectedFromActions || detectedFromTx;
75+
const shouldAllowTaikoL2 = executed && shouldCheckL2 && !isL2Confirmed;
76+
77+
useEffect(() => {
78+
setAllowedSecondaryChainIds(shouldAllowTaikoL2 ? [TAIKO_L2_CHAIN_ID] : []);
79+
80+
return () => {
81+
setAllowedSecondaryChainIds([]);
82+
};
83+
}, [setAllowedSecondaryChainIds, shouldAllowTaikoL2]);
7284

7385
// Don't render if no L2 leg detected (and not still checking)
7486
if (!shouldRenderL2ExecutionCard({ hasL2Leg, isExtracting, shouldCheckExecutedProposal: shouldCheckL2 })) {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React, { createContext, useContext, useMemo, useState } from "react";
2+
3+
export interface WalletChainPolicyContextProps {
4+
allowedSecondaryChainIds: number[];
5+
setAllowedSecondaryChainIds: (chainIds: number[]) => void;
6+
}
7+
8+
const WalletChainPolicyContext = createContext<WalletChainPolicyContextProps | undefined>(undefined);
9+
10+
export const WalletChainPolicyProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
11+
const [allowedSecondaryChainIds, setAllowedSecondaryChainIds] = useState<number[]>([]);
12+
13+
const value = useMemo(
14+
() => ({ allowedSecondaryChainIds, setAllowedSecondaryChainIds }),
15+
[allowedSecondaryChainIds]
16+
);
17+
18+
return <WalletChainPolicyContext.Provider value={value}>{children}</WalletChainPolicyContext.Provider>;
19+
};
20+
21+
export const useWalletChainPolicy = () => {
22+
const context = useContext(WalletChainPolicyContext);
23+
24+
if (!context) {
25+
throw new Error("useWalletChainPolicy must be used inside the WalletChainPolicyProvider");
26+
}
27+
28+
return context;
29+
};

packages/ui/src/context/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client
1111
import { UseDerivedWalletProvider } from "../hooks/useDerivedWallet";
1212
import { OdsModulesProvider } from "@aragon/ods";
1313
import { customModulesCopy, odsCoreProviderValues } from "@/components/ods-customizations";
14+
import { WalletChainPolicyProvider } from "./WalletChainPolicy";
1415

1516
const queryClient = new QueryClient({
1617
defaultOptions: {
@@ -53,7 +54,9 @@ export function RootContextProvider({ children }: { children: ReactNode }) {
5354
>
5455
<PersistQueryClientProvider client={queryClient} persistOptions={{ persister }}>
5556
<AlertProvider>
56-
<UseDerivedWalletProvider>{children}</UseDerivedWalletProvider>
57+
<WalletChainPolicyProvider>
58+
<UseDerivedWalletProvider>{children}</UseDerivedWalletProvider>
59+
</WalletChainPolicyProvider>
5760
</AlertProvider>
5861
</PersistQueryClientProvider>
5962
</OdsModulesProvider>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { describe, expect, test } from "bun:test";
2+
import { shouldForcePrimaryChainSwitch } from "../utils/wallet-chain-policy";
3+
4+
describe("shouldForcePrimaryChainSwitch", () => {
5+
test("force-switches when connected to Taiko but the current flow has not allowed it", () => {
6+
expect(shouldForcePrimaryChainSwitch(167000, 1, [])).toBe(true);
7+
});
8+
9+
test("does not force-switch when the current flow explicitly allows Taiko", () => {
10+
expect(shouldForcePrimaryChainSwitch(167000, 1, [167000])).toBe(false);
11+
});
12+
13+
test("does not force-switch when already on the primary chain", () => {
14+
expect(shouldForcePrimaryChainSwitch(1, 1, [])).toBe(false);
15+
});
16+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export function shouldForcePrimaryChainSwitch(
2+
currentChainId: number | undefined,
3+
primaryChainId: number,
4+
allowedSecondaryChainIds: number[] = []
5+
) {
6+
if (!currentChainId) return false;
7+
if (currentChainId === primaryChainId) return false;
8+
9+
return !allowedSecondaryChainIds.includes(currentChainId);
10+
}

0 commit comments

Comments
 (0)