Skip to content

[Feature]: Using Wagmi + React Hooks does not persist connected account through refreshes #2343

Open
@drewcook

Description

@drewcook

Is your request related to a problem?

Yes, persistance of the previously connected wallet and account.

Feature Description

It would be nice to allow a user to choose their wallet, connect their account, refresh the page, and have it automatically selected/connected so the user does not have to be re-prompted to do so. This can be done via localStorage, and it is already in place for some wagmi items, however, this feature doesn't exists.

If so, please advise on how to achieve this - the docs are sparse here.

I had tried rolling my own implementation with a custom provider that wraps some of the API, but there are errors in the underlying packages.

The wallet field from useConnectAccount is always null on first load. It would be nice to pick this up from localStorage instead by default.

Alternative Solutions

Here's a rough implementation that throws errors due to wallet being null.

const defaultContextValues: Web3ContextValues = {
	account: {
		address: undefined,
		addresses: undefined,
		chain: undefined,
		chainId: undefined,
		connector: undefined,
		isConnected: false,
		isReconnecting: false,
		isConnecting: false,
		isDisconnected: true,
		status: 'disconnected',
	},
	connecting: false,
	isConnected: false,
	handleConnectDisconnect: () => {},
}

const Web3Context = createContext<Web3ContextValues>(defaultContextValues)

export function Web3Provider({ children }: Props) {
	const context = useContext(Web3OnboardContext)

	// Local state for context values
	const [account, setAccount] = useState(defaultContextValues.account)

	// Hooks from web3-onboard
	const [{ wallet, connecting }, connect, disconnect] = useConnectWallet()

	const handleConnectWallet = () => {
		if (account?.isConnected && wallet) disconnect(wallet)
		else connect()
	}

	const setConnectedAccount = () => {
		const wagmiConfig = context?.state.get().wagmiConfig
		if (!wagmiConfig) return
		const acct = getAccount(wagmiConfig)
		setAccount(acct)
		localStorage.setItem('connectedAccount', stringify(acct))
	}

	useEffect(() => {
		// Check local storage for a previous connected account to persist through refreshes
		const storedAccount = localStorage.getItem('connectedAccount')
		if (storedAccount) setAccount(JSON.parse(storedAccount))
	}, [])

	useEffect(() => {
		const storedAccount = localStorage.getItem('connectedAccount')
		if (context && wallet) {
			// Connected, set local state and storage
			console.log('connected', { context, wallet })
			setConnectedAccount()
		} else if (storedAccount) {
			setAccount(JSON.parse(storedAccount))
		} else {
			// Disconnected, reset local state and storage
			console.log('disconnected')
			setAccount(undefined)
			localStorage.removeItem('connectedAccount')
		}
	}, [wallet, context])

	return (
		<Web3Context.Provider
			value={{
				account,
				connecting: !!account?.isConnecting,
				isConnected: !!account?.isConnected,
				handleConnectDisconnect: handleConnectWallet,
			}}
		>
			{children}
		</Web3Context.Provider>
	)
}

Anything else?

No response

Metadata

Metadata

Assignees

Labels

featureNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions