From f50a29c773492bf2099d15a8ae86846b52734b94 Mon Sep 17 00:00:00 2001 From: lelenei Date: Mon, 28 Mar 2022 10:59:55 +0800 Subject: [PATCH 01/11] feat: check contract address --- packages/web3-shared/evm/hooks/index.ts | 2 + .../web3-shared/evm/hooks/useAddressCheck.ts | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 packages/web3-shared/evm/hooks/useAddressCheck.ts diff --git a/packages/web3-shared/evm/hooks/index.ts b/packages/web3-shared/evm/hooks/index.ts index 489ef4a6a64a..f7a728a7d678 100644 --- a/packages/web3-shared/evm/hooks/index.ts +++ b/packages/web3-shared/evm/hooks/index.ts @@ -68,3 +68,5 @@ export * from './useImageChecker' export * from './useTrustedERC20Tokens' export * from './useTrustERC20TokenCallback' export * from './useAddERC20TokenCallback' + +export * from './useAddressCheck' diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useAddressCheck.ts new file mode 100644 index 000000000000..1568f962f921 --- /dev/null +++ b/packages/web3-shared/evm/hooks/useAddressCheck.ts @@ -0,0 +1,39 @@ +import { useAsync } from 'react-use' +import { useERC721TokenContract } from '../contracts' +import { useWeb3 } from './useWeb3' + +const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63' +function useCheckContract(address: string) { + const web3 = useWeb3() + return useAsync(async () => { + const result = await web3.eth.getCode(address) + return result !== '0x' + }, [address]).value +} + +function useCheckERC721(address: string) { + const erc721TokenContract = useERC721TokenContract(address) + return useAsync(async () => { + return erc721TokenContract?.methods.supportsInterface(ERC721_ENUMERABLE_INTERFACE_ID).call() + }, [erc721TokenContract]).value +} + +function useGetSymbol(address: string) { + const erc721TokenContract = useERC721TokenContract(address) + return useAsync(async () => { + return erc721TokenContract?.methods.symbol().call() + }, [erc721TokenContract]).value +} + +export function useAddressCheck(address: string) { + const isContract = useCheckContract(address) + const isERC721 = useCheckERC721(address) + const symbol = useGetSymbol(address) + + if (isContract && isERC721 && symbol === 'ERC1155') { + return 'ERC1155' + } else if (isContract && isERC721 && symbol !== 'ERC1155') { + return 'ERC721' + } + return 'ERC20' +} From c10ddac0b8f3c2b5000b31716cdc43a66ae3c0f7 Mon Sep 17 00:00:00 2001 From: lelenei Date: Mon, 28 Mar 2022 11:42:56 +0800 Subject: [PATCH 02/11] feat: check erc1155 --- packages/web3-contracts/abis/ERC1155.json | 21 ++++++++++++++++ .../web3-shared/evm/hooks/useAddressCheck.ts | 25 +++++++++++-------- 2 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 packages/web3-contracts/abis/ERC1155.json diff --git a/packages/web3-contracts/abis/ERC1155.json b/packages/web3-contracts/abis/ERC1155.json new file mode 100644 index 000000000000..6e166b582309 --- /dev/null +++ b/packages/web3-contracts/abis/ERC1155.json @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useAddressCheck.ts index 1568f962f921..531191902a21 100644 --- a/packages/web3-shared/evm/hooks/useAddressCheck.ts +++ b/packages/web3-shared/evm/hooks/useAddressCheck.ts @@ -1,8 +1,13 @@ import { useAsync } from 'react-use' +import type { AbiItem } from 'web3-utils' import { useERC721TokenContract } from '../contracts' +import { createContract } from './useContract' import { useWeb3 } from './useWeb3' +import ERC1155 from '@masknet/web3-contracts/abis/ERC1155.json' const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63' +const ERC1155_ENUMERABLE_INTERFACE_ID = '0xd9b67a26' + ' function useCheckContract(address: string) { const web3 = useWeb3() return useAsync(async () => { @@ -18,22 +23,20 @@ function useCheckERC721(address: string) { }, [erc721TokenContract]).value } -function useGetSymbol(address: string) { - const erc721TokenContract = useERC721TokenContract(address) - return useAsync(async () => { - return erc721TokenContract?.methods.symbol().call() - }, [erc721TokenContract]).value +function useCheckERC1155(address: string) { + const web3 = useWeb3() + const erc1155Contract = createContract(web3, address, ERC1155 as AbiItem[]) + return useAsync(async() => { + return erc1155Contract?.methods.supportsInterface(ERC1155_ENUMERABLE_INTERFACE_ID).call() + }, [erc1155Contract]) } export function useAddressCheck(address: string) { const isContract = useCheckContract(address) const isERC721 = useCheckERC721(address) - const symbol = useGetSymbol(address) + const isERC1155 = useCheckERC1155(address) - if (isContract && isERC721 && symbol === 'ERC1155') { - return 'ERC1155' - } else if (isContract && isERC721 && symbol !== 'ERC1155') { - return 'ERC721' - } + if (isContract && isERC1155) return 'ERC1155' + if (isContract && isERC721) return 'ERC721' return 'ERC20' } From 63e40fb0255426d0d46e2c28eaae7ac17b0d9f7e Mon Sep 17 00:00:00 2001 From: lelenei Date: Mon, 28 Mar 2022 11:44:26 +0800 Subject: [PATCH 03/11] fix: typo --- packages/web3-shared/evm/hooks/useAddressCheck.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useAddressCheck.ts index 531191902a21..a066e570faa4 100644 --- a/packages/web3-shared/evm/hooks/useAddressCheck.ts +++ b/packages/web3-shared/evm/hooks/useAddressCheck.ts @@ -7,7 +7,7 @@ import ERC1155 from '@masknet/web3-contracts/abis/ERC1155.json' const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63' const ERC1155_ENUMERABLE_INTERFACE_ID = '0xd9b67a26' - ' + function useCheckContract(address: string) { const web3 = useWeb3() return useAsync(async () => { @@ -26,7 +26,7 @@ function useCheckERC721(address: string) { function useCheckERC1155(address: string) { const web3 = useWeb3() const erc1155Contract = createContract(web3, address, ERC1155 as AbiItem[]) - return useAsync(async() => { + return useAsync(async () => { return erc1155Contract?.methods.supportsInterface(ERC1155_ENUMERABLE_INTERFACE_ID).call() }, [erc1155Contract]) } From e285fc544201ac4e78046b8793d7c6ce54e39a54 Mon Sep 17 00:00:00 2001 From: lelenei Date: Mon, 28 Mar 2022 11:47:33 +0800 Subject: [PATCH 04/11] fix: reply review --- packages/web3-shared/evm/hooks/useAddressCheck.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useAddressCheck.ts index a066e570faa4..297a14f1b693 100644 --- a/packages/web3-shared/evm/hooks/useAddressCheck.ts +++ b/packages/web3-shared/evm/hooks/useAddressCheck.ts @@ -36,7 +36,5 @@ export function useAddressCheck(address: string) { const isERC721 = useCheckERC721(address) const isERC1155 = useCheckERC1155(address) - if (isContract && isERC1155) return 'ERC1155' - if (isContract && isERC721) return 'ERC721' - return 'ERC20' + return isERC1155 ? 'ERC1155' : isERC721 ? 'ERC721' : isContract ? 'ERC20' : '' } From 5459e7a54ba59219688e2fa792f3d319a6813b11 Mon Sep 17 00:00:00 2001 From: lelenei Date: Mon, 28 Mar 2022 13:39:17 +0800 Subject: [PATCH 05/11] fix: check erc165 --- .../web3-shared/evm/hooks/useAddressCheck.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useAddressCheck.ts index 297a14f1b693..9cf750446fa5 100644 --- a/packages/web3-shared/evm/hooks/useAddressCheck.ts +++ b/packages/web3-shared/evm/hooks/useAddressCheck.ts @@ -4,6 +4,7 @@ import { useERC721TokenContract } from '../contracts' import { createContract } from './useContract' import { useWeb3 } from './useWeb3' import ERC1155 from '@masknet/web3-contracts/abis/ERC1155.json' +import { useERC165 } from '.' const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63' const ERC1155_ENUMERABLE_INTERFACE_ID = '0xd9b67a26' @@ -17,24 +18,21 @@ function useCheckContract(address: string) { } function useCheckERC721(address: string) { - const erc721TokenContract = useERC721TokenContract(address) - return useAsync(async () => { - return erc721TokenContract?.methods.supportsInterface(ERC721_ENUMERABLE_INTERFACE_ID).call() - }, [erc721TokenContract]).value + const erc721Contract = useERC721TokenContract(address) + return useERC165(erc721Contract, address, ERC721_ENUMERABLE_INTERFACE_ID) } function useCheckERC1155(address: string) { const web3 = useWeb3() const erc1155Contract = createContract(web3, address, ERC1155 as AbiItem[]) - return useAsync(async () => { - return erc1155Contract?.methods.supportsInterface(ERC1155_ENUMERABLE_INTERFACE_ID).call() - }, [erc1155Contract]) + return useERC165(erc1155Contract, address, ERC1155_ENUMERABLE_INTERFACE_ID) } export function useAddressCheck(address: string) { const isContract = useCheckContract(address) - const isERC721 = useCheckERC721(address) - const isERC1155 = useCheckERC1155(address) + const { value: isERC721, loading: loadingERC721 } = useCheckERC721(address) + const { value: isERC1155, loading: loadingERC1155 } = useCheckERC1155(address) + if (loadingERC1155 || loadingERC721) return return isERC1155 ? 'ERC1155' : isERC721 ? 'ERC721' : isContract ? 'ERC20' : '' } From 42c3941995f6a038059c970a0643c743553ba8fc Mon Sep 17 00:00:00 2001 From: lelenei Date: Mon, 28 Mar 2022 18:29:22 +0800 Subject: [PATCH 06/11] refactor: reply review --- .../web3-shared/evm/hooks/useAddressCheck.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useAddressCheck.ts index 9cf750446fa5..70ad541b7dcf 100644 --- a/packages/web3-shared/evm/hooks/useAddressCheck.ts +++ b/packages/web3-shared/evm/hooks/useAddressCheck.ts @@ -1,4 +1,4 @@ -import { useAsync } from 'react-use' +import { useAsyncRetry } from 'react-use' import type { AbiItem } from 'web3-utils' import { useERC721TokenContract } from '../contracts' import { createContract } from './useContract' @@ -11,10 +11,10 @@ const ERC1155_ENUMERABLE_INTERFACE_ID = '0xd9b67a26' function useCheckContract(address: string) { const web3 = useWeb3() - return useAsync(async () => { + return useAsyncRetry(async () => { const result = await web3.eth.getCode(address) return result !== '0x' - }, [address]).value + }, [address]) } function useCheckERC721(address: string) { @@ -22,17 +22,22 @@ function useCheckERC721(address: string) { return useERC165(erc721Contract, address, ERC721_ENUMERABLE_INTERFACE_ID) } -function useCheckERC1155(address: string) { +function useCreateERC1155TokenContract(address: string) { const web3 = useWeb3() const erc1155Contract = createContract(web3, address, ERC1155 as AbiItem[]) + return erc1155Contract +} + +function useCheckERC1155(address: string) { + const erc1155Contract = useCreateERC1155TokenContract(address) return useERC165(erc1155Contract, address, ERC1155_ENUMERABLE_INTERFACE_ID) } export function useAddressCheck(address: string) { - const isContract = useCheckContract(address) + const { value: isContract, loading: loadingContract } = useCheckContract(address) const { value: isERC721, loading: loadingERC721 } = useCheckERC721(address) const { value: isERC1155, loading: loadingERC1155 } = useCheckERC1155(address) - if (loadingERC1155 || loadingERC721) return + if (loadingERC1155 || loadingERC721 || loadingContract) return return isERC1155 ? 'ERC1155' : isERC721 ? 'ERC721' : isContract ? 'ERC20' : '' } From fbf09ff6f27342f05cf590d130e3b39cd212ede2 Mon Sep 17 00:00:00 2001 From: lelenei Date: Wed, 6 Apr 2022 11:37:49 +0800 Subject: [PATCH 07/11] fix: reply review --- .../web3-shared/evm/hooks/useAddressCheck.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useAddressCheck.ts index 70ad541b7dcf..15273e9ecba9 100644 --- a/packages/web3-shared/evm/hooks/useAddressCheck.ts +++ b/packages/web3-shared/evm/hooks/useAddressCheck.ts @@ -5,6 +5,7 @@ import { createContract } from './useContract' import { useWeb3 } from './useWeb3' import ERC1155 from '@masknet/web3-contracts/abis/ERC1155.json' import { useERC165 } from '.' +import { EthereumTokenType } from '../types' const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63' const ERC1155_ENUMERABLE_INTERFACE_ID = '0xd9b67a26' @@ -22,22 +23,27 @@ function useCheckERC721(address: string) { return useERC165(erc721Contract, address, ERC721_ENUMERABLE_INTERFACE_ID) } -function useCreateERC1155TokenContract(address: string) { +function useERC1155TokenContract(address: string) { const web3 = useWeb3() - const erc1155Contract = createContract(web3, address, ERC1155 as AbiItem[]) - return erc1155Contract + return createContract(web3, address, ERC1155 as AbiItem[]) } function useCheckERC1155(address: string) { - const erc1155Contract = useCreateERC1155TokenContract(address) + const erc1155Contract = useERC1155TokenContract(address) return useERC165(erc1155Contract, address, ERC1155_ENUMERABLE_INTERFACE_ID) } -export function useAddressCheck(address: string) { +export function useAddressCheck(address: string): EthereumTokenType { const { value: isContract, loading: loadingContract } = useCheckContract(address) const { value: isERC721, loading: loadingERC721 } = useCheckERC721(address) const { value: isERC1155, loading: loadingERC1155 } = useCheckERC1155(address) if (loadingERC1155 || loadingERC721 || loadingContract) return - return isERC1155 ? 'ERC1155' : isERC721 ? 'ERC721' : isContract ? 'ERC20' : '' + return isERC1155 + ? EthereumTokenType.ERC1155 + : isERC721 + ? EthereumTokenType.ERC721 + : isContract + ? EthereumTokenType.ERC20 + : EthereumTokenType.Native } From 7d8f683a93be08f942b461fa0e90f82965a9e166 Mon Sep 17 00:00:00 2001 From: lelenei Date: Wed, 6 Apr 2022 11:43:04 +0800 Subject: [PATCH 08/11] fix: return error --- packages/web3-shared/evm/hooks/useAddressCheck.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useAddressCheck.ts index 15273e9ecba9..7e43a3545a02 100644 --- a/packages/web3-shared/evm/hooks/useAddressCheck.ts +++ b/packages/web3-shared/evm/hooks/useAddressCheck.ts @@ -33,7 +33,7 @@ function useCheckERC1155(address: string) { return useERC165(erc1155Contract, address, ERC1155_ENUMERABLE_INTERFACE_ID) } -export function useAddressCheck(address: string): EthereumTokenType { +export function useAddressCheck(address: string): EthereumTokenType | undefined { const { value: isContract, loading: loadingContract } = useCheckContract(address) const { value: isERC721, loading: loadingERC721 } = useCheckERC721(address) const { value: isERC1155, loading: loadingERC1155 } = useCheckERC1155(address) @@ -45,5 +45,5 @@ export function useAddressCheck(address: string): EthereumTokenType { ? EthereumTokenType.ERC721 : isContract ? EthereumTokenType.ERC20 - : EthereumTokenType.Native + : undefined } From 6e8e7b1dd111c21b901f31f2ce5aff95b740cb49 Mon Sep 17 00:00:00 2001 From: lelenei Date: Wed, 6 Apr 2022 12:17:34 +0800 Subject: [PATCH 09/11] fix: reply review --- packages/web3-shared/evm/contracts/index.ts | 1 + .../evm/contracts/useERC1155TokenContract.ts | 8 ++++++++ .../{useAddressCheck.ts => useEthereumTokenType.ts} | 13 +++---------- 3 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 packages/web3-shared/evm/contracts/useERC1155TokenContract.ts rename packages/web3-shared/evm/hooks/{useAddressCheck.ts => useEthereumTokenType.ts} (75%) diff --git a/packages/web3-shared/evm/contracts/index.ts b/packages/web3-shared/evm/contracts/index.ts index b2d0c88afead..d4c4b3335ed6 100644 --- a/packages/web3-shared/evm/contracts/index.ts +++ b/packages/web3-shared/evm/contracts/index.ts @@ -1,3 +1,4 @@ export * from './useERC20TokenContract' export * from './useERC721TokenContract' export * from './useERC721TokenContracts' +export * from './useERC1155TokenContract' diff --git a/packages/web3-shared/evm/contracts/useERC1155TokenContract.ts b/packages/web3-shared/evm/contracts/useERC1155TokenContract.ts new file mode 100644 index 000000000000..17c58d3e4cca --- /dev/null +++ b/packages/web3-shared/evm/contracts/useERC1155TokenContract.ts @@ -0,0 +1,8 @@ +import { createContract, useWeb3 } from '../hooks' +import ERC1155 from '@masknet/web3-contracts/abis/ERC1155.json' +import type { AbiItem } from 'web3-utils' + +export function useERC1155TokenContract(address: string) { + const web3 = useWeb3() + return createContract(web3, address, ERC1155 as AbiItem[]) +} diff --git a/packages/web3-shared/evm/hooks/useAddressCheck.ts b/packages/web3-shared/evm/hooks/useEthereumTokenType.ts similarity index 75% rename from packages/web3-shared/evm/hooks/useAddressCheck.ts rename to packages/web3-shared/evm/hooks/useEthereumTokenType.ts index 7e43a3545a02..19eaaa15b3ac 100644 --- a/packages/web3-shared/evm/hooks/useAddressCheck.ts +++ b/packages/web3-shared/evm/hooks/useEthereumTokenType.ts @@ -1,9 +1,7 @@ import { useAsyncRetry } from 'react-use' -import type { AbiItem } from 'web3-utils' -import { useERC721TokenContract } from '../contracts' -import { createContract } from './useContract' +import { useERC1155TokenContract, useERC721TokenContract } from '../contracts' import { useWeb3 } from './useWeb3' -import ERC1155 from '@masknet/web3-contracts/abis/ERC1155.json' + import { useERC165 } from '.' import { EthereumTokenType } from '../types' @@ -23,17 +21,12 @@ function useCheckERC721(address: string) { return useERC165(erc721Contract, address, ERC721_ENUMERABLE_INTERFACE_ID) } -function useERC1155TokenContract(address: string) { - const web3 = useWeb3() - return createContract(web3, address, ERC1155 as AbiItem[]) -} - function useCheckERC1155(address: string) { const erc1155Contract = useERC1155TokenContract(address) return useERC165(erc1155Contract, address, ERC1155_ENUMERABLE_INTERFACE_ID) } -export function useAddressCheck(address: string): EthereumTokenType | undefined { +export function useEthereumTokenType(address: string): EthereumTokenType | undefined { const { value: isContract, loading: loadingContract } = useCheckContract(address) const { value: isERC721, loading: loadingERC721 } = useCheckERC721(address) const { value: isERC1155, loading: loadingERC1155 } = useCheckERC1155(address) From d8db366f18645d7e967a85f55831feadb35ae671 Mon Sep 17 00:00:00 2001 From: lelenei Date: Wed, 6 Apr 2022 13:23:57 +0800 Subject: [PATCH 10/11] fix: typo --- packages/web3-shared/evm/hooks/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-shared/evm/hooks/index.ts b/packages/web3-shared/evm/hooks/index.ts index f7a728a7d678..7761258ba2ce 100644 --- a/packages/web3-shared/evm/hooks/index.ts +++ b/packages/web3-shared/evm/hooks/index.ts @@ -69,4 +69,4 @@ export * from './useTrustedERC20Tokens' export * from './useTrustERC20TokenCallback' export * from './useAddERC20TokenCallback' -export * from './useAddressCheck' +export * from './useEthereumTokenType' From c9a9cb8da7f3ac92cbaaff8839aa6df2c7c5d0a0 Mon Sep 17 00:00:00 2001 From: lelenei Date: Wed, 6 Apr 2022 14:32:18 +0800 Subject: [PATCH 11/11] fix: reply review --- .../web3-shared/evm/contracts/useERC1155TokenContract.ts | 5 ++--- packages/web3-shared/evm/hooks/useEthereumTokenType.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/web3-shared/evm/contracts/useERC1155TokenContract.ts b/packages/web3-shared/evm/contracts/useERC1155TokenContract.ts index 17c58d3e4cca..a4b9512b8507 100644 --- a/packages/web3-shared/evm/contracts/useERC1155TokenContract.ts +++ b/packages/web3-shared/evm/contracts/useERC1155TokenContract.ts @@ -1,8 +1,7 @@ -import { createContract, useWeb3 } from '../hooks' import ERC1155 from '@masknet/web3-contracts/abis/ERC1155.json' import type { AbiItem } from 'web3-utils' +import { useContract } from '../hooks' export function useERC1155TokenContract(address: string) { - const web3 = useWeb3() - return createContract(web3, address, ERC1155 as AbiItem[]) + return useContract(address, ERC1155 as AbiItem[]) } diff --git a/packages/web3-shared/evm/hooks/useEthereumTokenType.ts b/packages/web3-shared/evm/hooks/useEthereumTokenType.ts index 19eaaa15b3ac..c5615bcab09b 100644 --- a/packages/web3-shared/evm/hooks/useEthereumTokenType.ts +++ b/packages/web3-shared/evm/hooks/useEthereumTokenType.ts @@ -13,7 +13,7 @@ function useCheckContract(address: string) { return useAsyncRetry(async () => { const result = await web3.eth.getCode(address) return result !== '0x' - }, [address]) + }, [address, web3]) } function useCheckERC721(address: string) {