ERCs

ERC-721 — Non-Fungible Token Standard

eips.ethereum.org/EIPS/eip-721

import {
  balanceOf,
  ownerOf,
  transferFrom,
  safeTransferFrom_42842e0e,
  safeTransferFrom_b88d4fde,
  approve,
  getApproved,
  setApprovalForAll,
  isApprovedForAll,
} from "@ethernauta/erc/721";

void balanceOf;
void ownerOf;
void transferFrom;
void safeTransferFrom_42842e0e;
void safeTransferFrom_b88d4fde;
void approve;
void getApproved;
void setApprovalForAll;
void isApprovedForAll;

Core methods

MethodShapePurpose
balanceOf({ owner })Callable<Uint256>NFT count owned.
ownerOf({ token_id })Callable<Address>Current owner.
transferFrom({ from, to, token_id })Signable<Hash32>Unsafe transfer.
safeTransferFrom({ from, to, token_id, data? })Signable<Hash32>Safe transfer (checks receiver).
approve({ to, token_id })Signable<Hash32>Per-token approval.
getApproved({ token_id })Callable<Address>Read approval.
setApprovalForAll({ operator, approved })Signable<Hash32>All-token approval.
isApprovedForAll({ owner, operator })Callable<boolean>Read operator approval.

Extensions

SubpathMethods
@ethernauta/erc/721/burnableburn
@ethernauta/erc/721/enumerabletotalSupply, token_of_owner_by_index, token_by_index
@ethernauta/erc/721/metadataname, symbol, tokenURI
@ethernauta/erc/721/pausablepause, unpause, paused

Reading owner + metadata

import { parse } from "valibot";
import type { Bytes } from "@ethernauta/core";
import { AddressSchema, Uint256Schema } from "@ethernauta/core";
import { ownerOf } from "@ethernauta/erc/721";
import { tokenURI } from "@ethernauta/erc/721/extensions/metadata";
import { eth_call } from "@ethernauta/eth";
import { contract, create_reader, encode_chain_id, http } from "@ethernauta/transport";
import { eip155_1 } from "@ethernauta/chain/eip155-1";

const CHAIN_ID = encode_chain_id({ namespace: "eip155", reference: eip155_1.chainId });
const reader = create_reader([
  { chainId: CHAIN_ID, transports: [http("https://ethereum-rpc.publicnode.com")] },
]);

const collection = parse(AddressSchema, "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D");
const tokenId = parse(Uint256Schema, "0x1");
const ctx = contract({ chain_id: CHAIN_ID, to: collection });

const owner_callable = ownerOf({ tokenId })(ctx);
const owner_bytes: Bytes = await eth_call([{ to: owner_callable.to, input: owner_callable.data }])(
  reader({ chain_id: CHAIN_ID }),
);
const owner = owner_callable.decode(owner_bytes);
void owner;

const uri_callable = tokenURI({ tokenId })(ctx);
const uri_bytes: Bytes = await eth_call([{ to: uri_callable.to, input: uri_callable.data }])(
  reader({ chain_id: CHAIN_ID }),
);
const uri = uri_callable.decode(uri_bytes);
void uri;

See also

  • ERC-1155 — multi-token alternative.
  • ERC-2981 — royalties for NFTs.
  • ERC-4494 — permit for ERC-721.
  • ERC-165 — interface detection (most NFTs implement 165).