Last active
December 18, 2022 10:43
-
-
Save leonidkuznetsov18/47c993348e3baee855075a8a909b8fc3 to your computer and use it in GitHub Desktop.
Detect ETH token standard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function detectStandard() { | |
// Check if the contract implements the ERC-20 interface | |
if (implementsERC20(abiERC20)) { | |
return 'ERC-20'; | |
} | |
// Check if the contract implements the ERC-721 interface | |
if (implementsERC721(abiERC721)) { | |
return 'ERC-721'; | |
} | |
// Check if the contract implements the ERC-1155 interface | |
if (implementsERC1155(abiERC1155)) { | |
return 'ERC-1155'; | |
} | |
return 'unknown'; | |
} | |
function implementsERC20(abi) { | |
// Check if the ABI includes the required functions for the ERC-20 interface | |
return ( | |
abi.filter( | |
(item) => item.name === 'transfer' && item.inputs.length === 2 && item.inputs[0].type === 'address' && item.inputs[1].type === 'uint256', | |
).length > 0 | |
&& abi.filter( | |
(item) => item.name === 'transferFrom' && item.inputs.length === 3 && item.inputs[0].type === 'address' && item.inputs[1].type === 'address' && item.inputs[2].type === 'uint256', | |
).length > 0 | |
&& abi.filter( | |
(item) => item.name === 'balanceOf' && item.inputs.length === 1 && item.inputs[0].type === 'address', | |
).length > 0 | |
); | |
} | |
function implementsERC721(abi) { | |
// Check if the ABI includes the required functions for the ERC-721 interface | |
return ( | |
abi.filter( | |
(item) => item.name === 'transferFrom' && item.inputs.length === 3 && item.inputs[0].type === 'address' && item.inputs[1].type === 'address' && item.inputs[2].type === 'uint256', | |
).length > 0 | |
&& abi.filter( | |
(item) => item.name === 'balanceOf' && item.inputs.length === 1 && item.inputs[0].type === 'address', | |
).length > 0 | |
&& abi.filter( | |
(item) => item.name === 'ownerOf' && item.inputs.length === 1 && item.inputs[0].type === 'uint256', | |
).length > 0 | |
); | |
} | |
function implementsERC1155(abi) { | |
// Check if the ABI includes the required functions for the ERC-1155 interface | |
return ( | |
abi.filter( | |
(item) => item.name === 'safeBatchTransferFrom' && item.inputs.length === 4 && item.inputs[0].type === 'address' && item.inputs[1].type === 'address' && item.inputs[2].type === 'uint256[]' && item.inputs[3].type === 'uint256[]', | |
).length > 0 | |
&& abi.filter( | |
(item) => item.name === 'balanceOf' && item.inputs.length === 2 && item.inputs[0].type === 'address' && item.inputs[1].type === 'uint256', | |
).length > 0 | |
); | |
} | |
export const abiERC1155 = [ | |
{ | |
inputs: [ | |
{ | |
internalType: 'string', | |
name: 'uri_', | |
type: 'string', | |
}, | |
], | |
stateMutability: 'nonpayable', | |
type: 'constructor', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: true, | |
internalType: 'address', | |
name: 'account', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
internalType: 'address', | |
name: 'operator', | |
type: 'address', | |
}, | |
{ | |
indexed: false, | |
internalType: 'bool', | |
name: 'approved', | |
type: 'bool', | |
}, | |
], | |
name: 'ApprovalForAll', | |
type: 'event', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: true, | |
internalType: 'address', | |
name: 'operator', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
internalType: 'address', | |
name: 'from', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
internalType: 'address', | |
name: 'to', | |
type: 'address', | |
}, | |
{ | |
indexed: false, | |
internalType: 'uint256[]', | |
name: 'ids', | |
type: 'uint256[]', | |
}, | |
{ | |
indexed: false, | |
internalType: 'uint256[]', | |
name: 'values', | |
type: 'uint256[]', | |
}, | |
], | |
name: 'TransferBatch', | |
type: 'event', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: true, | |
internalType: 'address', | |
name: 'operator', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
internalType: 'address', | |
name: 'from', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
internalType: 'address', | |
name: 'to', | |
type: 'address', | |
}, | |
{ | |
indexed: false, | |
internalType: 'uint256', | |
name: 'id', | |
type: 'uint256', | |
}, | |
{ | |
indexed: false, | |
internalType: 'uint256', | |
name: 'value', | |
type: 'uint256', | |
}, | |
], | |
name: 'TransferSingle', | |
type: 'event', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: false, | |
internalType: 'string', | |
name: 'value', | |
type: 'string', | |
}, | |
{ | |
indexed: true, | |
internalType: 'uint256', | |
name: 'id', | |
type: 'uint256', | |
}, | |
], | |
name: 'URI', | |
type: 'event', | |
}, | |
{ | |
inputs: [ | |
{ | |
internalType: 'address', | |
name: 'account', | |
type: 'address', | |
}, | |
{ | |
internalType: 'uint256', | |
name: 'id', | |
type: 'uint256', | |
}, | |
], | |
name: 'balanceOf', | |
outputs: [ | |
{ | |
internalType: 'uint256', | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
inputs: [ | |
{ | |
internalType: 'address[]', | |
name: 'accounts', | |
type: 'address[]', | |
}, | |
{ | |
internalType: 'uint256[]', | |
name: 'ids', | |
type: 'uint256[]', | |
}, | |
], | |
name: 'balanceOfBatch', | |
outputs: [ | |
{ | |
internalType: 'uint256[]', | |
name: '', | |
type: 'uint256[]', | |
}, | |
], | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
inputs: [ | |
{ | |
internalType: 'address', | |
name: 'account', | |
type: 'address', | |
}, | |
{ | |
internalType: 'address', | |
name: 'operator', | |
type: 'address', | |
}, | |
], | |
name: 'isApprovedForAll', | |
outputs: [ | |
{ | |
internalType: 'bool', | |
name: '', | |
type: 'bool', | |
}, | |
], | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
inputs: [ | |
{ | |
internalType: 'address', | |
name: 'from', | |
type: 'address', | |
}, | |
{ | |
internalType: 'address', | |
name: 'to', | |
type: 'address', | |
}, | |
{ | |
internalType: 'uint256[]', | |
name: 'ids', | |
type: 'uint256[]', | |
}, | |
{ | |
internalType: 'uint256[]', | |
name: 'amounts', | |
type: 'uint256[]', | |
}, | |
{ | |
internalType: 'bytes', | |
name: 'data', | |
type: 'bytes', | |
}, | |
], | |
name: 'safeBatchTransferFrom', | |
outputs: [], | |
stateMutability: 'nonpayable', | |
type: 'function', | |
}, | |
{ | |
inputs: [ | |
{ | |
internalType: 'address', | |
name: 'from', | |
type: 'address', | |
}, | |
{ | |
internalType: 'address', | |
name: 'to', | |
type: 'address', | |
}, | |
{ | |
internalType: 'uint256', | |
name: 'id', | |
type: 'uint256', | |
}, | |
{ | |
internalType: 'uint256', | |
name: 'amount', | |
type: 'uint256', | |
}, | |
{ | |
internalType: 'bytes', | |
name: 'data', | |
type: 'bytes', | |
}, | |
], | |
name: 'safeTransferFrom', | |
outputs: [], | |
stateMutability: 'nonpayable', | |
type: 'function', | |
}, | |
{ | |
inputs: [ | |
{ | |
internalType: 'address', | |
name: 'operator', | |
type: 'address', | |
}, | |
{ | |
internalType: 'bool', | |
name: 'approved', | |
type: 'bool', | |
}, | |
], | |
name: 'setApprovalForAll', | |
outputs: [], | |
stateMutability: 'nonpayable', | |
type: 'function', | |
}, | |
{ | |
inputs: [ | |
{ | |
internalType: 'bytes4', | |
name: 'interfaceId', | |
type: 'bytes4', | |
}, | |
], | |
name: 'supportsInterface', | |
outputs: [ | |
{ | |
internalType: 'bool', | |
name: '', | |
type: 'bool', | |
}, | |
], | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
inputs: [ | |
{ | |
internalType: 'uint256', | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
name: 'uri', | |
outputs: [ | |
{ | |
internalType: 'string', | |
name: '', | |
type: 'string', | |
}, | |
], | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
] as const; | |
export const abiERC20 = [ | |
{ | |
constant: true, | |
inputs: [], | |
name: 'name', | |
outputs: [ | |
{ | |
name: '', | |
type: 'string', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_spender', | |
type: 'address', | |
}, | |
{ | |
name: '_value', | |
type: 'uint256', | |
}, | |
], | |
name: 'approve', | |
outputs: [ | |
{ | |
name: 'success', | |
type: 'bool', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [], | |
name: 'totalSupply', | |
outputs: [ | |
{ | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_from', | |
type: 'address', | |
}, | |
{ | |
name: '_to', | |
type: 'address', | |
}, | |
{ | |
name: '_value', | |
type: 'uint256', | |
}, | |
], | |
name: 'transferFrom', | |
outputs: [ | |
{ | |
name: 'success', | |
type: 'bool', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [], | |
name: 'decimals', | |
outputs: [ | |
{ | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [], | |
name: 'version', | |
outputs: [ | |
{ | |
name: '', | |
type: 'string', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_owner', | |
type: 'address', | |
}, | |
], | |
name: 'balanceOf', | |
outputs: [ | |
{ | |
name: 'balance', | |
type: 'uint256', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [], | |
name: 'symbol', | |
outputs: [ | |
{ | |
name: '', | |
type: 'string', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_to', | |
type: 'address', | |
}, | |
{ | |
name: '_value', | |
type: 'uint256', | |
}, | |
], | |
name: 'transfer', | |
outputs: [ | |
{ | |
name: 'success', | |
type: 'bool', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_spender', | |
type: 'address', | |
}, | |
{ | |
name: '_value', | |
type: 'uint256', | |
}, | |
{ | |
name: '_extraData', | |
type: 'bytes', | |
}, | |
], | |
name: 'approveAndCall', | |
outputs: [ | |
{ | |
name: 'success', | |
type: 'bool', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_owner', | |
type: 'address', | |
}, | |
{ | |
name: '_spender', | |
type: 'address', | |
}, | |
], | |
name: 'allowance', | |
outputs: [ | |
{ | |
name: 'remaining', | |
type: 'uint256', | |
}, | |
], | |
payable: false, | |
type: 'function', | |
}, | |
{ | |
inputs: [ | |
{ | |
name: '_initialAmount', | |
type: 'uint256', | |
}, | |
{ | |
name: '_tokenName', | |
type: 'string', | |
}, | |
{ | |
name: '_decimalUnits', | |
type: 'uint8', | |
}, | |
{ | |
name: '_tokenSymbol', | |
type: 'string', | |
}, | |
], | |
type: 'constructor', | |
}, | |
{ | |
payable: false, | |
type: 'fallback', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: true, | |
name: '_from', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
name: '_to', | |
type: 'address', | |
}, | |
{ | |
indexed: false, | |
name: '_value', | |
type: 'uint256', | |
}, | |
], | |
name: 'Transfer', | |
type: 'event', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: true, | |
name: '_owner', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
name: '_spender', | |
type: 'address', | |
}, | |
{ | |
indexed: false, | |
name: '_value', | |
type: 'uint256', | |
}, | |
], | |
name: 'Approval', | |
type: 'event', | |
}, | |
] as const; | |
export const abiERC721 = [ | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: 'interfaceID', | |
type: 'bytes4', | |
}, | |
], | |
name: 'supportsInterface', | |
outputs: [ | |
{ | |
name: '', | |
type: 'bool', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [], | |
name: 'name', | |
outputs: [ | |
{ | |
name: '_name', | |
type: 'string', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
], | |
name: 'getApproved', | |
outputs: [ | |
{ | |
name: '', | |
type: 'address', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_approved', | |
type: 'address', | |
}, | |
{ | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
], | |
name: 'approve', | |
outputs: [], | |
payable: true, | |
stateMutability: 'payable', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [], | |
name: 'totalSupply', | |
outputs: [ | |
{ | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_from', | |
type: 'address', | |
}, | |
{ | |
name: '_to', | |
type: 'address', | |
}, | |
{ | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
], | |
name: 'transferFrom', | |
outputs: [], | |
payable: true, | |
stateMutability: 'payable', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_owner', | |
type: 'address', | |
}, | |
{ | |
name: '_index', | |
type: 'uint256', | |
}, | |
], | |
name: 'tokenOfOwnerByIndex', | |
outputs: [ | |
{ | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_from', | |
type: 'address', | |
}, | |
{ | |
name: '_to', | |
type: 'address', | |
}, | |
{ | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
], | |
name: 'safeTransferFrom', | |
outputs: [], | |
payable: true, | |
stateMutability: 'payable', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_index', | |
type: 'uint256', | |
}, | |
], | |
name: 'tokenByIndex', | |
outputs: [ | |
{ | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
], | |
name: 'ownerOf', | |
outputs: [ | |
{ | |
name: '', | |
type: 'address', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_owner', | |
type: 'address', | |
}, | |
], | |
name: 'balanceOf', | |
outputs: [ | |
{ | |
name: '', | |
type: 'uint256', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [], | |
name: 'symbol', | |
outputs: [ | |
{ | |
name: '_symbol', | |
type: 'string', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_operator', | |
type: 'address', | |
}, | |
{ | |
name: '_approved', | |
type: 'bool', | |
}, | |
], | |
name: 'setApprovalForAll', | |
outputs: [], | |
payable: false, | |
stateMutability: 'nonpayable', | |
type: 'function', | |
}, | |
{ | |
constant: false, | |
inputs: [ | |
{ | |
name: '_from', | |
type: 'address', | |
}, | |
{ | |
name: '_to', | |
type: 'address', | |
}, | |
{ | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
{ | |
name: 'data', | |
type: 'bytes', | |
}, | |
], | |
name: 'safeTransferFrom', | |
outputs: [], | |
payable: true, | |
stateMutability: 'payable', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
], | |
name: 'tokenURI', | |
outputs: [ | |
{ | |
name: '', | |
type: 'string', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
constant: true, | |
inputs: [ | |
{ | |
name: '_owner', | |
type: 'address', | |
}, | |
{ | |
name: '_operator', | |
type: 'address', | |
}, | |
], | |
name: 'isApprovedForAll', | |
outputs: [ | |
{ | |
name: '', | |
type: 'bool', | |
}, | |
], | |
payable: false, | |
stateMutability: 'view', | |
type: 'function', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: true, | |
name: '_from', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
name: '_to', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
], | |
name: 'Transfer', | |
type: 'event', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: true, | |
name: '_owner', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
name: '_approved', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
name: '_tokenId', | |
type: 'uint256', | |
}, | |
], | |
name: 'Approval', | |
type: 'event', | |
}, | |
{ | |
anonymous: false, | |
inputs: [ | |
{ | |
indexed: true, | |
name: '_owner', | |
type: 'address', | |
}, | |
{ | |
indexed: true, | |
name: '_operator', | |
type: 'address', | |
}, | |
{ | |
indexed: false, | |
name: '_approved', | |
type: 'bool', | |
}, | |
], | |
name: 'ApprovalForAll', | |
type: 'event', | |
}, | |
] as const; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment