fix bug in injected and external provider

pull/3356/head
yann300 2 years ago
parent 3744c7dc00
commit f3bb8ea519
  1. 52
      apps/remix-ide/src/app/providers/abstract-provider.tsx
  2. 4
      apps/remix-ide/src/app/providers/injected-provider.tsx

@ -21,36 +21,28 @@ export type SuccessRequest = (data: JsonDataResult) => void
export abstract class AbstractProvider extends Plugin {
provider: ethers.providers.JsonRpcProvider
blocked: boolean
blockchain: Blockchain
defaultUrl: string
connected: boolean
nodeUrl: string
constructor (profile, blockchain, defaultUrl) {
super(profile)
this.defaultUrl = defaultUrl
this.provider = null
this.blocked = false // used to block any call when trying to recover after a failed connection.
this.connected = false
this.blockchain = blockchain
this.nodeUrl = 'http://localhost:8545'
}
abstract body(): JSX.Element
onDeactivation () {
this.provider = null
this.blocked = false
}
sendAsync (data: JsonDataRequest): Promise<any> {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
if (this.blocked) return reject(new Error('provider unable to connect'))
// If provider is not set, allow to open modal only when provider is trying to connect
if (!this.provider) {
let value: string
try {
value = await ((): Promise<string> => {
async init () {
this.nodeUrl = await ((): Promise<string> => {
return new Promise((resolve, reject) => {
const modalContent: AppModal = {
id: this.profile.name,
@ -87,39 +79,20 @@ export abstract class AbstractProvider extends Plugin {
this.call('notification', 'modal', modalContent)
})
})()
} catch (e) {
// the modal has been canceled/hide
const result = data.method === 'net_listening' ? 'canceled' : []
resolve({ jsonrpc: '2.0', result: result, id: data.id })
this.switchAway(false)
return
this.provider = new ethers.providers.JsonRpcProvider(this.nodeUrl)
}
this.provider = new ethers.providers.JsonRpcProvider(value)
try {
setTimeout(() => {
if (!this.connected) {
this.switchAway(true)
reject('Unable to connect')
}
}, 2000)
await this.provider.detectNetwork() // this throws if the network cannot be detected
this.connected = true
} catch (e) {
this.switchAway(true)
reject('Unable to connect')
return
}
this.sendAsyncInternal(data, resolve, reject)
} else {
sendAsync (data: JsonDataRequest): Promise<any> {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
if (!this.provider) return reject(new Error('provider node set'))
this.sendAsyncInternal(data, resolve, reject)
}
})
}
private async switchAway (showError) {
if (!this.provider) return
this.provider = null
this.blocked = true
this.connected = false
if (showError) {
const modalContent: AlertModal = {
@ -130,16 +103,11 @@ export abstract class AbstractProvider extends Plugin {
this.call('notification', 'alert', modalContent)
}
await this.call('udapp', 'setEnvironmentMode', { context: 'vm-london'})
setTimeout(_ => { this.blocked = false }, 1000) // we wait 1 second for letting remix to switch to vm
return
}
private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise<void> {
if (this.provider) {
// Check the case where current environment is VM on UI and it still sends RPC requests
// This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!'
if (this.blockchain.getProvider() !== this.profile.displayName && data.method !== 'net_listening') return reject(new Error('Environment Updated !!'))
try {
const result = await this.provider.send(data.method, data.params)
resolve({ jsonrpc: '2.0', result, id: data.id })

@ -16,8 +16,8 @@ export class InjectedProvider extends Plugin {
}
askPermission (throwIfNoInjectedProvider) {
if (typeof (window as any).ethereum !== "undefined" && typeof (window as any).request === "function") {
(window as any).request({ method: "eth_requestAccounts" })
if ((typeof (window as any).ethereum) !== "undefined" && (typeof (window as any).ethereum.request) === "function") {
(window as any).ethereum.request({ method: "eth_requestAccounts" })
} else if (throwIfNoInjectedProvider) {
throw new Error(noInjectedProviderMsg)
}

Loading…
Cancel
Save