Skip to content

Commit

Permalink
chore: add balance & blocknumber notifier
Browse files Browse the repository at this point in the history
  • Loading branch information
guanbinrui committed Jun 12, 2022
1 parent df90e51 commit 4d51f92
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 10 deletions.
6 changes: 6 additions & 0 deletions packages/plugin-infra/src/web3-state/BalanceNotifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Emitter } from '@servie/events';
import type { BalanceEvent, BalanceNotifierState as Web3BalanceNotifierState } from '@masknet/web3-shared-base'

export class BalanceNotifierState<ChainId> implements Web3BalanceNotifierState<ChainId> {
emitter: Emitter<BalanceEvent<ChainId>> = new Emitter()
}
6 changes: 6 additions & 0 deletions packages/plugin-infra/src/web3-state/BlockNumberNotifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Emitter } from '@servie/events';
import type { BlockNumberEvent, BlockNumberNotifierState as Web3BlockNumberNotifierState } from '@masknet/web3-shared-base'

export class BlockNumberNotifierState<ChainId> implements Web3BlockNumberNotifierState<ChainId> {
emitter: Emitter<BlockNumberEvent<ChainId>> = new Emitter()
}
2 changes: 2 additions & 0 deletions packages/plugin-infra/src/web3-state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ export * from './Provider'
export * from './Identity'
export * from './Wallet'
export * from './Others'
export * from './BalanceNotifier'
export * from './BlockNumberNotifier'
4 changes: 4 additions & 0 deletions packages/plugin-infra/src/web3-types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type {
BalanceNotifierState,
BlockNumberNotifierState,
NetworkDescriptor,
ProviderDescriptor,
AddressBookState,
Expand Down Expand Up @@ -37,6 +39,8 @@ export declare namespace Web3Plugin {
Web3Provider,
> {
AddressBook?: AddressBookState<ChainId>
BalanceNotifier?: BalanceNotifierState<ChainId>
BlockNumberNotifier?: BlockNumberNotifierState<ChainId>
Hub?: HubState<ChainId, SchemaType, GasOption>
IdentityService?: IdentityServiceState
NameService?: NameServiceState<ChainId>
Expand Down
18 changes: 17 additions & 1 deletion packages/plugin-infra/src/web3/useBalance.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
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<S extends 'all' | void = void, T extends NetworkPluginID = NetworkPluginID>(
pluginID?: T,
options?: Web3Helper.Web3ConnectionOptionsScope<S, T>,
) {
const account = useAccount(pluginID, options?.account)
const connection = useWeb3Connection(pluginID, options)
const { BalanceNotifier, Others } = useWeb3State(pluginID)

return useAsyncRetry(async () => {
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
}
18 changes: 17 additions & 1 deletion packages/plugin-infra/src/web3/useBlockNumber.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
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<S extends 'all' | void = void, T extends NetworkPluginID = NetworkPluginID>(
pluginID?: T,
options?: Web3Helper.Web3ConnectionOptionsScope<S, T>,
) {
const chainId = useChainId(pluginID, options?.chainId)
const connection = useWeb3Connection(pluginID, options)
const { BlockNumberNotifier } = useWeb3State(pluginID)

return useAsyncRetry(async () => {
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
}
8 changes: 8 additions & 0 deletions packages/plugins/EVM/src/state/BalanceNotifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { BalanceNotifierState } from '@masknet/plugin-infra/web3'
import type { ChainId } from '@masknet/web3-shared-evm'

export class BalanceNotifier extends BalanceNotifierState<ChainId> {
constructor() {
super()
}
}
8 changes: 8 additions & 0 deletions packages/plugins/EVM/src/state/BlockNumberNotifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { BlockNumberNotifierState } from '@masknet/plugin-infra/web3'
import type { ChainId } from '@masknet/web3-shared-evm'

export class BlockNumberNotifier extends BlockNumberNotifierState<ChainId> {
constructor() {
super()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ export class RecentTransaction implements Middleware<Context> {
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:
Expand Down
5 changes: 4 additions & 1 deletion packages/plugins/EVM/src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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,
}),
Expand Down
21 changes: 21 additions & 0 deletions packages/web3-shared/base/src/specs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,17 @@ export interface Account<ChainId> {
chainId: ChainId
}


export interface BalanceEvent<ChainId> {
/** Emit if the balance of the account updated. */
update: [Account<ChainId>]
}

export interface BlockNumberEvent<ChainId> {
/** Emit if the balance of the chain updated. */
update: [ChainId]
}

export interface ProviderEvents<ChainId, ProviderType> {
/** Emit when the chain id changed. */
chainId: [string]
Expand Down Expand Up @@ -543,6 +554,7 @@ export interface ProviderOptions<ChainId> {
export interface TransactionChecker<ChainId> {
checkStatus(chainId: ChainId, id: string): Promise<TransactionStatusType>
}

export interface ConnectionOptions<ChainId, ProviderType, Transaction> {
/** Designate the sub-network id of the transaction. */
chainId?: ChainId
Expand Down Expand Up @@ -805,6 +817,7 @@ export interface SettingsState {
/** The source type of non-fungible assets */
nonFungibleAssetSourceType?: Subscription<SourceType>
}

export interface AddressBookState<ChainId> {
/** The tracked addresses of currently chosen sub-network */
addressBook?: Subscription<string[]>
Expand Down Expand Up @@ -1011,3 +1024,11 @@ export interface OthersState<ChainId, SchemaType, ProviderType, NetworkType> {
getAverageBlockDelay(chainId?: ChainId, scale?: number): number
// #endregion
}

export interface BalanceNotifierState<ChainId> {
emitter: Emitter<BalanceEvent<ChainId>>
}

export interface BlockNumberNotifierState<ChainId> {
emitter: Emitter<BlockNumberEvent<ChainId>>
}

0 comments on commit 4d51f92

Please sign in to comment.