> ## Documentation Index
> Fetch the complete documentation index at: https://docs.notareum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Nft provenance

# NFT Provenance

NFTs are trivial to clone. The token standard binds a `(contract, tokenId)` pair to a URI, but nothing at the protocol level says the URI is authentic, the artist is who the listing claims, or the same work has not been minted on five other chains by impostors. Notareum binds an NFT (or an entire collection) to a creator identity via a signed `.nota` file, then anchors that binding in `NotaRegistry` where marketplaces and wallets can check it before they render, list, or buy.

## What gets bound

Two levels of binding are useful:

1. **Collection-level** `.nota` for the deployed ERC-721/ERC-1155 contract. Proves "this collection was created by this artist/studio". Issued once per deployment.
2. **Token-level** `.nota` for a specific `(contract, tokenId)`. Proves "this specific edition is authorized by the creator with this metadata". Issued per mint or per edition.

Collection-level is sufficient for most use cases. Token-level matters for 1-of-1 art, limited editions, and authenticated secondary sales.

```mermaid theme={"system"}
flowchart TB
    Artist[Artist identity] -->|signs| ColNota[Collection .nota]
    Artist -->|signs| TokNota[Token .nota]
    ColNota --> Collection[NFT Contract]
    TokNota --> Collection
    TokNota -->|tokenId| Edition[Specific tokenId]
    Collection --> Registry[NotaRegistry]
    Edition --> Registry
    Registry --> Market[Marketplace / Wallet]
```

## Creating a collection `.nota`

```typescript theme={"system"}
import { Notareum } from "@notareum/sdk";

const ntm = Notareum({ provider, signer: artistSigner, contracts });

const collectionNota = await ntm.nota
  .create({
    type: "nft_collection",
    chainId: 1,
    chainName: "ethereum",
    identifier: "0x...NftContractAddress",
    name: "Meridian by Alba Ruiz",
    description: "50-piece generative series, 2026.",
    alias: "meridian.alba.eth",
    resourceMetadata: {
      standard: "ERC-721",
      totalSupply: 50,
      artistName: "Alba Ruiz",
      artistSite: "https://albaruiz.art",
      metadataBaseUri: "ipfs://bafybeigdy...",
      metadataHash: "0xc3ab8ff137...",
      mintedAt: "2026-02-14",
      licenseSpdx: "CC-BY-NC-4.0",
    },
    issuerName: "Alba Ruiz",
    issuerEntityType: "individual",
  })
  .validate()
  .sign(artistSigner);

await ntm.registry.registerResource(collectionNota);
await ntm.verification.requestVerification(collectionNota.resourceId(), {
  level: "enhanced",
});
```

`metadataBaseUri` and `metadataHash` let a consumer check that the contract's `tokenURI` output is under the registered base and hashes to the expected root. Any drift signals tampered metadata.

## Creating a token `.nota`

```typescript theme={"system"}
const tokenNota = await ntm.nota
  .create({
    type: "nft",
    chainId: 1,
    chainName: "ethereum",
    identifier: "0x...NftContractAddress:7",
    name: "Meridian #7",
    description: "Hand-finished print, edition 7 of 50.",
    resourceMetadata: {
      contract: "0x...NftContractAddress",
      tokenId: "7",
      standard: "ERC-721",
      metadataUri: "ipfs://bafkreib5y...meta7.json",
      metadataHash: "0x9f2a4b1e...",
      mediaUri: "ipfs://bafkreif6x...media7.png",
      mediaHash: "0x48e1c9d0...",
    },
    issuerName: "Alba Ruiz",
    issuerEntityType: "individual",
  })
  .sign(artistSigner);
```

`identifier` encodes the composite `(contract, tokenId)` so the deterministic resource ID is unique per token. The SDK uses `:` as the separator by convention.

## Detecting fakes

A marketplace renders a listing by looking up the collection contract in `NotaRegistry`:

```typescript theme={"system"}
async function renderListing(contractAddr: string, tokenId: bigint) {
  // 1. Collection-level check
  const colId = ntm.registry.computeResourceId("nft_collection", 1, contractAddr);
  const col = await ntm.registry.getResource(colId);
  if (!col.exists || col.isRevoked) {
    return { status: "unverified", warning: "Unrecognized collection" };
  }

  // 2. Metadata tamper check
  const tokenUri = await nftContract.tokenURI(tokenId);
  const metadata = await fetch(tokenUri).then((r) => r.json());
  if (!tokenUri.startsWith(col.metadataBaseUri)) {
    return { status: "tampered", warning: "tokenURI outside registered base" };
  }

  return {
    status: "verified",
    artist: col.issuerName,
    level: col.level,
    license: col.resourceMetadata.licenseSpdx,
  };
}
```

A marketplace that enforces this check eliminates the three most common NFT fraud vectors: impostor contracts with the same metadata, metadata swaps after minting, and cross-chain impersonation.

## Cross-chain provenance

A single artist often mints the same work on Ethereum, Polygon, Base, and Solana. Notareum represents this with multiple `.nota` files sharing the same issuer key but different `(chainId, identifier)` pairs, plus an optional `canonicalResource` field that points to the original mint:

```json theme={"system"}
{
  "resource": {
    "type": "nft_collection",
    "chainId": 137,
    "identifier": "0x...polygonContract",
    "resourceMetadata": {
      "canonicalResource": {
        "chainId": 1,
        "identifier": "0x...ethereumContract"
      },
      "bridgeProof": "ipfs://bafybei...proofofBurn"
    }
  }
}
```

A wallet can follow `canonicalResource` to find the original and its verification status. This defeats the "collection was minted on mainnet, fakes mint on L2" class of fraud.

## Secondary market receipts

Each sale can produce a receipt `.nota` containing:

* The on-chain transaction hash.
* The seller, buyer, and marketplace identities.
* Royalty destination (and whether royalties were honored).
* Price, currency, and timestamp.

The buyer receives a portable proof of ownership provenance that survives the marketplace going offline.

```typescript theme={"system"}
const receipt = await ntm.nota
  .create({
    type: "transaction",
    chainId: 1,
    chainName: "ethereum",
    identifier: txHash,
    name: "Sale: Meridian #7",
    resourceMetadata: {
      tokenResource: tokenNota.resourceId(),
      seller: sellerAddr,
      buyer: buyerAddr,
      marketplace: "opensea",
      price: "3.25",
      currency: "ETH",
      royaltyPaid: "0.1625",
      royaltyRecipient: artistAddr,
    },
  })
  .sign(marketplaceSigner);
```

## Artist workflows

* **Identity registration.** The artist registers a self-describing `.nota` of type `"address"` with an alias (e.g., `alba.art`). All subsequent collection `.nota` files come from the same key and inherit reputation.
* **Studio delegation.** A studio can register a multisig as issuer. Attestations from individual artists are layered as additional signatures on the `.nota` file via the optional `coSigners` field.
* **License metadata.** SPDX license codes in `resourceMetadata.licenseSpdx` give marketplaces a machine-readable license badge.

## Integration patterns

* **OpenSea-class marketplaces** check collection `.nota` before rendering a "verified creator" badge.
* **Wallets** flag NFTs from unregistered collections during display.
* **Aggregators** filter phishing airdrops by requiring at least a registered, non-revoked `.nota` before the token is shown in a user's inventory.
* **IP tooling** uses `licenseSpdx` to auto-generate license enforcement pages.

## Related pages

* [.nota File Format](../protocol/nota-file-format.md)
* [Smart Contract Verification](smart-contract-verification.md)
* [Cross-Chain Identity](cross-chain-identity.md)
* [NotaRegistry Contract](../smart-contracts/nota-registry.md)
