From 4d51f9294d01e2cd520a3093f8a01ab48d4390fa Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Sun, 12 Jun 2022 13:56:44 +0800 Subject: [PATCH 1/4] chore: add balance & blocknumber notifier --- .../src/web3-state/BalanceNotifier.ts | 6 ++++++ .../src/web3-state/BlockNumberNotifier.ts | 6 ++++++ packages/plugin-infra/src/web3-state/index.ts | 2 ++ packages/plugin-infra/src/web3-types.ts | 4 ++++ packages/plugin-infra/src/web3/useBalance.ts | 18 +++++++++++++++- .../plugin-infra/src/web3/useBlockNumber.ts | 18 +++++++++++++++- .../plugins/EVM/src/state/BalanceNotifier.ts | 8 +++++++ .../EVM/src/state/BlockNumberNotifier.ts | 8 +++++++ .../Connection/middleware/Transaction.ts | 13 ++++++------ packages/plugins/EVM/src/state/index.ts | 5 ++++- packages/web3-shared/base/src/specs/index.ts | 21 +++++++++++++++++++ 11 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 packages/plugin-infra/src/web3-state/BalanceNotifier.ts create mode 100644 packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts create mode 100644 packages/plugins/EVM/src/state/BalanceNotifier.ts create mode 100644 packages/plugins/EVM/src/state/BlockNumberNotifier.ts diff --git a/packages/plugin-infra/src/web3-state/BalanceNotifier.ts b/packages/plugin-infra/src/web3-state/BalanceNotifier.ts new file mode 100644 index 000000000000..5a8e5bc4a661 --- /dev/null +++ b/packages/plugin-infra/src/web3-state/BalanceNotifier.ts @@ -0,0 +1,6 @@ +import { Emitter } from '@servie/events'; +import type { BalanceEvent, BalanceNotifierState as Web3BalanceNotifierState } from '@masknet/web3-shared-base' + +export class BalanceNotifierState implements Web3BalanceNotifierState { + emitter: Emitter> = new Emitter() +} diff --git a/packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts b/packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts new file mode 100644 index 000000000000..aa8ded6d5b18 --- /dev/null +++ b/packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts @@ -0,0 +1,6 @@ +import { Emitter } from '@servie/events'; +import type { BlockNumberEvent, BlockNumberNotifierState as Web3BlockNumberNotifierState } from '@masknet/web3-shared-base' + +export class BlockNumberNotifierState implements Web3BlockNumberNotifierState { + emitter: Emitter> = new Emitter() +} diff --git a/packages/plugin-infra/src/web3-state/index.ts b/packages/plugin-infra/src/web3-state/index.ts index 99c0423a4099..4c9aaf959530 100644 --- a/packages/plugin-infra/src/web3-state/index.ts +++ b/packages/plugin-infra/src/web3-state/index.ts @@ -12,3 +12,5 @@ export * from './Provider' export * from './Identity' export * from './Wallet' export * from './Others' +export * from './BalanceNotifier' +export * from './BlockNumberNotifier' diff --git a/packages/plugin-infra/src/web3-types.ts b/packages/plugin-infra/src/web3-types.ts index 2125d1b2213b..9a11303bbb1c 100644 --- a/packages/plugin-infra/src/web3-types.ts +++ b/packages/plugin-infra/src/web3-types.ts @@ -1,4 +1,6 @@ import type { + BalanceNotifierState, + BlockNumberNotifierState, NetworkDescriptor, ProviderDescriptor, AddressBookState, @@ -37,6 +39,8 @@ export declare namespace Web3Plugin { Web3Provider, > { AddressBook?: AddressBookState + BalanceNotifier?: BalanceNotifierState + BlockNumberNotifier?: BlockNumberNotifierState Hub?: HubState IdentityService?: IdentityServiceState NameService?: NameServiceState diff --git a/packages/plugin-infra/src/web3/useBalance.ts b/packages/plugin-infra/src/web3/useBalance.ts index 89d9ad950570..fe968037c83a 100644 --- a/packages/plugin-infra/src/web3/useBalance.ts +++ b/packages/plugin-infra/src/web3/useBalance.ts @@ -1,8 +1,11 @@ +import { useEffect } from 'react' import { useAsyncRetry } from 'react-use' +import { noop } from 'lodash-unified' import type { NetworkPluginID } from '@masknet/web3-shared-base' import type { Web3Helper } from '../web3-helpers' import { useAccount } from './useAccount' import { useWeb3Connection } from './useWeb3Connection' +import { useWeb3State } from '../entry-web3' export function useBalance( pluginID?: T, @@ -10,9 +13,22 @@ export function useBalance { + const asyncResult = useAsyncRetry(async () => { if (!account || !connection) return '0' return connection.getBalance(account) }, [account, connection]) + + useEffect(() => { + return ( + BalanceNotifier?.emitter.on('update', (ev) => { + if (Others?.isSameAddress(account, ev.account)) { + asyncResult.retry() + } + }) ?? noop + ) + }, [account, asyncResult.retry, BalanceNotifier, Others]) + + return asyncResult } diff --git a/packages/plugin-infra/src/web3/useBlockNumber.ts b/packages/plugin-infra/src/web3/useBlockNumber.ts index 5812548d48c2..e4fe7244ae60 100644 --- a/packages/plugin-infra/src/web3/useBlockNumber.ts +++ b/packages/plugin-infra/src/web3/useBlockNumber.ts @@ -1,8 +1,11 @@ +import { useEffect } from 'react' import { useAsyncRetry } from 'react-use' +import { noop } from 'lodash-unified' import type { NetworkPluginID } from '@masknet/web3-shared-base' import type { Web3Helper } from '../web3-helpers' import { useChainId } from './useChainId' import { useWeb3Connection } from './useWeb3Connection' +import { useWeb3State } from '../entry-web3' export function useBlockNumber( pluginID?: T, @@ -10,9 +13,22 @@ export function useBlockNumber { + const asyncRetry = useAsyncRetry(async () => { if (!connection) return 0 return connection.getBlockNumber() }, [chainId, connection]) + + useEffect(() => { + return ( + BlockNumberNotifier?.emitter.on('update', (actualChainId) => { + if (actualChainId === chainId) { + asyncRetry.retry() + } + }) ?? noop + ) + }, [chainId, asyncRetry, BlockNumberNotifier]) + + return asyncRetry } diff --git a/packages/plugins/EVM/src/state/BalanceNotifier.ts b/packages/plugins/EVM/src/state/BalanceNotifier.ts new file mode 100644 index 000000000000..5099835ba645 --- /dev/null +++ b/packages/plugins/EVM/src/state/BalanceNotifier.ts @@ -0,0 +1,8 @@ +import { BalanceNotifierState } from '@masknet/plugin-infra/web3' +import type { ChainId } from '@masknet/web3-shared-evm' + +export class BalanceNotifier extends BalanceNotifierState { + constructor() { + super() + } +} diff --git a/packages/plugins/EVM/src/state/BlockNumberNotifier.ts b/packages/plugins/EVM/src/state/BlockNumberNotifier.ts new file mode 100644 index 000000000000..1d5c2a4fe77b --- /dev/null +++ b/packages/plugins/EVM/src/state/BlockNumberNotifier.ts @@ -0,0 +1,8 @@ +import { BlockNumberNotifierState } from '@masknet/plugin-infra/web3' +import type { ChainId } from '@masknet/web3-shared-evm' + +export class BlockNumberNotifier extends BlockNumberNotifierState { + constructor() { + super() + } +} diff --git a/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts b/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts index c84f9195056e..394677c44ab3 100644 --- a/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts +++ b/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts @@ -15,13 +15,12 @@ export class RecentTransaction implements Middleware { switch (context.method) { case EthereumMethodType.ETH_SEND_TRANSACTION: if (!context.config || typeof context.result !== 'string') return - else - await Transaction?.addTransaction?.( - context.chainId, - context.account, - context.result, - context.config, - ) + await Transaction?.addTransaction?.( + context.chainId, + context.account, + context.result, + context.config, + ) TransactionWatcher?.watchTransaction(context.chainId, context.result, context.config) break case EthereumMethodType.ETH_GET_TRANSACTION_RECEIPT: diff --git a/packages/plugins/EVM/src/state/index.ts b/packages/plugins/EVM/src/state/index.ts index d803e681360d..606c9c0ffd55 100644 --- a/packages/plugins/EVM/src/state/index.ts +++ b/packages/plugins/EVM/src/state/index.ts @@ -14,6 +14,8 @@ import { TransactionFormatter } from './TransactionFormatter' import { TransactionWatcher } from './TransactionWatcher' import type { EVM_Web3State } from './Connection/types' import { IdentityService } from './IdentityService' +import { BalanceNotifier } from './BalanceNotifier' +import { BlockNumberNotifier } from './BlockNumberNotifier' export function createWeb3State(context: Plugin.Shared.SharedContext): EVM_Web3State { const Provider_ = new Provider(context) @@ -22,7 +24,8 @@ export function createWeb3State(context: Plugin.Shared.SharedContext): EVM_Web3S return { Settings: Settings_, Provider: Provider_, - + BalanceNotifier: new BalanceNotifier(), + BlockNumberNotifier: new BlockNumberNotifier(), AddressBook: new AddressBook(context, { chainId: Provider_.chainId, }), diff --git a/packages/web3-shared/base/src/specs/index.ts b/packages/web3-shared/base/src/specs/index.ts index a6af988f268c..c3ecc1c8b695 100644 --- a/packages/web3-shared/base/src/specs/index.ts +++ b/packages/web3-shared/base/src/specs/index.ts @@ -500,6 +500,17 @@ export interface Account { chainId: ChainId } + +export interface BalanceEvent { + /** Emit if the balance of the account updated. */ + update: [Account] +} + +export interface BlockNumberEvent { + /** Emit if the balance of the chain updated. */ + update: [ChainId] +} + export interface ProviderEvents { /** Emit when the chain id changed. */ chainId: [string] @@ -543,6 +554,7 @@ export interface ProviderOptions { export interface TransactionChecker { checkStatus(chainId: ChainId, id: string): Promise } + export interface ConnectionOptions { /** Designate the sub-network id of the transaction. */ chainId?: ChainId @@ -805,6 +817,7 @@ export interface SettingsState { /** The source type of non-fungible assets */ nonFungibleAssetSourceType?: Subscription } + export interface AddressBookState { /** The tracked addresses of currently chosen sub-network */ addressBook?: Subscription @@ -1011,3 +1024,11 @@ export interface OthersState { getAverageBlockDelay(chainId?: ChainId, scale?: number): number // #endregion } + +export interface BalanceNotifierState { + emitter: Emitter> +} + +export interface BlockNumberNotifierState { + emitter: Emitter> +} From 0913be2282d26b71a62f57e5eb1a5ebd01488018 Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Sun, 12 Jun 2022 14:17:22 +0800 Subject: [PATCH 2/4] chore: register notifier --- .../src/web3-state/BalanceNotifier.ts | 4 +-- .../src/web3-state/BlockNumberNotifier.ts | 7 +++-- .../Connection/middleware/Transaction.ts | 31 +++++++++++++------ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/plugin-infra/src/web3-state/BalanceNotifier.ts b/packages/plugin-infra/src/web3-state/BalanceNotifier.ts index 5a8e5bc4a661..5a9be83741c9 100644 --- a/packages/plugin-infra/src/web3-state/BalanceNotifier.ts +++ b/packages/plugin-infra/src/web3-state/BalanceNotifier.ts @@ -1,6 +1,6 @@ -import { Emitter } from '@servie/events'; +import { Emitter } from '@servie/events' import type { BalanceEvent, BalanceNotifierState as Web3BalanceNotifierState } from '@masknet/web3-shared-base' -export class BalanceNotifierState implements Web3BalanceNotifierState { +export class BalanceNotifierState implements Web3BalanceNotifierState { emitter: Emitter> = new Emitter() } diff --git a/packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts b/packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts index aa8ded6d5b18..0d906c1edd1f 100644 --- a/packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts +++ b/packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts @@ -1,5 +1,8 @@ -import { Emitter } from '@servie/events'; -import type { BlockNumberEvent, BlockNumberNotifierState as Web3BlockNumberNotifierState } from '@masknet/web3-shared-base' +import { Emitter } from '@servie/events' +import type { + BlockNumberEvent, + BlockNumberNotifierState as Web3BlockNumberNotifierState, +} from '@masknet/web3-shared-base' export class BlockNumberNotifierState implements Web3BlockNumberNotifierState { emitter: Emitter> = new Emitter() diff --git a/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts b/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts index 394677c44ab3..84d1281ed876 100644 --- a/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts +++ b/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts @@ -7,7 +7,7 @@ import { Web3StateSettings } from '../../../settings' export class RecentTransaction implements Middleware { async fn(context: Context, next: () => Promise) { - const { Transaction, TransactionWatcher } = Web3StateSettings.value + const { Transaction, TransactionWatcher, BalanceNotifier, BlockNumberNotifier } = Web3StateSettings.value await next() @@ -26,14 +26,27 @@ export class RecentTransaction implements Middleware { case EthereumMethodType.ETH_GET_TRANSACTION_RECEIPT: const receipt = context.result as TransactionReceipt | null const status = getReceiptStatus(receipt) - if (receipt?.transactionHash && status !== TransactionStatusType.NOT_DEPEND) { - await Transaction?.updateTransaction?.( - context.chainId, - context.account, - receipt.transactionHash, - status, - ) - } + if (!receipt?.transactionHash || status === TransactionStatusType.NOT_DEPEND) return + + // update in house transaction state + await Transaction?.updateTransaction?.( + context.chainId, + context.account, + receipt.transactionHash, + status, + ) + + // update built-in notifier + BalanceNotifier?.emitter.emit('update', { + account: receipt.from, + chainId: context.chainId, + }) + BalanceNotifier?.emitter.emit('update', { + // it could be a contract address, but it doesn't matter + account: receipt.to, + chainId: context.chainId, + }) + BlockNumberNotifier?.emitter.emit('update', context.chainId) break case EthereumMethodType.MASK_REPLACE_TRANSACTION: if (!context.config || typeof context.result !== 'string') return From c69388789dd2dc7a5871209565a6ed7871b6fbf1 Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Sun, 12 Jun 2022 18:25:08 +0800 Subject: [PATCH 3/4] refactor: reduce rpc requests --- .../background/services/helper/r2d2Fetch.ts | 3 +- .../mask/src/plugins/Gitcoin/constants.ts | 2 +- .../mask/src/web3/UI/TokenAmountPanel.tsx | 3 ++ packages/plugin-infra/src/web3/useBalance.ts | 8 +++--- .../plugin-infra/src/web3/useBlockNumber.ts | 6 ++-- .../src/web3/useFungibleTokenBalance.ts | 28 ++++++++++++++++--- .../EVM/src/state/Connection/connection.ts | 6 ++-- .../src/state/Connection/middleware/Squash.ts | 13 ++++++++- .../Connection/middleware/Transaction.ts | 9 ++++-- .../src/state/Connection/providers/Base.ts | 4 +-- packages/web3-shared/evm/utils/contract.ts | 2 -- packages/web3-shared/evm/utils/provider.ts | 12 +++++++- 12 files changed, 71 insertions(+), 25 deletions(-) diff --git a/packages/mask/background/services/helper/r2d2Fetch.ts b/packages/mask/background/services/helper/r2d2Fetch.ts index 6b0aa6a51195..e6d499c57acd 100644 --- a/packages/mask/background/services/helper/r2d2Fetch.ts +++ b/packages/mask/background/services/helper/r2d2Fetch.ts @@ -41,7 +41,8 @@ export async function r2d2Fetch(input: RequestInfo, init?: RequestInit): Promise // r2d2 worker const r2deWorkerType = matchers.find((x) => url.startsWith(x[0]))?.[1] - if (r2deWorkerType) globalThis.fetch(url.replace(new URL(url).origin, `https://${r2deWorkerType}.${r2d2URL}`), init) + if (r2deWorkerType) + return globalThis.fetch(url.replace(new URL(url).origin, `https://${r2deWorkerType}.${r2d2URL}`), init) // fallback return globalThis.fetch(input, init) diff --git a/packages/mask/src/plugins/Gitcoin/constants.ts b/packages/mask/src/plugins/Gitcoin/constants.ts index d616143e0db8..d01cd68b0a9a 100644 --- a/packages/mask/src/plugins/Gitcoin/constants.ts +++ b/packages/mask/src/plugins/Gitcoin/constants.ts @@ -4,4 +4,4 @@ export const PLUGIN_ID = PluginId.Gitcoin export const PLUGIN_META_KEY = `${PluginId.Gitcoin}:1` export const PLUGIN_NAME = 'Gitcoin' export const PLUGIN_DESCRIPTION = 'Gitcoin grants sustain web3 projects with quadratic funding.' -export const GITCOIN_API_GRANTS_V1 = 'https://gitcoin.co/grants/v1/api/grant/:id' +export const GITCOIN_API_GRANTS_V1 = 'https://gitcoin.co/grants/v1/api/grant/:id/' diff --git a/packages/mask/src/web3/UI/TokenAmountPanel.tsx b/packages/mask/src/web3/UI/TokenAmountPanel.tsx index 299377356926..08546ca374a0 100644 --- a/packages/mask/src/web3/UI/TokenAmountPanel.tsx +++ b/packages/mask/src/web3/UI/TokenAmountPanel.tsx @@ -109,6 +109,9 @@ export function TokenAmountPanel(props: TokenAmountPanelProps) { type="text" value={amount} variant="outlined" + onKeyDown={(ev) => { + if (ev.key === 'Enter') ev.preventDefault() + }} onChange={onChange} placeholder="0.0" InputProps={{ diff --git a/packages/plugin-infra/src/web3/useBalance.ts b/packages/plugin-infra/src/web3/useBalance.ts index fe968037c83a..ac1dce24d6a3 100644 --- a/packages/plugin-infra/src/web3/useBalance.ts +++ b/packages/plugin-infra/src/web3/useBalance.ts @@ -4,6 +4,7 @@ import { noop } from 'lodash-unified' import type { NetworkPluginID } from '@masknet/web3-shared-base' import type { Web3Helper } from '../web3-helpers' import { useAccount } from './useAccount' +import { useChainId } from './useChainId' import { useWeb3Connection } from './useWeb3Connection' import { useWeb3State } from '../entry-web3' @@ -12,20 +13,19 @@ export function useBalance, ) { const account = useAccount(pluginID, options?.account) + const chainId = useChainId(pluginID, options?.chainId) const connection = useWeb3Connection(pluginID, options) const { BalanceNotifier, Others } = useWeb3State(pluginID) const asyncResult = useAsyncRetry(async () => { if (!account || !connection) return '0' return connection.getBalance(account) - }, [account, connection]) + }, [account, chainId, connection]) useEffect(() => { return ( BalanceNotifier?.emitter.on('update', (ev) => { - if (Others?.isSameAddress(account, ev.account)) { - asyncResult.retry() - } + if (Others?.isSameAddress(account, ev.account)) asyncResult.retry() }) ?? noop ) }, [account, asyncResult.retry, BalanceNotifier, Others]) diff --git a/packages/plugin-infra/src/web3/useBlockNumber.ts b/packages/plugin-infra/src/web3/useBlockNumber.ts index e4fe7244ae60..e7c8b012129d 100644 --- a/packages/plugin-infra/src/web3/useBlockNumber.ts +++ b/packages/plugin-infra/src/web3/useBlockNumber.ts @@ -23,12 +23,10 @@ export function useBlockNumber { return ( BlockNumberNotifier?.emitter.on('update', (actualChainId) => { - if (actualChainId === chainId) { - asyncRetry.retry() - } + if (actualChainId === chainId) asyncRetry.retry() }) ?? noop ) - }, [chainId, asyncRetry, BlockNumberNotifier]) + }, [chainId, asyncRetry.retry, BlockNumberNotifier]) return asyncRetry } diff --git a/packages/plugin-infra/src/web3/useFungibleTokenBalance.ts b/packages/plugin-infra/src/web3/useFungibleTokenBalance.ts index 632236dc4fc8..ebd686507357 100644 --- a/packages/plugin-infra/src/web3/useFungibleTokenBalance.ts +++ b/packages/plugin-infra/src/web3/useFungibleTokenBalance.ts @@ -1,6 +1,11 @@ -import type { NetworkPluginID } from '@masknet/web3-shared-base' +import { useEffect } from 'react' import useAsyncRetry from 'react-use/lib/useAsyncRetry' +import { noop } from 'lodash-unified' +import type { NetworkPluginID } from '@masknet/web3-shared-base' +import { useWeb3State } from '../entry-web3' import type { Web3Helper } from '../web3-helpers' +import { useAccount } from './useAccount' +import { useChainId } from './useChainId' import { useWeb3Connection } from './useWeb3Connection' export function useFungibleTokenBalance( @@ -8,10 +13,25 @@ export function useFungibleTokenBalance, ) { + const account = useAccount(pluginID, options?.account) + const chainId = useChainId(pluginID, options?.chainId) const connection = useWeb3Connection(pluginID, options) + const { BalanceNotifier, Others } = useWeb3State(pluginID) - return useAsyncRetry(async () => { - if (!connection || !address) return '0' + const asyncRetry = useAsyncRetry(async () => { + if (!connection) return '0' return connection.getFungibleTokenBalance(address ?? '', options) - }, [address, connection, JSON.stringify(options)]) + }, [account, address, chainId, connection, JSON.stringify(options)]) + + useEffect(() => { + return ( + BalanceNotifier?.emitter.on('update', (ev) => { + if (Others?.isSameAddress(account, ev.account)) { + asyncRetry.retry() + } + }) ?? noop + ) + }, [account, asyncRetry.retry, BalanceNotifier, Others]) + + return asyncRetry } diff --git a/packages/plugins/EVM/src/state/Connection/connection.ts b/packages/plugins/EVM/src/state/Connection/connection.ts index 93cc9c12d7fd..9fad27c77933 100644 --- a/packages/plugins/EVM/src/state/Connection/connection.ts +++ b/packages/plugins/EVM/src/state/Connection/connection.ts @@ -30,8 +30,10 @@ import { sendTransaction, createERC20Token, parseStringOrBytes32, + createWeb3, createWeb3Provider, getEthereumConstants, + isValidAddress, } from '@masknet/web3-shared-evm' import { Account, @@ -161,7 +163,7 @@ class Connection implements EVM_Connection { } getWeb3(options?: EVM_Web3ConnectionOptions) { - const web3 = new Web3( + const web3 = createWeb3( createWeb3Provider((requestArguments: RequestArguments) => this.hijackedRequest(requestArguments, options)), ) return Promise.resolve(web3) @@ -464,7 +466,7 @@ class Connection implements EVM_Connection { } async getNativeTokenBalance(options?: EVM_Web3ConnectionOptions): Promise { const account = options?.account ?? this.account - if (!account) return '0' + if (!isValidAddress(account)) return '0' return this.getBalance(options?.account ?? this.account, options) } async getFungibleTokenBalance(address: string, options?: EVM_Web3ConnectionOptions): Promise { diff --git a/packages/plugins/EVM/src/state/Connection/middleware/Squash.ts b/packages/plugins/EVM/src/state/Connection/middleware/Squash.ts index 54853d48b969..c80505f73e56 100644 --- a/packages/plugins/EVM/src/state/Connection/middleware/Squash.ts +++ b/packages/plugins/EVM/src/state/Connection/middleware/Squash.ts @@ -24,6 +24,13 @@ export class Squash implements Middleware { const [address, tag = 'latest'] = params as [string, string] return sha3([chainId, method, address, tag].join()) } + case EthereumMethodType.ETH_GET_BLOCK_BY_NUMBER: { + const [number, full] = params as [string, boolean] + return sha3([chainId, method, number, full].join()) + } + case EthereumMethodType.ETH_BLOCK_NUMBER: { + return sha3([chainId, method].join()) + } case EthereumMethodType.ETH_GET_BALANCE: case EthereumMethodType.ETH_GET_TRANSACTION_COUNT: const [account, tag = 'latest'] = params as [string, string] @@ -70,7 +77,11 @@ export class Squash implements Middleware { this.cache.set(id, promise) await next() - this.cache.delete(id) + + // keep cache for 1s + setTimeout(() => { + this.cache.delete(id) + }, 1000) if (context.error) reject(context.error) else resolve(context.result) diff --git a/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts b/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts index 84d1281ed876..f9281ef74731 100644 --- a/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts +++ b/packages/plugins/EVM/src/state/Connection/middleware/Transaction.ts @@ -8,6 +8,7 @@ import { Web3StateSettings } from '../../../settings' export class RecentTransaction implements Middleware { async fn(context: Context, next: () => Promise) { const { Transaction, TransactionWatcher, BalanceNotifier, BlockNumberNotifier } = Web3StateSettings.value + const isSquashed = typeof context.result !== 'undefined' await next() @@ -24,6 +25,8 @@ export class RecentTransaction implements Middleware { TransactionWatcher?.watchTransaction(context.chainId, context.result, context.config) break case EthereumMethodType.ETH_GET_TRANSACTION_RECEIPT: + if (isSquashed) return + const receipt = context.result as TransactionReceipt | null const status = getReceiptStatus(receipt) if (!receipt?.transactionHash || status === TransactionStatusType.NOT_DEPEND) return @@ -38,13 +41,13 @@ export class RecentTransaction implements Middleware { // update built-in notifier BalanceNotifier?.emitter.emit('update', { - account: receipt.from, chainId: context.chainId, + account: receipt.from, }) + // it could be a contract address, but it doesn't matter BalanceNotifier?.emitter.emit('update', { - // it could be a contract address, but it doesn't matter - account: receipt.to, chainId: context.chainId, + account: receipt.to, }) BlockNumberNotifier?.emitter.emit('update', context.chainId) break diff --git a/packages/plugins/EVM/src/state/Connection/providers/Base.ts b/packages/plugins/EVM/src/state/Connection/providers/Base.ts index 50387655eba5..9eaab06a55e7 100644 --- a/packages/plugins/EVM/src/state/Connection/providers/Base.ts +++ b/packages/plugins/EVM/src/state/Connection/providers/Base.ts @@ -5,6 +5,7 @@ import { Emitter } from '@servie/events' import type { Account, ProviderEvents, ProviderOptions } from '@masknet/web3-shared-base' import { chainResolver, + createWeb3, createWeb3Provider, ChainId, ProviderType, @@ -79,8 +80,7 @@ export class BaseProvider implements EVM_Provider { // Create a web3 instance from the external provider by default. async createWeb3(options?: ProviderOptions) { - // @ts-ignore - return new Web3(await this.createWeb3Provider(options)) + return createWeb3(await this.createWeb3Provider(options)) } // Create an external provider from the basic request method. diff --git a/packages/web3-shared/evm/utils/contract.ts b/packages/web3-shared/evm/utils/contract.ts index 2c2ecd4187a5..b05020353cb1 100644 --- a/packages/web3-shared/evm/utils/contract.ts +++ b/packages/web3-shared/evm/utils/contract.ts @@ -49,7 +49,5 @@ export async function sendTransaction( export function createContract(web3: Web3 | null, address: string, ABI: AbiItem[]) { if (!address || !isValidAddress(address) || !web3) return null const contract = new web3.eth.Contract(ABI, address) as unknown as T - contract.transactionConfirmationBlocks = 0 - contract.transactionPollingTimeout = 10 * 1000 return contract } diff --git a/packages/web3-shared/evm/utils/provider.ts b/packages/web3-shared/evm/utils/provider.ts index 7635f7db7cfc..4ec56364cdc1 100644 --- a/packages/web3-shared/evm/utils/provider.ts +++ b/packages/web3-shared/evm/utils/provider.ts @@ -1,7 +1,17 @@ -import type { RequestArguments } from 'web3-core' +import Web3 from 'web3' +import type { provider as Provider, RequestArguments } from 'web3-core' import type { JsonRpcPayload, JsonRpcResponse } from 'web3-core-helpers' import type { Web3Provider } from '../types' +export function createWeb3(provider: Provider) { + const web3 = new Web3(provider) + web3.eth.transactionBlockTimeout = 10 * 1000 + web3.eth.transactionPollingTimeout = 10 * 1000 + // @ts-ignore disable the default polling strategy + web3.eth.transactionPollingInterval = Number.MAX_SAFE_INTEGER + return web3 +} + export function createWeb3Provider(request: (requestArguments: RequestArguments) => Promise): Web3Provider { const provider: Web3Provider = { on() { From 6030fecdfed921df418b61204e9c858305337ecf Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Sun, 12 Jun 2022 18:31:05 +0800 Subject: [PATCH 4/4] fix: lint error --- packages/plugins/EVM/src/state/Connection/connection.ts | 1 - packages/plugins/EVM/src/state/Connection/providers/Base.ts | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/plugins/EVM/src/state/Connection/connection.ts b/packages/plugins/EVM/src/state/Connection/connection.ts index 9fad27c77933..a27dcc3221b8 100644 --- a/packages/plugins/EVM/src/state/Connection/connection.ts +++ b/packages/plugins/EVM/src/state/Connection/connection.ts @@ -1,4 +1,3 @@ -import Web3 from 'web3' import { AbiItem, numberToHex, toHex, toNumber } from 'web3-utils' import { first } from 'lodash-unified' import urlcat from 'urlcat' diff --git a/packages/plugins/EVM/src/state/Connection/providers/Base.ts b/packages/plugins/EVM/src/state/Connection/providers/Base.ts index 9eaab06a55e7..a83e3c05765a 100644 --- a/packages/plugins/EVM/src/state/Connection/providers/Base.ts +++ b/packages/plugins/EVM/src/state/Connection/providers/Base.ts @@ -1,6 +1,6 @@ -import Web3 from 'web3' import { toHex } from 'web3-utils' import type { RequestArguments } from 'web3-core' +import { delay } from '@dimensiondev/kit' import { Emitter } from '@servie/events' import type { Account, ProviderEvents, ProviderOptions } from '@masknet/web3-shared-base' import { @@ -14,7 +14,6 @@ import { NetworkType, } from '@masknet/web3-shared-evm' import type { EVM_Provider } from '../types' -import { delay } from '@dimensiondev/kit' export class BaseProvider implements EVM_Provider { emitter = new Emitter>()