Skip to content

Commit

Permalink
refactor: reduce block number queries (#3511)
Browse files Browse the repository at this point in the history
* chore: update weth address

* refactor: move chain state to wallet plugin

* chore: add useStartWatchChainState

* fix: fetch balance if wallet is just created

* refactor: batch requests

* refactor: remove unused deps

Co-authored-by: Jack Works <[email protected]>

* refactor: reply reviews

* fix: chain name

Co-authored-by: Jack Works <[email protected]>
  • Loading branch information
guanbinrui and Jack-Works committed Jun 29, 2021
1 parent c74a884 commit ed441b6
Show file tree
Hide file tree
Showing 15 changed files with 145 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ export * from './EthereumServices/network'
export * from './EthereumServices/provider'
export * from './EthereumServices/tokenList'
export * from './EthereumServices/nonce'
export * from './EthereumServices/chainState'

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import { safeUnreachable } from '@dimensiondev/maskbook-shared'
import { createWeb3 } from './web3'
import * as WalletConnect from './providers/WalletConnect'
import { currentAccountSettings, currentProviderSettings } from '../../../plugins/Wallet/settings'
import { addRecentTransaction } from '../../../plugins/Wallet/services'
import { addRecentTransaction, getWallet } from '../../../plugins/Wallet/services'
import { commitNonce, getNonce, resetNonce } from './nonce'
import { getWalletCached } from './wallet'
import { getGasPrice } from './network'
import { EthereumAddress } from 'wallet.ts'

Expand All @@ -26,10 +25,13 @@ export async function INTERNAL_send(
console.log(new Error().stack)
}

const web3 = createWeb3()
const account = currentAccountSettings.value
const provider = web3.currentProvider as HttpProvider | undefined
const providerType = currentProviderSettings.value
const wallet = providerType === ProviderType.Maskbook ? await getWallet() : null
const web3 = createWeb3({
privKeys: wallet?._private_key_ ? [wallet._private_key_] : [],
})
const provider = web3.currentProvider as HttpProvider | undefined

// unable to create provider
if (!provider) {
Expand Down Expand Up @@ -92,7 +94,6 @@ export async function INTERNAL_send(
// send the transaction
switch (providerType) {
case ProviderType.Maskbook:
const wallet = getWalletCached()
const _private_key_ = wallet?._private_key_
if (!wallet || !_private_key_) throw new Error('Unable to sign transaction.')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ import * as Maskbook from './providers/Maskbook'
import * as MetaMask from './providers/MetaMask'
import * as WalletConnect from './providers/WalletConnect'
import { currentChainIdSettings, currentProviderSettings } from '../../../plugins/Wallet/settings'
import { getWalletCached } from './wallet'

export function createWeb3({
chainId = currentChainIdSettings.value,
providerType = currentProviderSettings.value,
privKeys = [] as string[],
} = {}) {
switch (providerType) {
case ProviderType.Maskbook:
const _private_key_ = getWalletCached()?._private_key_
return Maskbook.createWeb3({
chainId,
privKeys: _private_key_ ? [_private_key_] : [],
privKeys,
})
case ProviderType.MetaMask:
return MetaMask.createWeb3()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ export async function restoreBackup(json: object, whoAmI?: ProfileIdentifier) {
})
}

for (const x of data.wallets) {
for (const [i, x] of data.wallets.entries()) {
const record = WalletRecordFromJSONFormat(x)
if (record.mnemonic || record._private_key_) await importNewWallet(record)
if (record.mnemonic || record._private_key_) await importNewWallet(record, i !== 0)
}

for (const x of data.posts) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function ViewDetailed(props: ViewDetailedProps) {
chainId={getChainIdFromName(asset.chain)}
/>
<Typography className={classes.name}>{asset.token.symbol}</Typography>
{asset.chain !== chainDetailed.chain.toLowerCase() ? (
{asset.chain !== chainDetailed.shortName.toLowerCase() ? (
<Chip className={classes.chain} label={asset.chain} size="small" />
) : null}
</Box>,
Expand Down
2 changes: 2 additions & 0 deletions packages/maskbook/src/plugins/Wallet/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export const PLUGIN_IDENTIFIER = 'com.maskbook.wallet'

// Private key at m/purpose'/coin_type'/account'/change
export const HD_PATH_WITHOUT_INDEX_ETHEREUM = "m/44'/60'/0'/0"

export const UPDATE_CHAIN_STATE_DELAY = 30 /* seconds */ * 1000 /* milliseconds */
3 changes: 3 additions & 0 deletions packages/maskbook/src/plugins/Wallet/define.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { WalletConnectQRCodeDialog } from './UI/WalletConnectQRCodeDialog'
import { WalletStatusDialog } from './UI/WalletStatusDialog'
import { WalletRenameWalletDialog } from './UI/RenameWalletDialog'
import { ConnectWalletDialog } from './UI/ConnectWalletDialog'
import { useStartWatchChainState } from './hooks/useStartWatchChainState'

export const WalletPluginDefine: PluginConfig = {
id: PLUGIN_IDENTIFIER,
Expand All @@ -19,6 +20,7 @@ export const WalletPluginDefine: PluginConfig = {
stage: PluginStage.Production,
scope: PluginScope.Internal,
PageComponent() {
useStartWatchChainState()
return (
<>
<SelectWalletDialog />
Expand All @@ -34,6 +36,7 @@ export const WalletPluginDefine: PluginConfig = {
)
},
DashboardComponent() {
useStartWatchChainState()
return (
<>
<SelectWalletDialog />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { useAssetsMerged } from './useAssetsMerged'
export function useAssetsFromChain(tokens: FungibleTokenDetailed[]) {
const chainDetailed = useChainDetailed()
const { value: listOfBalance = [], loading, error, retry } = useTokensBalance(tokens.map((y) => y.address))

return {
value: useAssetsMerged(
// the length not matched in case of error occurs
listOfBalance.length === tokens.length
? listOfBalance.map(
(balance, idx): Asset => ({
chain: chainDetailed?.chain.toLowerCase() ?? 'eth',
chain: chainDetailed?.shortName.toLowerCase() ?? 'eth',
token: tokens[idx],
balance,
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useEffect } from 'react'
import { pollingTask } from '../../../utils'
import { UPDATE_CHAIN_STATE_DELAY } from '../constants'
import { WalletRPC } from '../messages'

const task = pollingTask(
async () => {
await WalletRPC.kickToUpdateChainState()
return false
},
{
autoStart: false,
delay: UPDATE_CHAIN_STATE_DELAY,
},
)

export function useStartWatchChainState() {
useEffect(() => {
// emit an updating request immediately
WalletRPC.updateChainState()
}, [])
return useEffect(() => {
// start the polling task
task.reset()
return () => task.cancel()
}, [])
}
75 changes: 75 additions & 0 deletions packages/maskbook/src/plugins/Wallet/services/chain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { ChainId, getNetworkTypeFromChainId, ProviderType } from '@dimensiondev/web3-shared'
import { getBalance, getBlockNumber, resetAllNonce } from '../../../extension/background-script/EthereumService'
import { pollingTask, startEffects } from '../../../utils'
import {
currentAccountSettings,
currentBalanceSettings,
currentBlockNumberSettings,
currentChainIdSettings,
currentNetworkSettings,
currentProviderSettings,
} from '../settings'
import { UPDATE_CHAIN_STATE_DELAY } from '../constants'
import { getWallet } from './wallet'

const beats: true[] = []

export async function kickToUpdateChainState() {
beats.push(true)
}

export async function updateChainState(chainId?: ChainId) {
// reset the polling task cause it will be called from service call
resetPoolTask()

// forget those passed beats
beats.length = 0

// update network type
if (chainId) currentNetworkSettings.value = getNetworkTypeFromChainId(chainId)

// update chain state
try {
const wallet = await getWallet()
;[currentBlockNumberSettings.value, currentBalanceSettings.value] = await Promise.all([
getBlockNumber(),
wallet ? getBalance(wallet.address) : currentBalanceSettings.value,
])
} catch (error) {
// do nothing
} finally {
// reset the polling if chain state updated successfully
resetPoolTask()
}
}

let resetPoolTask: () => void = () => {}

const effect = startEffects(import.meta.webpackHot)

// poll the newest chain state
effect(() => {
const { reset, cancel } = pollingTask(
async () => {
if (beats.length <= 0) return false
await updateChainState()
return false
},
{
delay: UPDATE_CHAIN_STATE_DELAY,
},
)
resetPoolTask = reset
return cancel
})

// revalidate chain state if the chainId of current provider was changed
effect(() =>
currentChainIdSettings.addListener((chainId) => {
updateChainState(chainId)
if (currentProviderSettings.value === ProviderType.Maskbook) resetAllNonce()
}),
)

// revalidate chain state if the current wallet was changed
effect(() => currentAccountSettings.addListener(() => updateChainState()))
1 change: 1 addition & 0 deletions packages/maskbook/src/plugins/Wallet/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './erc1155'
export * from './assets'
export * from './transactions'
export * from './recentTransactions'
export * from './chain'
9 changes: 6 additions & 3 deletions packages/maskbook/src/plugins/Wallet/services/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export function createMnemonicWords() {

export async function importNewWallet(
rec: PartialRequired<Omit<WalletRecord, 'id' | 'eth_balance' | 'createdAt' | 'updatedAt'>, 'name'>,
slient = false,
) {
const { name, path, mnemonic = [], passphrase = '' } = rec
const address = await getWalletAddress()
Expand Down Expand Up @@ -167,9 +168,11 @@ export async function importNewWallet(
else if (!record_.mnemonic.length && !record_._private_key_)
await t.objectStore('Wallet').put(WalletRecordIntoDB(record))
}
WalletMessages.events.walletsUpdated.sendToAll(undefined)
currentAccountSettings.value = record.address
currentProviderSettings.value = ProviderType.Maskbook
if (!slient) {
WalletMessages.events.walletsUpdated.sendToAll(undefined)
currentAccountSettings.value = record.address
currentProviderSettings.value = ProviderType.Maskbook
}
return address
async function getWalletAddress() {
if (rec.address) return rec.address
Expand Down
25 changes: 17 additions & 8 deletions packages/maskbook/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,16 @@ export function batchReplace(source: string, group: Array<[string | RegExp, stri
export function pollingTask(
task: () => Promise<boolean>,
{
autoStart = true,
delay = 30 * 1000,
}: {
autoStart?: boolean
delay?: number
} = {},
) {
let canceled = false
let canceled = !autoStart
let timer: NodeJS.Timeout

const runTask = async () => {
if (canceled) return
let stop = false
Expand All @@ -146,15 +149,21 @@ export function pollingTask(
} catch (e) {
console.error(e)
}
if (!stop) timer = setTimeout(runTask, delay)
if (!stop) resetTask()
}
const resetTask = () => {
canceled = false
clearTimeout(timer)
timer = setTimeout(runTask, delay)
}
runTask()
const cancelTask = () => {
canceled = true
}

if (!canceled) runTask()
return {
cancel: () => (canceled = true),
reset: () => {
clearTimeout(timer)
timer = setTimeout(runTask, delay)
},
reset: resetTask,
cancel: cancelTask,
}
}
export function addUint8Array(a: ArrayBuffer, b: ArrayBuffer) {
Expand Down
2 changes: 1 addition & 1 deletion packages/web3-shared/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const CONSTANTS = {
[ChainId.Ropsten]: '0xc778417E063141139Fce010982780140Aa0cD5Ab',
[ChainId.Rinkeby]: '0xc778417E063141139Fce010982780140Aa0cD5Ab',
[ChainId.Kovan]: '0xd0A1E359811322d97991E03f863a0C30C2cF029C',
[ChainId.Gorli]: '',
[ChainId.Gorli]: '0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6',
[ChainId.BSC]: '',
[ChainId.BSCT]: '',
[ChainId.Matic]: '',
Expand Down

0 comments on commit ed441b6

Please sign in to comment.