Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
{
...config,
displayName: 'core',
setupFilesAfterEnv: ['<rootDir>/packages/core/test/setup.ts'],
testEnvironment: 'node',
testRegex: 'packages/core/.*\\.test\\.ts$',
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"devDependencies": {
"@walletconnect/ethereum-provider": "1.7.1",
"ethers": "^5.5.1",
"wagmi-testing": "0.1.11",
"walletlink": "^2.2.8"
}
}
62 changes: 62 additions & 0 deletions packages/core/src/actions/accounts/balance.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { contracts, wallets } from 'wagmi-testing'

import { getProvider } from '../../../test'
import { balanceAction } from './balance'

const provider = getProvider()

describe('balanceAction', () => {
it('fetches eth balance', async () => {
const balance = await balanceAction({
config: {
addressOrName: wallets.ethers1.address,
},
provider,
})
expect(balance).toMatchInlineSnapshot(`
{
"decimals": 18,
"formatted": "0.193861344139087225",
"symbol": "ETH",
"unit": "ether",
"value": {
"hex": "0x02b0bbdd89170d79",
"type": "BigNumber",
},
}
`)
})

it.skip('fetches token balance', async () => {
const balance = await balanceAction({
config: {
addressOrName: wallets.ethers3.address,
token: contracts.uniToken,
},
provider,
})
expect(balance).toMatchInlineSnapshot()
})

it('formats balance', async () => {
const balance = await balanceAction({
config: {
addressOrName: wallets.ethers1.address,
formatUnits: 'gwei',
},
provider,
})
expect(balance).toMatchInlineSnapshot(`
{
"decimals": 18,
"formatted": "193861344.139087225",
"symbol": "ETH",
"unit": "gwei",
"value": {
"hex": "0x02b0bbdd89170d79",
"type": "BigNumber",
},
}
`)
})
})
54 changes: 54 additions & 0 deletions packages/core/src/actions/accounts/balance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { ethers, utils } from 'ethers'

import { defaultChains, defaultL2Chains, erc20ABI } from '../../constants'
import { Balance, Chain, Unit, WithProvider } from '../../types'

export type BalanceActionArgs = WithProvider<{
/** Chains to use for looking up native currency */
chains?: Chain[]
/** Configuration to use for balance */
config: {
/** Address or ENS name */
addressOrName: string
/** Units for formatting output */
formatUnits?: Unit | number
/** ERC-20 address */
token?: string
}
}>

export type BalanceActionResult = Balance

export const balanceAction = async ({
chains = [...defaultChains, ...defaultL2Chains],
config,
provider,
}: BalanceActionArgs): Promise<BalanceActionResult> => {
const unit = config.formatUnits ?? 'ether'

if (config.token) {
const contract = new ethers.Contract(config.token, erc20ABI, provider)
const [value, decimals, symbol] = await Promise.all([
contract.balanceOf(config.addressOrName),
contract.decimals(),
contract.symbol(),
])
return {
decimals,
formatted: utils.formatUnits(value, unit),
symbol,
unit,
value,
}
}

const value = await provider.getBalance(config.addressOrName)
const chain = chains.find((x) => x.id === provider.network.chainId)
return {
decimals: chain?.nativeCurrency?.decimals ?? 18,
formatted: utils.formatUnits(value, unit),
symbol: chain?.nativeCurrency?.symbol ?? 'ETH',
unit,
value,
}
}
2 changes: 2 additions & 0 deletions packages/core/src/actions/accounts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export type { BalanceActionArgs, BalanceActionResult } from './balance'
export { balanceAction } from './balance'
2 changes: 2 additions & 0 deletions packages/core/src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export type { BalanceActionArgs, BalanceActionResult } from './accounts'
export { balanceAction } from './accounts'
10 changes: 9 additions & 1 deletion packages/core/src/constants/units.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
// https://github.com/ethers-io/ethers.js/blob/master/packages/units/src.ts/index.ts#L10-L18
export const units = ['wei', 'kwei', 'mwei', 'gwei', 'szabo', 'finney', 'ether']
export const units = [
'wei',
'kwei',
'mwei',
'gwei',
'szabo',
'finney',
'ether',
] as const
1 change: 1 addition & 0 deletions packages/core/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ it('should expose correct exports', () => {
[
"Connector",
"InjectedConnector",
"balanceAction",
"erc1155ABI",
"erc20ABI",
"erc721ABI",
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
export { Connector, InjectedConnector } from './connectors'
export type { ConnectorData, ConnectorEvents } from './connectors'

export type { BalanceActionArgs, BalanceActionResult } from './actions'
export { balanceAction } from './actions'

export {
erc1155ABI,
erc20ABI,
Expand All @@ -22,6 +25,6 @@ export {
UserRejectedRequestError,
} from './errors'

export type { Chain, Unit } from './types'
export type { Balance, Chain, Unit } from './types'

export { normalizeChainId } from './utils'
6 changes: 6 additions & 0 deletions packages/core/src/types/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { BaseProvider } from '@ethersproject/providers'

export type WithProvider<T> = T & {
/** Interface for connecting to network */
provider: BaseProvider
}
12 changes: 12 additions & 0 deletions packages/core/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { BigNumber } from 'ethers'

import { units } from '../constants'
import './declarations'

export type { WithProvider } from './actions'

export type Balance = {
decimals: number
formatted: string
symbol: string
unit: Unit | number
value: BigNumber
}

export type Chain = {
id: number
name: AddEthereumChainParameter['chainName']
Expand Down
5 changes: 5 additions & 0 deletions packages/core/test/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { providers } from 'ethers'
import { infuraApiKey } from 'wagmi-testing'

export const getProvider = ({ chainId }: { chainId?: number } = {}) =>
new providers.InfuraProvider(chainId ?? 1, infuraApiKey)
11 changes: 11 additions & 0 deletions packages/core/test/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '@testing-library/jest-dom'

import { server } from 'wagmi-testing'

// Establish API mocking before all tests.
beforeAll(() => server.listen())
// Reset any request handlers that we may add during the tests,
// so they don't affect other tests.
afterEach(() => server.resetHandlers())
// Clean up after the tests are finished.
afterAll(() => server.close())
2 changes: 2 additions & 0 deletions packages/react/src/hooks/accounts/useBalance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ describe('useBalance', () => {
"decimals": 18,
"formatted": "0.193861344139087225",
"symbol": "ETH",
"unit": "ether",
"value": {
"hex": "0x02b0bbdd89170d79",
"type": "BigNumber",
Expand Down Expand Up @@ -104,6 +105,7 @@ describe('useBalance', () => {
"decimals": 18,
"formatted": "0.193861344139087225",
"symbol": "ETH",
"unit": "ether",
"value": {
"hex": "0x02b0bbdd89170d79",
"type": "BigNumber",
Expand Down
63 changes: 16 additions & 47 deletions packages/react/src/hooks/accounts/useBalance.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import * as React from 'react'
import { BigNumber, ethers, utils } from 'ethers'
import { Unit, defaultChains, defaultL2Chains, erc20ABI } from 'wagmi-core'
import { BigNumber } from 'ethers'
import {
BalanceActionArgs,
balanceAction,
defaultChains,
defaultL2Chains,
} from 'wagmi-core'

import { useContext } from '../../context'
import { useProvider } from '../providers'
import { useBlockNumber } from '../network-status'
import { useCacheBuster, useCancel } from '../utils'

export type Config = {
/** Address or ENS name */
addressOrName?: string
/** Units for formatting output */
formatUnits?: Unit | number
/** Disables fetching */
skip?: boolean
/** ERC-20 address */
token?: string
/** Subscribe to changes */
watch?: boolean
}
} & Partial<BalanceActionArgs['config']>

type State = {
balance?: {
Expand Down Expand Up @@ -70,52 +69,22 @@ export const useBalance = ({
}
if (!config_.addressOrName) throw new Error('address is required')

const formatUnits_ = config_.formatUnits ?? 'ether'

setState((x) => ({ ...x, error: undefined, loading: true }))
let balance: State['balance']
if (config_.token) {
const contract = new ethers.Contract(
config_.token,
erc20ABI,
provider,
)
const [value, decimals, symbol] = await Promise.all([
contract.balanceOf(config_.addressOrName),
contract.decimals(),
contract.symbol(),
])
balance = {
decimals,
formatted: utils.formatUnits(value, formatUnits_),
symbol,
value,
}
} else {
const value = await provider.getBalance(config_.addressOrName)
const chain = [
const balance = await balanceAction({
chains: [
...(connector?.chains ?? []),
...defaultChains,
...defaultL2Chains,
].find((x) => x.id === provider.network.chainId)
balance = {
decimals: chain?.nativeCurrency?.decimals ?? 18,
formatted: utils.formatUnits(value, formatUnits_),
symbol: chain?.nativeCurrency?.symbol ?? 'ETH',
value,
}
}

if (!didCancel) {
setState((x) => ({ ...x, balance, loading: false }))
}
],
config: <BalanceActionArgs['config']>config_,
provider,
})
if (!didCancel) setState((x) => ({ ...x, balance, loading: false }))

return { data: balance, error: undefined }
} catch (error_) {
const error = <Error>error_
if (!didCancel) {
setState((x) => ({ ...x, error, loading: false }))
}
if (!didCancel) setState((x) => ({ ...x, error, loading: false }))
return { data: undefined, error }
}
},
Expand Down
3 changes: 2 additions & 1 deletion packages/react/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
infuraApiKey,
wallets,
} from 'wagmi-testing'
import { chain } from 'wagmi-core'

import { Provider, ProviderProps } from '../src'

Expand All @@ -23,7 +24,7 @@ type Props = ProviderProps & {
| React.ReactNode
}
export const wrapper = (props: Props) => {
const network = props.chainId ?? 1
const network = props.chainId ?? chain.mainnet.id
return (
<Provider
connectors={[
Expand Down
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.