Skip to content

Commit 680d0da

Browse files
author
Lorenzo Sicilia
committed
Added ethMethodKey and ethContractKey util functions
1 parent ef1aaa9 commit 680d0da

File tree

4 files changed

+61
-52
lines changed

4 files changed

+61
-52
lines changed

src/components/ERC20View.tsx

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11
import React, { useEffect, useMemo } from "react"
2-
import { buildContract, IERC20, memoizedBuildContract } from "../utils"
3-
import ERC20ABI from "../abi/ERC20.abi.json"
2+
import { buildContract, ethContractKey, IERC20, memoizedBuildContract } from "../utils"
43
import useSWR, { keyInterface } from "swr"
54
import { useWeb3React } from "@web3-react/core"
65
import { Web3Provider } from "@ethersproject/providers"
76
import { formatUnits } from "@ethersproject/units"
87
import { BigNumber } from "@ethersproject/bignumber"
98
import { ABI, ABIs } from "../abi"
109
import { useWeb3Filter } from "../hooks/useWeb3Filter"
11-
import { Contract } from "@ethersproject/contracts"
1210

13-
const balanceOfKey = (address:string, account:string): keyInterface => {
14-
return [ABI.ERC20, address, "balanceOf", account]
15-
}
11+
1612
export const ERC20View = ({ name, address, decimals, symbol }: IERC20) => {
1713
const { account, library } = useWeb3React<Web3Provider>()
18-
const { data: balance, isValidating, error, mutate } = useSWR<BigNumber>(
19-
// [ABI.ERC20, address, "balanceOf", account]
20-
balanceOfKey(address, account)
21-
)
22-
console.log({balance})
23-
// useWeb3Filter(
24-
// balanceOfKey(address, account),
25-
// "Transfer",
26-
// (from, to, amount, event) => {
27-
// console.log("Transfer|sent", { from, to, amount, event })
28-
// mutate(balance.sub(amount), false)
29-
// // mutate(undefined, true)
30-
// }
31-
// )
14+
const key = ethContractKey([
15+
address,
16+
"balanceOf",
17+
account])
18+
const { data: balance, error, mutate } = useSWR<BigNumber>(key)
19+
20+
useWeb3Filter(key, [
21+
(contract) => [
22+
contract.filters.Transfer(account, null), // fromMe
23+
async () => {
24+
mutate(undefined, true)
25+
},
26+
],
27+
(contract) => [
28+
contract.filters.Transfer(null, account), //toMe
29+
async () => await mutate(undefined, true),
30+
],
31+
])
3232

3333
// TODO LS export as useFilter.e.g useFilter(contract, [contract.filters.Transfer(account, null), mutate]) The web3fetcher could return the data and the contract built
34-
useEffect(() => {
34+
/*useEffect(() => {
3535
const contract = buildContract(address, ABIs.get(ABI.ERC20), library)
3636
const fromMe = contract.filters.Transfer(account, null)
37-
console.log()
3837
contract.once(fromMe, (from, to, amount, event) => {
3938
console.log("Transfer|sent", { from, to, amount, event })
40-
mutate(balance.sub(amount), false)
41-
// mutate(undefined, true)
39+
// mutate(balance.sub(amount), false) BUG because this is a closure the balance isn't update
40+
// we could useRef https://stackoverflow.com/a/53641229 but it isn't very elegant
41+
mutate(undefined, true)
4242
})
4343
4444
const toMe = contract.filters.Transfer(null, account)
4545
contract.once(toMe, (from, to, amount, event) => {
4646
console.log("Transfer|received", { from, to, amount, event })
47-
mutate(balance.add(amount), false)
48-
// mutate(undefined, true)
47+
// mutate(balance.add(amount), false) // BUG because this is a closure the balance isn't update
48+
mutate(undefined, true)
4949
})
5050
console.log("rendering", {
5151
fromMe: contract.listenerCount(fromMe),
@@ -56,7 +56,7 @@ export const ERC20View = ({ name, address, decimals, symbol }: IERC20) => {
5656
contract.removeAllListeners(toMe)
5757
contract.removeAllListeners(fromMe)
5858
}
59-
}, [])
59+
}, [])*/
6060

6161
if (error) {
6262
return <pre>{error}</pre>

src/components/EtherView.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import { formatEther } from "@ethersproject/units"
66
import { BigNumber } from "@ethersproject/bignumber"
77

88
export const EtherView = () => {
9-
const context = useWeb3React<Web3Provider>()
10-
const { account, library } = context
9+
const { account, library } = useWeb3React<Web3Provider>()
1110

1211
const {
1312
data: ethBalance,
@@ -37,13 +36,6 @@ export const EtherView = () => {
3736
updateBalance(balance, false)
3837
})
3938

40-
console.log({
41-
isValidating,
42-
blockNumberIsValidating,
43-
ethBalance,
44-
blockNumber,
45-
})
46-
4739
/*if (!ethBalance || !blockNumber) {
4840
return <pre>...</pre>
4941
}*/

src/hooks/useWeb3Filter.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
11
import { useEffect } from "react"
2+
import { buildContract } from "../utils"
3+
import { ABI, ABIs } from "../abi"
4+
import { useWeb3React } from "@web3-react/core"
5+
import { Web3Provider } from "@ethersproject/providers"
6+
import { keyInterface } from "swr"
7+
import { Contract, EventFilter } from "@ethersproject/contracts"
28

3-
export function useWeb3Filter(contract, filter, callback) {
9+
type keyValue = (contract: Contract) => [EventFilter, () => Promise<any>]
10+
export type IFilter = keyValue[]
11+
12+
export function useWeb3Filter(key: keyInterface, filters: IFilter) {
13+
const { library } = useWeb3React<Web3Provider>()
14+
const [abi, address, method, ...params] = key
15+
const contract = buildContract(address, ABIs.get(abi), library)
416
useEffect(() => {
5-
contract.once(filter, callback)
17+
filters.forEach((filterFactory) => {
18+
const [filter, callback] = filterFactory(contract)
19+
contract.once(filter, callback)
20+
})
621
}, [])
722

823
return () => {
924
console.log("cleanup!")
10-
contract.removeAllListeners(filter)
25+
filters.forEach((factory) => {
26+
const [filter] = factory(contract)
27+
contract.removeAllListeners(filter)
28+
})
1129
}
1230
}

src/utils/index.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,37 @@ import { Contract } from "@ethersproject/contracts"
22
import { ABI } from "../abi/index"
33
import { Web3Provider } from "@ethersproject/providers"
44
import memoize from "fast-memoize"
5+
import { keyInterface } from "swr"
56

67
export function buildContract(address:string, abi:any, library:Web3Provider) {
78
return new Contract(address, abi, library.getSigner())
89
}
910

1011
export const memoizedBuildContract = memoize(buildContract)
1112

13+
export const ethMethodKey = (args): keyInterface => {
14+
return args
15+
}
16+
17+
export const ethContractKey = (args): keyInterface => {
18+
return [ABI.ERC20, ...args]
19+
}
20+
1221
export const web3Fetcher = (
1322
library: Web3Provider,
1423
ABIs: Map<ABI, any>
1524
) => async (...args) => {
1625
// debugger
17-
const [provider] = args
18-
const isContract = Object.values(ABI).includes(provider)
26+
const [abi] = args
27+
const isContract = ABIs.get(abi) !== undefined
1928
if (isContract) {
2029
const [_, address, method, ...params] = args
2130
// extract as buildContract memoized
2231
const contract = buildContract(
2332
address,
24-
ABIs.get(provider),
33+
ABIs.get(abi),
2534
library
2635
)
27-
/*const [paramWithFilter] = params.filter((p) => p.hasOwnProperty("filters"))
28-
if (paramWithFilter) {
29-
paramWithFilter.filters.forEach((filter) => {
30-
contract.once(filter, () => {
31-
console.log("mutate", { args })
32-
mutate(args)
33-
})
34-
})
35-
}*/
36-
3736
console.log({ contract: address, method, params })
3837
return contract[method](...params)
3938
}

0 commit comments

Comments
 (0)