Skip to content

Commit

Permalink
fix: switch chain for injected, wallet-connect version (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
npnam93 authored Sep 27, 2024
1 parent 54bb04d commit 67a5050
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 55 deletions.
2 changes: 1 addition & 1 deletion packages/connect/src/connectors/base/BaseConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export abstract class BaseConnector<ProviderType = IEIP1193Provider>
abstract isAuthorized(): Promise<boolean>;
abstract getAccounts(): Promise<readonly string[]>;
abstract getChainId(): Promise<number>;
abstract switchChain(chain: number): Promise<boolean>;
abstract switchChain(chain: number): Promise<void>;
abstract requestAccounts(): Promise<readonly string[]>;

protected abstract requestProvider(): Promise<ProviderType>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -66,11 +62,10 @@ export class InjectedConnector extends BaseConnector {

async switchChain(chain: number) {
const provider = await this.getProvider();
const chainId = provider?.request<number | string>({
return provider.request<void>({
method: 'wallet_switchEthereumChain',
params: [{ chainId: numberToHex(chain) }],
});
return !!chainId;
}

async getChainId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ export class RoninWalletConnectConnector extends BaseConnector<EthereumProvider>
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 {
Expand Down Expand Up @@ -92,17 +94,15 @@ export class RoninWalletConnectConnector extends BaseConnector<EthereumProvider>

async switchChain(chain: number) {
const provider = await this.getProvider();

const chainId = await provider?.request<number | string>({
return provider.request<void>({
method: 'wallet_switchEthereumChain',
params: [{ chainId: numberToHex(chain) }],
});
return !!chainId;
}

async getChainId() {
const provider = await this.getProvider();
const chainId = await provider?.request<number | string>({
const chainId = await provider?.request<string>({
method: 'eth_chainId',
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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() {
Expand All @@ -69,11 +55,10 @@ export class RoninWalletConnector extends BaseConnector {

async switchChain(chain: number) {
const provider = await this.getProvider();
const chainId = await provider?.request<number | string>({
return provider.request<void>({
method: 'wallet_switchEthereumChain',
params: [{ chainId: numberToHex(chain) }],
});
return !!chainId;
}

async getChainId() {
Expand Down
1 change: 0 additions & 1 deletion packages/connect/src/connectors/safe/SafeConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
15 changes: 5 additions & 10 deletions packages/connect/src/connectors/waypoint/WaypointConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ export class WaypointConnector extends BaseConnector<WaypointProvider> {
}

async switchChain() {
console.error(new ConnectorError(ConnectorErrorType.SWITCH_CHAIN_NOT_SUPPORTED));
return false;
throw new ConnectorError(ConnectorErrorType.SWITCH_CHAIN_NOT_SUPPORTED);
}

async getChainId() {
Expand Down Expand Up @@ -61,14 +60,10 @@ export class WaypointConnector extends BaseConnector<WaypointProvider> {
};

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);
Expand Down
3 changes: 2 additions & 1 deletion packages/connect/src/providers/ronin-wallet-connect.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
1 change: 0 additions & 1 deletion packages/connect/src/types/connector-error.ts
Original file line number Diff line number Diff line change
@@ -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',
}
Expand Down
2 changes: 1 addition & 1 deletion packages/connect/src/types/connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface IBaseConnector extends IConnectorEventEmitter {
isAuthorized(): Promise<boolean>;
getAccounts(): Promise<readonly string[]>;
getChainId(): Promise<number>;
switchChain(chain: any): Promise<boolean>;
switchChain(chain: number): Promise<void>;
requestAccounts(): Promise<readonly string[]>;
shouldAutoReconnect(): Promise<boolean>;
autoConnect(): Promise<IConnectResult | null>;
Expand Down
73 changes: 73 additions & 0 deletions packages/wagmi/README.md
Original file line number Diff line number Diff line change
@@ -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 = () => (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<YourComponent />
</QueryClientProvider>
</WagmiProvider>
);
```

### Using Wagmi Hooks
```javascript
import { useAccount, useConnect, useDisconnect, useSignMessage } from 'wagmi';
import { Button } from '@nextui-org/react';

const YourComponent = () => {
const { connect, connectors } = useConnect();

return (
<div>
{connectors.map((connector) => (
<Button onClick={() => connect({ connector })} key={connector.id}>
Connect to {connector.name}
</Button>
))}
</div>
);
};
```

0 comments on commit 67a5050

Please sign in to comment.