diff --git a/lib/ethers/contracts/erc1155.ex b/lib/ethers/contracts/erc1155.ex index aa49387..83284df 100644 --- a/lib/ethers/contracts/erc1155.ex +++ b/lib/ethers/contracts/erc1155.ex @@ -2,8 +2,16 @@ defmodule Ethers.Contracts.ERC1155 do @moduledoc """ ERC1155 token interface - More info: https://ethereum.org/en/developers/docs/standards/tokens/erc-1155/ + More info: https://eips.ethereum.org/EIPS/eip-1155 """ use Ethers.Contract, abi: :erc1155 + + @behaviour Ethers.Contracts.ERC165 + + # ERC-165 Interface ID + @interface_id Ethers.Utils.hex_decode!("0xd9b67a26") + + @impl Ethers.Contracts.ERC165 + def erc165_interface_id, do: @interface_id end diff --git a/lib/ethers/contracts/erc165.ex b/lib/ethers/contracts/erc165.ex new file mode 100644 index 0000000..374fc2d --- /dev/null +++ b/lib/ethers/contracts/erc165.ex @@ -0,0 +1,30 @@ +defmodule Ethers.Contracts.ERC165 do + @moduledoc """ + ERC-165 Standard Interface Detection + + More info: https://eips.ethereum.org/EIPS/eip-165 + """ + use Ethers.Contract, abi: :erc165 + + @behaviour __MODULE__ + + @callback erc165_interface_id() :: <<_::32>> + + @interface_id Ethers.Utils.hex_decode!("0x01ffc9a7") + + defmodule NotERC165CompatibleError do + defexception [:message] + end + + @impl __MODULE__ + def erc165_interface_id, do: @interface_id + + def supports_interface(iface) when is_atom(iface) do + supports_interface(iface.erc165_interface_id()) + rescue + UndefinedFunctionError -> + reraise NotERC165CompatibleError, + "module #{iface} does not implement ERC165 behaviour", + __STACKTRACE__ + end +end diff --git a/lib/ethers/contracts/erc721.ex b/lib/ethers/contracts/erc721.ex index d3dc58d..b3966c1 100644 --- a/lib/ethers/contracts/erc721.ex +++ b/lib/ethers/contracts/erc721.ex @@ -2,8 +2,16 @@ defmodule Ethers.Contracts.ERC721 do @moduledoc """ ERC721 token interface - More info: https://ethereum.org/en/developers/docs/standards/tokens/erc-721/ + More info: https://eips.ethereum.org/EIPS/eip-721 """ use Ethers.Contract, abi: :erc721 + + @behaviour Ethers.Contracts.ERC165 + + # Interface ID + @interface_id Ethers.Utils.hex_decode!("0x80ac58cd") + + @impl Ethers.Contracts.ERC165 + def erc165_interface_id, do: @interface_id end diff --git a/priv/abi/erc165.json b/priv/abi/erc165.json new file mode 100644 index 0000000..50dd916 --- /dev/null +++ b/priv/abi/erc165.json @@ -0,0 +1,23 @@ +[ + { + "inputs": + [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +]