From b79e37f9b63c334eaaa1f604f4c0da43161b5965 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 3 Nov 2023 16:49:27 +0100 Subject: [PATCH 1/9] add more type for safety --- .../src/app/providers/abstract-provider.tsx | 13 +++++++++---- .../src/app/providers/injected-provider.tsx | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/apps/remix-ide/src/app/providers/abstract-provider.tsx b/apps/remix-ide/src/app/providers/abstract-provider.tsx index a5185b6129f..ea4cc5e281b 100644 --- a/apps/remix-ide/src/app/providers/abstract-provider.tsx +++ b/apps/remix-ide/src/app/providers/abstract-provider.tsx @@ -14,11 +14,15 @@ export type JsonDataResult = { id: number jsonrpc: string // version result?: any - error?: any + error?: { + code: number, + message: string + data?: string + } errorData?: any } -export type RejectRequest = (error: Error) => void +export type RejectRequest = (error: JsonDataResult) => void export type SuccessRequest = (data: JsonDataResult) => void export interface IProvider { @@ -98,7 +102,7 @@ export abstract class AbstractProvider extends Plugin implements IProvider { sendAsync(data: JsonDataRequest): Promise { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { - if (!this.provider) return reject(new Error('provider node set')) + if (!this.provider) return reject({jsonrpc: '2.0', id: data.id, error: { message: 'provider node set', code: -32603 } } as JsonDataResult) this.sendAsyncInternal(data, resolve, reject) }) } @@ -128,7 +132,8 @@ export abstract class AbstractProvider extends Plugin implements IProvider { if (error && error.message && error.message.includes('net_version') && error.message.includes('SERVER_ERROR')) { this.switchAway(true) } - reject(error) + error.code = -32603 + reject({jsonrpc: '2.0', error, id: data.id}) } } else { const result = data.method === 'net_listening' ? 'canceled' : [] diff --git a/apps/remix-ide/src/app/providers/injected-provider.tsx b/apps/remix-ide/src/app/providers/injected-provider.tsx index a4273e0f31a..36c7e35774a 100644 --- a/apps/remix-ide/src/app/providers/injected-provider.tsx +++ b/apps/remix-ide/src/app/providers/injected-provider.tsx @@ -80,7 +80,7 @@ export abstract class InjectedProvider extends Plugin implements IProvider { this.call('notification', 'toast', 'No injected provider (e.g Metamask) has been found.') return resolve({ jsonrpc: '2.0', - error: 'no injected provider found', + error: { message: 'no injected provider found', code: -32603 }, id: data.id }) } @@ -89,7 +89,7 @@ export abstract class InjectedProvider extends Plugin implements IProvider { if (web3Provider.request) resultData = await web3Provider.request({method: data.method, params: data.params}) else if (web3Provider.send) resultData = await web3Provider.send(data.method, data.params) else { - resolve({jsonrpc: '2.0', error: 'provider not valid', id: data.id}) + resolve({jsonrpc: '2.0', error: { message: 'provider not valid', code: -32603 }, id: data.id}) return } if (resultData) { @@ -98,7 +98,7 @@ export abstract class InjectedProvider extends Plugin implements IProvider { } resolve({jsonrpc: '2.0', result: resultData, id: data.id}) } else { - resolve({jsonrpc: '2.0', error: 'no return data provided', id: data.id}) + resolve({jsonrpc: '2.0', result: null, id: data.id}) } } catch (error) { if (error.data && error.data.originalError && error.data.originalError.data) { From bb206ce62822b763fab83b29afe06e47c63aa94b Mon Sep 17 00:00:00 2001 From: yann300 Date: Sat, 4 Nov 2023 21:48:16 +0100 Subject: [PATCH 2/9] fix wallet connect --- apps/remix-ide/src/blockchain/blockchain.tsx | 18 +++++++--- .../src/services/WalletConnectRemixClient.ts | 33 ++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index fa210bb8fbd..69e90355264 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -940,12 +940,20 @@ export class Blockchain extends Plugin { cb(null, txResult, address, returnValue) } catch (error) { - if (this.isInjectedWeb3()) { - const errorMessage = error.innerError ? error.innerError.message : error.message - const errorData = error.innerError ? error.innerError.data : error.data + const buildError = async (errorMessage, errorData) => { const compiledContracts = await this.call('compilerArtefacts', 'getAllContractDatas') - const injectedError = txExecution.checkError({ errorMessage, errorData }, compiledContracts) - cb(injectedError.message) + return txExecution.checkError({ errorMessage, errorData }, compiledContracts) + } + let errorMessage + let errorData + if (error.innerError) { + errorMessage = error.innerError.message + errorData = error.innerError.data + cb((await buildError(errorMessage, errorData)).message) + } else if (error.message || error.data) { + errorMessage = error.message + errorData = error.data + cb((await buildError(errorMessage, errorData)).message) } else cb(error) } diff --git a/apps/walletconnect/src/services/WalletConnectRemixClient.ts b/apps/walletconnect/src/services/WalletConnectRemixClient.ts index 6f8b494d00a..2332c48c9ba 100644 --- a/apps/walletconnect/src/services/WalletConnectRemixClient.ts +++ b/apps/walletconnect/src/services/WalletConnectRemixClient.ts @@ -106,25 +106,40 @@ export class WalletConnectRemixClient extends PluginClient { if (provider.isMetaMask) { return new Promise((resolve) => { - provider.sendAsync(data, (err, response) => { - if (err) { - console.error(err) - return resolve({jsonrpc: '2.0', result: [], id: data.id}) + 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 { const message = await provider.request(data) - return {jsonrpc: '2.0', result: message, id: data.id} } } } else { - console.error( - `Cannot make ${data.method} request. Remix client is not connected to walletconnect client` - ) - return {jsonrpc: '2.0', result: [], id: data.id} + 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} } } From 06ea93a1cca959fe5ffb9dce70ded0f86c13dac9 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 6 Nov 2023 10:16:03 +0100 Subject: [PATCH 3/9] return error from gasEstimate if EvmError --- apps/remix-ide/src/app/tabs/web3-provider.js | 2 +- libs/remix-simulator/src/methods/transactions.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/web3-provider.js b/apps/remix-ide/src/app/tabs/web3-provider.js index 1d4655667bf..89b75287390 100644 --- a/apps/remix-ide/src/app/tabs/web3-provider.js +++ b/apps/remix-ide/src/app/tabs/web3-provider.js @@ -64,7 +64,7 @@ export class Web3ProviderModule extends Plugin { try { resultFn(null, await provider.sendAsync(payload)) } catch (e) { - resultFn(e.message) + resultFn(e.error ? new Error(e.error) : new Error(e)) } } else { reject(new Error('User denied permission')) diff --git a/libs/remix-simulator/src/methods/transactions.ts b/libs/remix-simulator/src/methods/transactions.ts index 25c751ed4d5..bdf26bfbc3e 100644 --- a/libs/remix-simulator/src/methods/transactions.ts +++ b/libs/remix-simulator/src/methods/transactions.ts @@ -159,6 +159,9 @@ export class Transactions { processTx(this.txRunnerInstance, payload, true, (error, value: VMexecutionResult) => { if (error) return cb(error) const result: RunTxResult = value.result + if (result.execResult && result.execResult.exceptionError && result.execResult.exceptionError.errorType === 'EvmError') { + return cb(result.execResult.exceptionError.error) + } if ((result as any).receipt?.status === '0x0' || (result as any).receipt?.status === 0) { try { const msg = `0x${result.execResult.returnValue.toString('hex') || '0'}` From fba123c36623cc94a3b96a8a5bcd60e970a312ee Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 6 Nov 2023 11:17:50 +0100 Subject: [PATCH 4/9] fix e2e test --- apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts index fc3253614d7..2c99c0a6d9a 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts @@ -132,7 +132,7 @@ module.exports = { .click('*[data-id="testTabCheckAllTests"]') .clickElementAtPosition('.singleTestLabel', 1) .scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]') - .waitForElementContainsText('*[data-id="testTabSolidityUnitTestsOutput"]', 'revert Deploy Failed', 120000) + .waitForElementContainsText('*[data-id="testTabSolidityUnitTestsOutput"]', 'contract deployment failed: revert', 120000) }, 'Should fail when parameters are passed to method in test contract #group3': function (browser: NightwatchBrowser) { From b4d8548633d4cf4ed31b21a7f0e169d3da2ec128 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 6 Nov 2023 13:31:07 +0100 Subject: [PATCH 5/9] fix printing context values --- libs/remix-ui/terminal/src/lib/components/Context.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/terminal/src/lib/components/Context.tsx b/libs/remix-ui/terminal/src/lib/components/Context.tsx index 1f06c16e2e9..12adc818860 100644 --- a/libs/remix-ui/terminal/src/lib/components/Context.tsx +++ b/libs/remix-ui/terminal/src/lib/components/Context.tsx @@ -47,7 +47,7 @@ const Context = ({opts, provider}: {opts; provider: string}) => {
- [block:{block} txIndex:{i}] + [block:{block.toString()} txIndex:{i.toString()}]
from: {from} @@ -76,7 +76,7 @@ const Context = ({opts, provider}: {opts; provider: string}) => {
- [block:{block} txIndex:{i}] + [block:{block.toString()} txIndex:{i.toString()}]
from: {from} From c8d86419a14446f24c423de5001dd9c79572c5f5 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 7 Nov 2023 10:29:56 +0100 Subject: [PATCH 6/9] add try/catch and increase polling interval --- .../src/services/WalletConnectRemixClient.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/walletconnect/src/services/WalletConnectRemixClient.ts b/apps/walletconnect/src/services/WalletConnectRemixClient.ts index 2332c48c9ba..bdbf84efcf7 100644 --- a/apps/walletconnect/src/services/WalletConnectRemixClient.ts +++ b/apps/walletconnect/src/services/WalletConnectRemixClient.ts @@ -59,7 +59,9 @@ export class WalletConnectRemixClient extends PluginClient { ] const {publicClient} = configureChains(this.chains, [ w3mProvider({projectId: PROJECT_ID}) - ]) + ], { + pollingInterval: 5000 + }) this.wagmiConfig = createConfig({ autoConnect: false, @@ -132,8 +134,12 @@ export class WalletConnectRemixClient extends PluginClient { }) }) } else { - const message = await provider.request(data) - return {jsonrpc: '2.0', result: message, id: data.id} + 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 { From 62960c5ac52b6f72f7ea62b8af962732f8f14443 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 7 Nov 2023 10:49:57 +0100 Subject: [PATCH 7/9] fix spamming the network --- .../walletconnect/src/services/WalletConnectRemixClient.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/walletconnect/src/services/WalletConnectRemixClient.ts b/apps/walletconnect/src/services/WalletConnectRemixClient.ts index bdbf84efcf7..b28cf448f7e 100644 --- a/apps/walletconnect/src/services/WalletConnectRemixClient.ts +++ b/apps/walletconnect/src/services/WalletConnectRemixClient.ts @@ -24,6 +24,7 @@ export class WalletConnectRemixClient extends PluginClient { chains: Chain[] currentChain: number internalEvents: EventManager + connected: boolean constructor() { super() @@ -76,13 +77,15 @@ export class WalletConnectRemixClient extends PluginClient { subscribeToEvents() { this.wagmiConfig.subscribe((event) => { - if (event.status === 'connected') { + if (event.status === 'connected' && !this.connected) { + this.connected = true this.emit('accountsChanged', [event.data.account]) if (this.currentChain !== event.data.chain.id) { this.currentChain = event.data.chain.id this.emit('chainChanged', event.data.chain.id) } - } else if (event.status === 'disconnected') { + } else if (event.status === 'disconnected' && this.connected) { + this.connected = false this.emit('accountsChanged', []) this.emit('chainChanged', 0) this.currentChain = 0 From 1cfe284e3dd597502f9c5f9ed709c713190bd80c Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 7 Nov 2023 12:56:20 +0100 Subject: [PATCH 8/9] fix event subscribing walletconnect --- .../src/services/WalletConnectRemixClient.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/walletconnect/src/services/WalletConnectRemixClient.ts b/apps/walletconnect/src/services/WalletConnectRemixClient.ts index b28cf448f7e..0a4ccc00460 100644 --- a/apps/walletconnect/src/services/WalletConnectRemixClient.ts +++ b/apps/walletconnect/src/services/WalletConnectRemixClient.ts @@ -24,7 +24,7 @@ export class WalletConnectRemixClient extends PluginClient { chains: Chain[] currentChain: number internalEvents: EventManager - connected: boolean + currentAcount: string constructor() { super() @@ -77,16 +77,18 @@ export class WalletConnectRemixClient extends PluginClient { subscribeToEvents() { this.wagmiConfig.subscribe((event) => { - if (event.status === 'connected' && !this.connected) { - this.connected = true - this.emit('accountsChanged', [event.data.account]) + if (event.status === 'connected') { + if (event.data.account !== this.currentAcount) { + this.currentAcount = event.data.account + this.emit('accountsChanged', [event.data.account]) + } if (this.currentChain !== event.data.chain.id) { this.currentChain = event.data.chain.id this.emit('chainChanged', event.data.chain.id) } - } else if (event.status === 'disconnected' && this.connected) { - this.connected = false + } else if (event.status === 'disconnected') { this.emit('accountsChanged', []) + this.currentAcount = '' this.emit('chainChanged', 0) this.currentChain = 0 } From 3d4759720ccb3752d23498e3aca722a71acc6ed3 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 7 Nov 2023 13:14:11 +0100 Subject: [PATCH 9/9] contine polling if contract address not available --- libs/remix-lib/src/execution/txRunnerWeb3.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libs/remix-lib/src/execution/txRunnerWeb3.ts b/libs/remix-lib/src/execution/txRunnerWeb3.ts index 0ddd2fdc3dc..cd4a42ae386 100644 --- a/libs/remix-lib/src/execution/txRunnerWeb3.ts +++ b/libs/remix-lib/src/execution/txRunnerWeb3.ts @@ -175,16 +175,22 @@ export class TxRunnerWeb3 { } } -async function tryTillReceiptAvailable (txhash, web3) { +async function tryTillReceiptAvailable (txhash: string, web3: Web3) { try { const receipt = await web3.eth.getTransactionReceipt(txhash) - if (receipt) return receipt + if (receipt) { + if (!receipt.to && !receipt.contractAddress) { + // this is a contract creation and the receipt doesn't contain a contract address. we have to keep polling... + console.log('this is a contract creation and the receipt does nott contain a contract address. we have to keep polling...') + } else + return receipt + } } catch (e) {} await pause() return await tryTillReceiptAvailable(txhash, web3) } -async function tryTillTxAvailable (txhash, web3) { +async function tryTillTxAvailable (txhash: string, web3: Web3) { try { const tx = await web3.eth.getTransaction(txhash) if (tx && tx.blockHash) return tx