From 67a50500b7c5e425b5544b4c4a8052e0e540db48 Mon Sep 17 00:00:00 2001 From: Nguyen Phi Nam Date: Fri, 27 Sep 2024 11:42:25 +0700 Subject: [PATCH] fix: switch chain for injected, wallet-connect version (#17) --- .../src/connectors/base/BaseConnector.ts | 2 +- .../connectors/injected/InjectedConnector.ts | 7 +- .../RoninWalletConnectConnector.ts | 8 +- .../ronin-wallet/RoninWalletConnector.ts | 45 ++++-------- .../src/connectors/safe/SafeConnector.ts | 1 - .../connectors/waypoint/WaypointConnector.ts | 15 ++-- .../src/providers/ronin-wallet-connect.ts | 3 +- packages/connect/src/types/connector-error.ts | 1 - packages/connect/src/types/connector.ts | 2 +- packages/wagmi/README.md | 73 +++++++++++++++++++ 10 files changed, 102 insertions(+), 55 deletions(-) diff --git a/packages/connect/src/connectors/base/BaseConnector.ts b/packages/connect/src/connectors/base/BaseConnector.ts index 7f7dc80..9c176d9 100644 --- a/packages/connect/src/connectors/base/BaseConnector.ts +++ b/packages/connect/src/connectors/base/BaseConnector.ts @@ -32,7 +32,7 @@ export abstract class BaseConnector abstract isAuthorized(): Promise; abstract getAccounts(): Promise; abstract getChainId(): Promise; - abstract switchChain(chain: number): Promise; + abstract switchChain(chain: number): Promise; abstract requestAccounts(): Promise; protected abstract requestProvider(): Promise; diff --git a/packages/connect/src/connectors/injected/InjectedConnector.ts b/packages/connect/src/connectors/injected/InjectedConnector.ts index 0b72a5a..6591d2b 100644 --- a/packages/connect/src/connectors/injected/InjectedConnector.ts +++ b/packages/connect/src/connectors/injected/InjectedConnector.ts @@ -18,10 +18,6 @@ export class InjectedConnector extends BaseConnector { async connect(chainId?: number) { const provider = await this.getProvider(); - if (!provider) { - throw new ConnectorError(ConnectorErrorType.PROVIDER_NOT_FOUND); - } - try { const accounts = await this.requestAccounts(); const currentChainId = await this.getChainId(); @@ -66,11 +62,10 @@ export class InjectedConnector extends BaseConnector { async switchChain(chain: number) { const provider = await this.getProvider(); - const chainId = provider?.request({ + return provider.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: numberToHex(chain) }], }); - return !!chainId; } async getChainId() { diff --git a/packages/connect/src/connectors/ronin-wallet-connect/RoninWalletConnectConnector.ts b/packages/connect/src/connectors/ronin-wallet-connect/RoninWalletConnectConnector.ts index f251058..71305b7 100644 --- a/packages/connect/src/connectors/ronin-wallet-connect/RoninWalletConnectConnector.ts +++ b/packages/connect/src/connectors/ronin-wallet-connect/RoninWalletConnectConnector.ts @@ -48,11 +48,13 @@ export class RoninWalletConnectConnector extends BaseConnector this.setupProviderListeners(); const targetChainId = chainId ?? WC_SUPPORTED_CHAIN_IDS[0]; const isChainSupported = WC_SUPPORTED_CHAIN_IDS.includes(targetChainId); + if (!isChainSupported) { throw new ConnectorError(ConnectorErrorType.SWITCH_CHAIN_NOT_SUPPORTED); } const isAuthorized = await this.isAuthorized(); + if (!isAuthorized) { await provider.connect({ chains: [targetChainId] }); } else { @@ -92,17 +94,15 @@ export class RoninWalletConnectConnector extends BaseConnector async switchChain(chain: number) { const provider = await this.getProvider(); - - const chainId = await provider?.request({ + return provider.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: numberToHex(chain) }], }); - return !!chainId; } async getChainId() { const provider = await this.getProvider(); - const chainId = await provider?.request({ + const chainId = await provider?.request({ method: 'eth_chainId', }); diff --git a/packages/connect/src/connectors/ronin-wallet/RoninWalletConnector.ts b/packages/connect/src/connectors/ronin-wallet/RoninWalletConnector.ts index a82a92d..dc728ca 100644 --- a/packages/connect/src/connectors/ronin-wallet/RoninWalletConnector.ts +++ b/packages/connect/src/connectors/ronin-wallet/RoninWalletConnector.ts @@ -2,7 +2,6 @@ import { DEFAULT_CONNECTORS_CONFIG } from '../../common/connectors'; import { ReconnectStorage } from '../../common/storage'; import { requestRoninProvider } from '../../providers'; import { IConnectorConfigs } from '../../types/connector'; -import { ConnectorError, ConnectorErrorType } from '../../types/connector-error'; import { EIP1193Event, IEIP1193Provider } from '../../types/eip1193'; import { numberToHex } from '../../utils'; import { BaseConnector } from '../base/BaseConnector'; @@ -17,36 +16,23 @@ export class RoninWalletConnector extends BaseConnector { async connect(chainId?: number) { const provider = await this.getProvider(); + const accounts = await this.requestAccounts(); + const currentChainId = await this.getChainId(); - if (!provider) { - throw new ConnectorError(ConnectorErrorType.PROVIDER_NOT_FOUND); + if (chainId && currentChainId !== chainId) { + await this.switchChain(chainId); } - try { - const accounts = await this.requestAccounts(); - const currentChainId = await this.getChainId(); - - if (chainId && currentChainId !== chainId) { - await this.switchChain(chainId); - } - - const connectResults = { - provider, - chainId: chainId || currentChainId, - account: accounts[0], - }; - - this.setupProviderListeners(); - this.onConnect(connectResults); - ReconnectStorage.add(this.id); - - return connectResults; - } catch (err) { - if ((err as any as { code: number; message: string })?.code === 4001) { - throw new ConnectorError(ConnectorErrorType.USER_REJECTED_REQUEST, err); - } - throw new ConnectorError(ConnectorErrorType.CONNECT_FAILED, err); - } + const connectResults = { + provider, + chainId: chainId || currentChainId, + account: accounts[0], + }; + + this.setupProviderListeners(); + this.onConnect(connectResults); + ReconnectStorage.add(this.id); + return connectResults; } async disconnect() { @@ -69,11 +55,10 @@ export class RoninWalletConnector extends BaseConnector { async switchChain(chain: number) { const provider = await this.getProvider(); - const chainId = await provider?.request({ + return provider.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: numberToHex(chain) }], }); - return !!chainId; } async getChainId() { diff --git a/packages/connect/src/connectors/safe/SafeConnector.ts b/packages/connect/src/connectors/safe/SafeConnector.ts index 95961e5..8e94981 100644 --- a/packages/connect/src/connectors/safe/SafeConnector.ts +++ b/packages/connect/src/connectors/safe/SafeConnector.ts @@ -64,7 +64,6 @@ export class SafeConnector extends BaseConnector { async switchChain(chain: number) { // TODO: Add a Connector Error for not allowing switch chain throw new ConnectorError(ConnectorErrorType.SWITCH_CHAIN_NOT_SUPPORTED); - return false; // This is to prevent TS error } async getChainId() { diff --git a/packages/connect/src/connectors/waypoint/WaypointConnector.ts b/packages/connect/src/connectors/waypoint/WaypointConnector.ts index eff59c0..ce21599 100644 --- a/packages/connect/src/connectors/waypoint/WaypointConnector.ts +++ b/packages/connect/src/connectors/waypoint/WaypointConnector.ts @@ -27,8 +27,7 @@ export class WaypointConnector extends BaseConnector { } async switchChain() { - console.error(new ConnectorError(ConnectorErrorType.SWITCH_CHAIN_NOT_SUPPORTED)); - return false; + throw new ConnectorError(ConnectorErrorType.SWITCH_CHAIN_NOT_SUPPORTED); } async getChainId() { @@ -61,14 +60,10 @@ export class WaypointConnector extends BaseConnector { }; if (!account) { - try { - const { address, accessToken } = await provider.connect(); - connectResult.account = address as string; - connectResult.accessToken = accessToken; - LocalStorage.set(WAYPOINT_ACCESS_TOKEN_STORAGE_KEY, accessToken); - } catch (err) { - throw new ConnectorError(ConnectorErrorType.CONNECT_FAILED, err); - } + const { address, accessToken } = await provider.connect(); + connectResult.account = address as string; + connectResult.accessToken = accessToken; + LocalStorage.set(WAYPOINT_ACCESS_TOKEN_STORAGE_KEY, accessToken); } ReconnectStorage.add(this.id); diff --git a/packages/connect/src/providers/ronin-wallet-connect.ts b/packages/connect/src/providers/ronin-wallet-connect.ts index 36eca5b..9b128a1 100644 --- a/packages/connect/src/providers/ronin-wallet-connect.ts +++ b/packages/connect/src/providers/ronin-wallet-connect.ts @@ -1,4 +1,5 @@ -import { EthereumProvider, EthereumProviderOptions } from '@walletconnect/ethereum-provider'; +import { EthereumProvider } from '@walletconnect/ethereum-provider'; +import { EthereumProviderOptions } from '@walletconnect/ethereum-provider/dist/types/EthereumProvider'; import { WC_RPC_MAP, diff --git a/packages/connect/src/types/connector-error.ts b/packages/connect/src/types/connector-error.ts index a4bc320..04d02a9 100644 --- a/packages/connect/src/types/connector-error.ts +++ b/packages/connect/src/types/connector-error.ts @@ -1,7 +1,6 @@ export enum ConnectorErrorType { PROVIDER_NOT_FOUND = 'ProviderNotFound', CONNECT_FAILED = 'ConnectFailed', - USER_REJECTED_REQUEST = 'UserRejectedRequest', NOT_INSTALLED = 'NotInstalled', SWITCH_CHAIN_NOT_SUPPORTED = 'SwitchChainNotSupported', } diff --git a/packages/connect/src/types/connector.ts b/packages/connect/src/types/connector.ts index 80296bb..9a29ef3 100644 --- a/packages/connect/src/types/connector.ts +++ b/packages/connect/src/types/connector.ts @@ -27,7 +27,7 @@ export interface IBaseConnector extends IConnectorEventEmitter { isAuthorized(): Promise; getAccounts(): Promise; getChainId(): Promise; - switchChain(chain: any): Promise; + switchChain(chain: number): Promise; requestAccounts(): Promise; shouldAutoReconnect(): Promise; autoConnect(): Promise; diff --git a/packages/wagmi/README.md b/packages/wagmi/README.md index e69de29..c9a5d93 100644 --- a/packages/wagmi/README.md +++ b/packages/wagmi/README.md @@ -0,0 +1,73 @@ +# TantoKit Wagmi + +## Installation + +With yarn + +``` +yarn add @sky-mavis/tanto-wagmi +``` + +With npm + +``` +npm install @sky-mavis/tanto-wagmi +``` + +## Usage + +### Create Config +Create and export a new Wagmi config using createConfig where chains and transports are set up for the Ronin and Saigon network and roninWallet() connects to the Ronin wallet, waypoint() connect to Ronin Waypoint. + +```javascript +import { roninWallet, waypoint } from '@sky-mavis/tanto-wagmi'; +import { ronin, saigon } from 'viem/chains'; +import { createConfig, http } from 'wagmi'; + +export const config = createConfig({ + chains: [ronin, saigon], + transports: { + [ronin.id]: http(), + [saigon.id]: http(), + }, + connectors: [roninWallet(), waypoint()], +}) +``` + +### Wrap Application with Providers + +```javascript +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { WagmiProvider } from 'wagmi'; + +const queryClient = new QueryClient(); + +const App = () => ( + + + + + +); +``` + +### Using Wagmi Hooks +```javascript +import { useAccount, useConnect, useDisconnect, useSignMessage } from 'wagmi'; +import { Button } from '@nextui-org/react'; + +const YourComponent = () => { + const { connect, connectors } = useConnect(); + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ); +}; +``` +