API Reference

NonFungibleToken API

This module provides the full NonFungibleToken module API.

For an overview of the module, read the NonFungibleToken guide.

import "./node_modules/@openzeppelin/compact-contracts/token/NonFungibleToken";

Ledger

_name: Opaque<"string">

sealed ledger

#

The token's human-readable name, set once at construction.

_symbol: Opaque<"string">

sealed ledger

#

The token's ticker symbol, set once at construction.

_isInitialized: Boolean

ledger

#

Initialization flag, tracked per-module to avoid the compiler's shared transitive-dependency state bug (LFDT-Minokawa/compact#270). See the Initializable module for rationale.

_owners: Map<Uint<128>, Either<Bytes<32>, ContractAddress>>

ledger

#

Mapping from token IDs to their owner addresses.

_balances: Map<Either<Bytes<32>, ContractAddress>, Uint<128>>

ledger

#

Mapping from account addresses to their token balances.

_tokenApprovals: Map<Uint<128>, Either<Bytes<32>, ContractAddress>>

ledger

#

Mapping from token IDs to approved addresses.

_operatorApprovals: Map<Either<Bytes<32>, ContractAddress>, Map<Either<Bytes<32>, ContractAddress>, Boolean>>

ledger

#

Mapping from owner addresses to operator approvals.

_tokenURIs: Map<Uint<128>, Opaque<"string">>

ledger

#

Mapping from token IDs to their metadata URIs.

Witnesses

wit_NonFungibleTokenSK() → Bytes<32>

witness

#

Returns the caller's secret key used in deriving the account identifier.

The same key produces the same account identifier across all contracts. Users who desire cross-contract unlinkability should use different keys per contract.

Circuits

initialize(name_: Opaque<"string">, symbol_: Opaque<"string">) → []

circuit

#

Initializes the contract by setting the name and symbol.

This MUST be called in the implementing contract's constructor. Failure to do so can lead to an irreparable contract.

Requirements:

  • Contract is not initialized.

balanceOf(owner: Either<Bytes<32>, ContractAddress>) → Uint<128>

circuit

#

Returns the number of tokens in owner's account.

Requirements:

  • The contract is initialized.
k=10, rows=671

ownerOf(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>

circuit

#

Returns the owner of the tokenId token.

Requirements:

  • The contract is initialized.
  • The tokenId must exist.
k=9, rows=331

name() → Opaque<"string">

circuit

#

Returns the token name.

Requirements:

  • The contract is initialized.
k=6, rows=26

symbol() → Opaque<"string">

circuit

#

Returns the symbol of the token.

Requirements:

  • The contract is initialized.
k=6, rows=26

tokenURI(tokenId: Uint<128>) → Opaque<"string">

circuit

#

Returns the token URI for the given tokenId. Returns the empty string if a tokenURI does not exist.

Requirements:

  • The contract is initialized.
  • The tokenId must exist.

Native strings and string operations aren't supported within the Compact language, e.g. concatenating a base URI + token ID is not possible like in other NFT implementations. Therefore, we propose the URI storage approach; whereby, NFTs may or may not have unique "base" URIs. It's up to the implementation to decide on how to handle this.

k=9, rows=324

_setTokenURI(tokenId: Uint<128>, tokenURI: Opaque<"string">) → []

circuit

#

Sets the URI as tokenURI for the given tokenId.

Requirements:

  • The contract is initialized.
  • The tokenId must exist.

The URI for a given NFT is usually set when the NFT is minted.

k=9, rows=287

approve(to: Either<Bytes<32>, ContractAddress>, tokenId: Uint<128>) → []

circuit

#

Gives permission to to to transfer tokenId token to another account. The approval is cleared when the token is transferred.

Only a single account can be approved at a time, so approving the zero value clears previous approvals.

In the case of an external (non-contract) caller, the caller's identity is derived from the wit_NonFungibleTokenSK witness as persistentHash(secretKey).

Requirements:

  • The contract is initialized.
  • The caller must either own the token or be an approved operator.
  • tokenId must exist.
k=13, rows=3406

getApproved(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>

circuit

#

Returns the account approved for tokenId token.

Requirements:

  • The contract is initialized.
  • tokenId must exist.
k=9, rows=420

setApprovalForAll(
  operator: Either<Bytes<32>, ContractAddress>,
  approved: Boolean
) → []

circuit

#

Approve or remove operator as an operator for the caller. Operators can call transferFrom for any token owned by the caller.

In the case of an external (non-contract) caller, the caller's identity is derived from the wit_NonFungibleTokenSK witness as persistentHash(secretKey).

Requirements:

  • The contract is initialized.
  • The operator cannot be zero.
k=13, rows=2938

isApprovedForAll(
  owner: Either<Bytes<32>, ContractAddress>,
  operator: Either<Bytes<32>, ContractAddress>
) → Boolean

circuit

#

Returns if the operator is allowed to manage all of the assets of owner.

Requirements:

  • The contract is initialized.
k=11, rows=1341

transferFrom(
  fromAddress: Either<Bytes<32>, ContractAddress>,
  to: Either<Bytes<32>, ContractAddress>,
  tokenId: Uint<128>
) → []

circuit

#

Transfers tokenId token from fromAddress to to.

Transfers to contract addresses are currently disallowed until contract-to-contract interactions are supported in Compact. This restriction prevents assets from being inadvertently locked in contracts that cannot currently handle token receipt.

In the case of an external (non-contract) caller, the caller's identity is derived from the wit_NonFungibleTokenSK witness as persistentHash(secretKey).

Requirements:

  • The contract is initialized.
  • fromAddress is not zero.
  • to is not zero.
  • to is not a ContractAddress.
  • tokenId token must be owned by fromAddress.
  • If the caller is not fromAddress, it must be approved to move this token by either approve or setApprovalForAll.
k=13, rows=4702

_unsafeTransferFrom(
  fromAddress: Either<Bytes<32>, ContractAddress>,
  to: Either<Bytes<32>, ContractAddress>,
  tokenId: Uint<128>
) → []

circuit

#

Transfers tokenId token from fromAddress to to. It does NOT check if the recipient is a ContractAddress.

In the case of an external (non-contract) caller, the caller's identity is derived from the wit_NonFungibleTokenSK witness as persistentHash(secretKey).

Transfers to contract addresses are considered unsafe because contract-to-contract calls are not currently supported. Tokens sent to a contract address may become irretrievable. Once contract-to-contract calls are supported, this circuit may be deprecated.

Requirements:

  • The contract is initialized.
  • fromAddress is not zero.
  • to is not zero.
  • tokenId token must be owned by fromAddress.
  • If the caller is not fromAddress, it must be approved to move this token by either approve or setApprovalForAll.
k=13, rows=4699

_ownerOf(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>

circuit

#

Returns the owner of the tokenId. Does NOT revert if token doesn't exist.

Requirements:

  • The contract is initialized.
k=9, rows=306

_getApproved(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>

circuit

#

Returns the approved address for tokenId. Returns the zero value if tokenId is not minted.

Requirements:

  • The contract is initialized.
k=9, rows=306

_isAuthorized(
  owner: Either<Bytes<32>, ContractAddress>,
  spender: Either<Bytes<32>, ContractAddress>,
  tokenId: Uint<128>
) → Boolean

circuit

#

Returns whether spender is allowed to manage owner's tokens, or tokenId in particular (ignoring whether it is owned by owner).

Requirements:

  • The contract is initialized.

This function assumes that owner is the actual owner of tokenId and does not verify this assumption.

k=11, rows=1796

_checkAuthorized(
  owner: Either<Bytes<32>, ContractAddress>,
  spender: Either<Bytes<32>, ContractAddress>,
  tokenId: Uint<128>
) → []

circuit

#

Checks if spender can operate on tokenId, assuming the provided owner is the actual owner.

Requirements:

  • The contract is initialized.
  • spender has approval from owner for tokenId OR spender has approval to manage all of owner's assets.

This function assumes that owner is the actual owner of tokenId and does not verify this assumption.

k=11, rows=1802

_mint(to: Either<Bytes<32>, ContractAddress>, tokenId: Uint<128>) → []

circuit

#

Mints tokenId and transfers it to to.

Requirements:

  • The contract is initialized.
  • tokenId must not exist.
  • to is not zero.
  • to is not a ContractAddress.
k=11, rows=1388

_unsafeMint(to: Either<Bytes<32>, ContractAddress>, tokenId: Uint<128>) → []

circuit

#

Mints tokenId and transfers it to to. It does NOT check if the recipient is a ContractAddress.

Requirements:

  • The contract is initialized.
  • tokenId must not exist.
  • to is not zero.

Transfers to contract addresses are considered unsafe because contract-to-contract calls are not currently supported. Tokens sent to a contract address may become irretrievable. Once contract-to-contract calls are supported, this circuit may be deprecated.

k=11, rows=1385

_burn(tokenId: Uint<128>) → []

circuit

#

Destroys tokenId. The approval is cleared when the token is burned. This circuit does not check if the sender is authorized to operate on the token.

Requirements:

  • The contract is initialized.
  • tokenId must exist.
k=10, rows=507

_transfer(
  fromAddress: Either<Bytes<32>, ContractAddress>,
  to: Either<Bytes<32>, ContractAddress>,
  tokenId: Uint<128>
) → []

circuit

#

Transfers tokenId from fromAddress to to. As opposed to transferFrom, this imposes no restrictions on the caller's identity.

Transfers to contract addresses are currently disallowed until contract-to-contract interactions are supported in Compact. This restriction prevents assets from being inadvertently locked in contracts that cannot currently handle token receipt.

Requirements:

  • The contract is initialized.
  • to is not zero.
  • to is not a ContractAddress.
  • tokenId token must be owned by fromAddress.
k=11, rows=1982

_unsafeTransfer(
  fromAddress: Either<Bytes<32>, ContractAddress>,
  to: Either<Bytes<32>, ContractAddress>,
  tokenId: Uint<128>
) → []

circuit

#

Transfers tokenId from fromAddress to to. As opposed to _unsafeTransferFrom, this imposes no restrictions on the caller's identity. It does NOT check if the recipient is a ContractAddress.

Requirements:

  • The contract is initialized.
  • to is not zero.
  • tokenId token must be owned by fromAddress.

Transfers to contract addresses are considered unsafe because contract-to-contract calls are not currently supported. Tokens sent to a contract address may become irretrievable. Once contract-to-contract calls are supported, this circuit may be deprecated.

k=11, rows=1979

_approve(
  to: Either<Bytes<32>, ContractAddress>,
  tokenId: Uint<128>,
  auth: Either<Bytes<32>, ContractAddress>
) → []

circuit

#

Approve to to operate on tokenId.

Requirements:

  • The contract is initialized.
  • tokenId must exist.
  • If auth is non 0, then this function will check that auth is either the owner of the token, or approved to operate on the token (by the owner).
k=11, rows=1755

_unsafeApprove(
  to: Either<Bytes<32>, ContractAddress>,
  tokenId: Uint<128>,
  auth: Either<Bytes<32>, ContractAddress>,
  isExistenceRequired: Boolean
) → []

circuit

#

Approve to to operate on tokenId, requiring the token to exist only when isExistenceRequired is true.

Passing false skips the check that tokenId was minted. Both _unsafeTransferFrom and _update read that invariant back, so a planted approval can mint a token nobody authorized or outlive a later mint. Pass false only where the owner has already been read, as _update does.

Counterpart to Solidity's _approve(to, tokenId, auth, bool emitEvent), where the flag also suppresses the Approval event. Compact has no events, so it carries the existence check alone.

Requirements:

  • The contract is initialized.
  • tokenId must exist, unless isExistenceRequired is false and auth is zero.
  • If auth is non 0, then this function will check that auth is either the owner of the token, or approved to operate on the token (by the owner).
k=11, rows=1868

_setApprovalForAll(
  owner: Either<Bytes<32>, ContractAddress>,
  operator: Either<Bytes<32>, ContractAddress>,
  approved: Boolean
) → []

circuit

#

Approve operator to operate on all of owner tokens.

Requirements:

  • The contract is initialized.
  • owner is not zero.
  • operator is not zero.
k=11, rows=1280

_requireOwned(tokenId: Uint<128>) → Either<Bytes<32>, ContractAddress>

circuit

#

Reverts if the tokenId doesn't have a current owner (it hasn't been minted, or it has been burned). Returns the owner.

Requirements:

  • The contract is initialized.
  • tokenId must exist.
k=9, rows=329