Skip to content

Conversation

@PierreJeanjacquot
Copy link
Member

@PierreJeanjacquot PierreJeanjacquot commented May 28, 2025

This PR introduces a new component <ChainSyncManager> to keep the chain state up to date between the global store, URL, and user account provider.

Tested scenarios (platforms: brave browser linux, chrome metamask linux):

  • landing:
    • when user lands on / or /<unknown-chain>/* the default chain (bellecour) is selected
    • when user lands on /<known-chain>/* the known chain is selected
  • account auto-reconnection
    • when the user account auto reconnects to the selected chain, nothing happens
    • when the user account auto reconnects to another supported chain, the account chain is selected, then the user account is requested to switch back to the previous chain
    • when the user account auto reconnects to an unsupported chain, the reown modal suggests switching to a supported chain, and a warning is displayed until the account is connected to a supported chain
  • account connection
    • when the user account connects to the selected chain, nothing happens
    • when the user account connects to another supported chain, the account chain is selected, then the user account is requested to switch back to the previous chain
    • when the user account connects to an unsupported chain, the reown modal suggests switching to a supported chain, and a warning is displayed until the account is connected to a supported chain

const SUPPORTED_CHAIN_IDS = SUPPORTED_CHAINS.map((chain) => chain.id);

export function UnsupportedChain() {
const { isConnected, chainId } = useUserStore();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chainId from store may be different from account's chainId

Comment on lines -17 to -26
const newChainSlug = SUPPORTED_CHAINS.find(
(chain) => chain.id === Number(value)
)?.slug;
const pathParts = location.pathname.split('/').filter(Boolean);
const newPath =
pathParts.length > 1
? `/${newChainSlug}/${pathParts.slice(1).join('/')}`
: `/${newChainSlug}`;

navigate({ to: newPath });
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed side effect in the component implementation, chain navigation is handled by a single component

Comment on lines +9 to +11
if (!chainId) {
throw Error('Missing chainId')
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chainId initial state is undefined

adapters: [wagmiAdapter],
networks: networks,
projectId,
defaultNetwork: bellecour,
Copy link
Member Author

@PierreJeanjacquot PierreJeanjacquot May 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default network was removed to avoid switching to the default chain before switching to the selected chain

scenario:

  • user disconnected, arbitrum-sepolia is active
  • user connects with an account on ethereum mainnet
  • connection modal force to switch to bellecour 🐛

Copy link
Member

@ErwanDecoster ErwanDecoster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything seems fine to me, I just have one remark:

Imagine I am on "http://localhost:5173/bellecour". If I modify the URL to "http://localhost:5173/arbitrum-sepolia", for a brief moment, the URL reverts to "http://localhost:5173/bellecour" before finally becoming "http://localhost:5173/arbitrum-sepolia" again.

I find this behavior a bit strange, but it doesn't really pose a problem.

@PierreJeanjacquot
Copy link
Member Author

Everything seems fine to me, I just have one remark:

Imagine I am on "http://localhost:5173/bellecour". If I modify the URL to "http://localhost:5173/arbitrum-sepolia", for a brief moment, the URL reverts to "http://localhost:5173/bellecour" before finally becoming "http://localhost:5173/arbitrum-sepolia" again.

I find this behavior a bit strange, but it doesn't really pose a problem.

This reflects the state of the account:

  1. URL on chain A is the source of truth
  2. the wallet auto reconnects on chain B and becomes the source of truth
  3. the app detects that the wallet has changed the chain and requests a rollback to chain A
    4.a. the wallet accepts (or delegates acceptance to the user) and connects chain A
    4.b. the wallet delegates the request to the user, the user rejects the request, and stays on chain B

Depending on the wallet used, step 4.a. may not require user confirmation and create this "glitchy" view, but if the wallet delegates the confirmation, step 4.b. occurs and must be handled properly.

In my opinion, it is not safe to skip the state synchronization by omitting step 2 because the outcome of step 4 is unknown.

@PierreJeanjacquot PierreJeanjacquot merged commit 7ea657b into feature/chain-switch May 28, 2025
1 check passed
@PierreJeanjacquot PierreJeanjacquot deleted the feat/chain-sync-manager branch May 28, 2025 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants