-
Notifications
You must be signed in to change notification settings - Fork 937
/
WalletConnectRemixClient.ts
134 lines (125 loc) · 4.27 KB
/
WalletConnectRemixClient.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { PluginClient } from '@remixproject/plugin'
import { createClient } from '@remixproject/plugin-webview'
import { createWeb3Modal, defaultConfig } from '@web3modal/ethers5/react'
import { constants } from '../utils/constants'
import EventManager from 'events'
import { PROJECT_ID as projectId, METADATA as metadata } from './constant'
import { Chain, RequestArguments } from '../types'
export class WalletConnectRemixClient extends PluginClient {
web3modal: ReturnType<typeof createWeb3Modal>
ethersConfig: ReturnType<typeof defaultConfig>
chains: Chain[]
currentChain: number
internalEvents: EventManager
currentAccount: string
constructor() {
super()
createClient(this)
this.internalEvents = new EventManager()
this.methods = ['sendAsync', 'init', 'deactivate']
this.onload()
}
onActivation() {
this.subscribeToEvents()
this.call('theme', 'currentTheme').then((theme: any) => {
this.internalEvents.emit('themeChanged', theme.quality.toLowerCase())
})
}
init() {
console.log('initializing walletconnect plugin...')
}
initClient() {
try {
const ethersConfig = defaultConfig({
metadata,
rpcUrl: 'https://cloudflare-eth.com'
})
this.web3modal = createWeb3Modal({ projectId, chains: constants.chains, metadata, ethersConfig })
this.ethersConfig = ethersConfig
this.chains = constants.chains
} catch (e) {
return console.error('Could not get a wallet connection', e)
}
}
subscribeToEvents() {
this.web3modal.subscribeProvider(({ address, isConnected, chainId })=>{
if (isConnected){
if (address !== this.currentAccount) {
this.currentAccount = address
this.emit('accountsChanged', [address])
}
if (this.currentChain !== chainId) {
this.currentChain = chainId
this.emit('chainChanged', chainId)
}
} else {
this.emit('accountsChanged', [])
this.currentAccount = ''
this.emit('chainChanged', 0)
this.currentChain = 0
}
},)
this.on('theme', 'themeChanged', (theme: any) => {
this.web3modal.setThemeMode(theme.quality)
})
}
async sendAsync(data: RequestArguments) {
const address = this.web3modal.getAddress()
const provider = this.web3modal.getWalletProvider()
if (address && provider) {
if (data.method === 'eth_accounts') {
return {
jsonrpc: '2.0',
result: [address],
id: data.id
}
} else {
//@ts-expect-error this flag does not correspond to EIP-1193 but was introduced by MetaMask
if (provider.isMetamask && provider.sendAsync) {
return new Promise((resolve) => {
//@ts-expect-error sendAsync is a legacy function we know MetaMask supports it
provider.sendAsync(data, (error, response) => {
if (error) {
if (error.data && error.data.originalError && error.data.originalError.data) {
resolve({
jsonrpc: '2.0',
error: error.data.originalError,
id: data.id
})
} else if (error.data && error.data.message) {
resolve({
jsonrpc: '2.0',
error: error.data && error.data,
id: data.id
})
} else {
resolve({
jsonrpc: '2.0',
error,
id: data.id
})
}
}
return resolve(response)
})
})
} else {
try {
const message = await provider.request(data)
return { jsonrpc: '2.0', result: message, id: data.id }
} catch (e) {
return { jsonrpc: '2.0', error: { message: e.message, code: -32603 }, id: data.id }
}
}
}
} else {
const err = `Cannot make ${data.method} request. Remix client is not connected to walletconnect client`
console.error(err)
return { jsonrpc: '2.0', error: { message: err, code: -32603 }, id: data.id }
}
}
async deactivate() {
console.log('deactivating walletconnect plugin...')
await this.web3modal.disconnect()
}
}