1- // import { createWeb3Modal, defaultConfig } from '@web3modal/ethers5/react';
2- // import {
3- // constants,
4- // PROJECT_ID as projectId,
5- // METADATA as metadata,
6- // } from './constants';
7- // import EventManager from 'events';
8- // import { Chain, RequestArguments } from '../types';
9- // import txRunner from './txRunner';
10- // import { saveSettings } from '../actions';
11-
12- // class WalletConnect {
13- // web3modal: ReturnType<typeof createWeb3Modal>;
14- // ethersConfig: ReturnType<typeof defaultConfig>;
15- // chains: Chain[];
16- // currentChain?: number;
17- // internalEvents: EventManager;
18- // currentAccount?: string;
19-
20- // constructor() {
21- // this.internalEvents = new EventManager();
22- // const ethersConfig = defaultConfig({
23- // metadata,
24- // rpcUrl: 'https://cloudflare-eth.com',
25- // });
26-
27- // this.web3modal = createWeb3Modal({
28- // projectId,
29- // chains: constants.chains,
30- // metadata,
31- // ethersConfig,
32- // });
33- // this.ethersConfig = ethersConfig;
34- // this.chains = constants.chains;
35- // }
36-
37- // subscribeToEvents() {
38- // this.web3modal.subscribeProvider(({ address, isConnected, chainId }) => {
39- // if (isConnected) {
40- // txRunner.getAccounts();
41- // if (address !== this.currentAccount) {
42- // this.currentAccount = address;
43- // }
44- // if (this.currentChain !== chainId) {
45- // this.currentChain = chainId;
46- // }
47- // } else {
48- // saveSettings({ loadedAccounts: {} });
49- // this.currentAccount = '';
50- // this.currentChain = 0;
51- // }
52- // });
53- // }
54-
55- // async sendAsync(data: RequestArguments) {
56- // const address = this.web3modal.getAddress();
57- // const provider = this.web3modal.getWalletProvider();
58- // if (address && provider) {
59- // if (data.method === 'eth_accounts') {
60- // return {
61- // jsonrpc: '2.0',
62- // result: [address],
63- // id: data.id,
64- // };
65- // } else {
66- // //@ts -expect-error this flag does not correspond to EIP-1193 but was introduced by MetaMask
67- // if (provider.isMetamask && provider.sendAsync) {
68- // return new Promise((resolve) => {
69- // //@ts -expect-error sendAsync is a legacy function we know MetaMask supports it
70- // provider.sendAsync(data, (error, response) => {
71- // if (error) {
72- // if (
73- // error.data &&
74- // error.data.originalError &&
75- // error.data.originalError.data
76- // ) {
77- // resolve({
78- // jsonrpc: '2.0',
79- // error: error.data.originalError,
80- // id: data.id,
81- // });
82- // } else if (error.data && error.data.message) {
83- // resolve({
84- // jsonrpc: '2.0',
85- // error: error.data && error.data,
86- // id: data.id,
87- // });
88- // } else {
89- // resolve({
90- // jsonrpc: '2.0',
91- // error,
92- // id: data.id,
93- // });
94- // }
95- // }
96- // return resolve(response);
97- // });
98- // });
99- // } else {
100- // try {
101- // const message = await provider.request(data);
102- // return { jsonrpc: '2.0', result: message, id: data.id };
103- // } catch (e: any) {
104- // return {
105- // jsonrpc: '2.0',
106- // error: { message: e.message, code: -32603 },
107- // id: data.id,
108- // };
109- // }
110- // }
111- // }
112- // } else {
113- // const err = `Cannot make ${data.method} request. Remix client is not connected to walletconnect client`;
114- // console.error(err);
115- // return {
116- // jsonrpc: '2.0',
117- // error: { message: err, code: -32603 },
118- // id: data.id,
119- // };
120- // }
121- // }
122-
123- // async deactivate() {
124- // console.log('deactivating walletconnect plugin...');
125- // await this.web3modal.disconnect();
126- // }
127- // }
128-
129- // export default new WalletConnect();
1+ import { createAppKit , Provider } from '@reown/appkit'
2+ import { Ethers5Adapter } from '@reown/appkit-adapter-ethers5'
3+ import { mainnet , sepolia , arbitrum , arbitrumSepolia , optimism , optimismSepolia , solana , solanaTestnet , bitcoin , bitcoinTestnet , bsc , bscTestnet , polygon } from "@reown/appkit/networks"
4+ import { constants } from './constants'
5+ import { EventEmitter } from 'events'
6+
7+ export interface RequestArguments {
8+ readonly method : string
9+ readonly params ?: readonly unknown [ ] | object
10+ readonly id ?: number
11+ }
12+
13+ export type Chain = {
14+ chainId : number
15+ name : string
16+ currency : string
17+ explorerUrl : string
18+ rpcUrl : string
19+ }
20+
21+ export class WalletConnect {
22+ appkit : ReturnType < typeof createAppKit >
23+ chains : Chain [ ]
24+ currentChain : string | number
25+ currentAccount : string
26+ events : EventEmitter
27+
28+ constructor ( ) {
29+ this . appkit = createAppKit ( {
30+ adapters : [ new Ethers5Adapter ( ) ] ,
31+ projectId : constants . PROJECT_ID ,
32+ metadata : constants . METADATA ,
33+ networks : [ mainnet , sepolia , arbitrum , arbitrumSepolia , optimism , optimismSepolia , solana , solanaTestnet , bitcoin , bitcoinTestnet , bsc , bscTestnet , polygon ]
34+ } )
35+ this . chains = constants . chains
36+ this . events = new EventEmitter ( )
37+ }
38+
39+ onActivation ( ) {
40+ this . subscribeToEvents ( )
41+ }
42+
43+ async init ( ) {
44+ console . log ( 'initializing walletconnect plugin...' )
45+ }
46+
47+ async openModal ( ) {
48+ if ( this . isWalletConnected ( ) ) return await this . appkit . open ( )
49+ await this . appkit . open ( )
50+ }
51+
52+ isWalletConnected ( ) {
53+ const isConnected = this . appkit . getIsConnectedState ( )
54+
55+ return isConnected
56+ }
57+
58+ subscribeToEvents ( ) {
59+ this . appkit . subscribeState ( async ( state ) => {
60+ if ( ! state . open ) {
61+ this . events . emit ( 'closeModal' )
62+ try {
63+ const provider = await this . appkit . getProvider ( this . appkit . chainNamespaces [ 0 ] )
64+ if ( provider ) {
65+ this . events . emit ( 'connectionSuccessful' )
66+ }
67+ } catch ( error ) {
68+ this . events . emit ( 'connectionFailed' , error . message )
69+ }
70+ }
71+ } )
72+
73+ this . appkit . subscribeNetwork ( ( network ) => {
74+ const address = this . appkit . getAddress ( )
75+ if ( this . isWalletConnected ( ) ) {
76+ if ( address !== this . currentAccount ) {
77+ this . currentAccount = address
78+ this . events . emit ( 'accountsChanged' , [ address ] )
79+ }
80+ if ( this . currentChain !== network . chainId ) {
81+ this . currentChain = network . chainId
82+ this . events . emit ( 'chainChanged' , network . chainId )
83+ }
84+ } else {
85+ this . events . emit ( 'accountsChanged' , [ ] )
86+ this . currentAccount = ''
87+ this . events . emit ( 'chainChanged' , 0 )
88+ this . currentChain = 0
89+ }
90+ } )
91+
92+ this . appkit . subscribeEvents ( ( eventPayload ) => {
93+ if ( eventPayload . data . event === 'CONNECT_SUCCESS' ) {
94+ this . events . emit ( 'connectionSuccessful' , 'Connection successful' )
95+ } else if ( eventPayload . data . event === 'CONNECT_ERROR' ) {
96+ this . events . emit ( 'connectionFailed' , 'Connection failed' )
97+ } else if ( eventPayload . data . event === 'DISCONNECT_SUCCESS' ) {
98+ this . events . emit ( 'connectionDisconnected' , 'Connection disconnected' )
99+ }
100+ } )
101+ }
102+
103+ async sendAsync ( data : RequestArguments ) : Promise < { jsonrpc : string , result ?: any , error ?: any , id : number } > {
104+ const providerType = this . appkit . getProviderType ( this . appkit . chainNamespaces [ 0 ] )
105+
106+ if ( providerType === 'ANNOUNCED' ) {
107+ return this . sendAnnouncedRequest ( data )
108+ } else if ( providerType === 'WALLET_CONNECT' ) {
109+ return this . sendWalletConnectRequest ( data )
110+ } else {
111+ const err = `Cannot make ${ data . method } request. Remix client is not connected to walletconnect client`
112+ console . error ( err )
113+ return { jsonrpc : '2.0' , error : { message : err , code : - 32603 } , id : data . id }
114+ }
115+
116+ }
117+
118+ async sendAnnouncedRequest ( data : RequestArguments ) : Promise < { jsonrpc : string , result ?: any , error ?: any , id : number } > {
119+ const address = this . appkit . getAddress ( )
120+ const provider = this . appkit . getProvider < Provider > ( this . appkit . chainNamespaces [ 0 ] )
121+
122+ if ( data . method === 'eth_accounts' ) {
123+ return {
124+ jsonrpc : '2.0' ,
125+ result : [ address ] ,
126+ id : data . id
127+ }
128+ }
129+ return new Promise ( ( resolve ) => {
130+ //@ts -expect-error sendAsync is a legacy function we know MetaMask supports it
131+ provider . sendAsync ( data , ( error , response ) => {
132+ if ( error ) {
133+ if ( error . data && error . data . originalError && error . data . originalError . data ) {
134+ resolve ( {
135+ jsonrpc : '2.0' ,
136+ error : error . data . originalError ,
137+ id : data . id
138+ } )
139+ } else if ( error . data && error . data . message ) {
140+ resolve ( {
141+ jsonrpc : '2.0' ,
142+ error : error . data && error . data ,
143+ id : data . id
144+ } )
145+ } else {
146+ resolve ( {
147+ jsonrpc : '2.0' ,
148+ error,
149+ id : data . id
150+ } )
151+ }
152+ }
153+ return resolve ( response )
154+ } )
155+ } )
156+ }
157+
158+ async sendWalletConnectRequest ( data : RequestArguments ) : Promise < { jsonrpc : string , result ?: any , error ?: any , id : number } > {
159+ const provider = this . appkit . getProvider < Provider > ( this . appkit . chainNamespaces [ 0 ] )
160+ const address = this . appkit . getAddress ( )
161+
162+ if ( data . method === 'eth_accounts' ) {
163+ return {
164+ jsonrpc : '2.0' ,
165+ result : [ address ] ,
166+ id : data . id
167+ }
168+ }
169+
170+ try {
171+ const message = await provider . request ( data )
172+ return { jsonrpc : '2.0' , result : message , id : data . id }
173+ } catch ( e ) {
174+ return { jsonrpc : '2.0' , error : { message : e . message , code : - 32603 } , id : data . id }
175+ }
176+ }
177+
178+ async deactivate ( ) {
179+ console . log ( 'deactivating walletconnect plugin...' )
180+ }
181+ }
182+
183+ export default new WalletConnect ( )
0 commit comments