# Deno & Fetch

**Quick-Start Example**

This streamlined tutorial shows how to mint a **CIP-25 NFT** on Cardano using **Deno + Fetch** and the **Anvil API**. Everything lives in a single file (`mint.ts`) so you can copy-paste and run.

We'll:

1. Load wallets (Customer, Policy)
2. Create a native script using our [Native Script utilities](/developer-tools/utility-functions.md)
3. Build a mint payload for one CIP-25 asset
4. Call `transactions/build`
5. Sign with the Policy & Customer keys (customer signature is done in the backend for simplicity)
6. Submit the transaction
7. Verify the NFT on-chain

***

## Prerequisites

**Two Wallets** – You'll need two wallets with these fields:

* **Customer Wallet**: Pays fees, receives the minted NFT
  * `base_address_preprod`: Testnet address (`addr_test1...`)
  * `skey`: Signing key (`ed25519e_sk1...`)
* **Policy Wallet**: Controls minting policy
  * `base_address_preprod`: Testnet address (`addr_test1...`)
  * `skey`: Signing key (`ed25519e_sk1...`)

{% hint style="info" %}
**New to Cardano?** A "signing key" (skey) is your wallet's private key that proves you own the wallet. The "base address" is like your bank account number where ADA is stored. If you don't have wallets, see the [Wallet CLI documentation](/developer-tools/wallet-cli.md) THIS SHOULD BE STORED SECURELY AND NEVER SHARED OR EXPOSED. See the documentation for best practices.
{% endhint %}

**Anvil API Key** – A valid Anvil API key. See [Authentication](/anvil-api/authentication.md).

**Utility Helpers** – Import helpers from the [utilities-functions](/developer-tools/utility-functions.md) guide to keep this file short.

***

## Project Structure

For the absolute minimum setup, you only need:

```
your-project/
├── mint.ts                 # Main minting script
├── utils/
│   ├── shared.ts          # Utility functions (timeToSlot, getKeyhash, createNativeScript)
│   └── constant.ts        # API configuration (URLs, headers)
├── wallet-customer.json   # Customer wallet (pays fees, receives NFT)
└── wallet-policy.json     # Policy wallet (controls minting policy)
```

***

## Quick-Start Script

```ts
import { Buffer } from "node:buffer";
import {
  FixedTransaction,
  PrivateKey,
} from "npm:@emurgo/cardano-serialization-lib-nodejs@14.1.1";
import {
  createNativeScript,
  timeToSlot,
  getKeyhash,
} from "../utils/shared.ts";
import { API_URL, HEADERS } from "../utils/constant.ts";

// Load wallets
const customerWallet = JSON.parse(Deno.readTextFileSync("wallet-customer.json"));
const policyWallet = JSON.parse(Deno.readTextFileSync("wallet-policy.json"));

// Create native script
const slot = await timeToSlot(new Date("2026-01-01"));
const keyhash = await getKeyhash(policyWallet.base_address_preprod);
const nativeScript = await createNativeScript(keyhash!, slot);

// Prepare mint payload
const counter = Date.now();
const assetName = `anvilapicip25_${counter}`;

// Build transaction
const buildBody = {
  changeAddress: customerWallet.base_address_preprod,
  mint: [
    {
      // CIP-25 asset with Metadata
      version: "cip25",
      assetName: { name: assetName, format: "utf8" },
      metadata: {
        name: `anvil-api-${counter}`,
        image: `ipfs://YOUR_IPFS_HASH_HERE`,
        mediaType: "image/png",
        description: "Anvil API CIP-25 Mint Example",
      },
      policyId: nativeScript.hash,
      quantity: 1,
    },
  ],
  preloadedScripts: [nativeScript],
};

const buildResult = await fetch(`${API_URL}/transactions/build`, {
  method: "POST",
  headers: HEADERS,
  body: JSON.stringify(buildBody),
});
const buildJson = await buildResult.json();
if (!buildResult.ok) {
  throw new Error(buildJson.message);
}

// Sign transaction
const tx = FixedTransaction.from_bytes(Buffer.from(buildJson.complete, "hex"));

// Sign with policy wallet
tx.sign_and_add_vkey_signature(PrivateKey.from_bech32(policyWallet.skey));

// Sign with customer wallet. Normally this would come from the clientside via your customers browser extenstion
// This is here for simplicity. See full minting examples below.
tx.sign_and_add_vkey_signature(PrivateKey.from_bech32(customerWallet.skey));

// Submit transaction
const submitResult = await fetch(`${API_URL}/transactions/submit`,
  {
    method: "POST",
    headers: HEADERS,
    body: JSON.stringify({ transaction: tx.to_hex() })
  });
const submitJson = await submitResult.json();

if (!submitResult.ok) {
  throw new Error(submitJson.message);
}

console.log("Submitted Transaction Hash: ", submitJson.txHash);
```

***

## Utility Files Reference

You'll need to create the utility files. See the [Utility Functions documentation](/developer-tools/utility-functions.md) for detailed API endpoint information and examples.

The utility files provide these key functions:

* **`timeToSlot(date: Date): Promise<number>`** - Converts timestamps to Cardano slots
* **`getKeyhash(address: string): Promise<string>`** - Extracts payment key hash from addresses
* **`createNativeScript(keyHash: string, ttl: number): Promise<{policyId: string, script: string}>`** - Creates time-locked native scripts
* **API configuration** - Anvil API endpoints and headers

> **💡 Tip**: The [anvil-api-examples repository](https://github.com/Cardano-Forge/anvil-api-examples/blob/main/utils/shared.ts) contains the most up-to-date utility functions and is the recommended source.

***

## Running the Script

```bash
# Run the script
deno run --allow-all mint.ts
```

***

## Troubleshooting

### Common Issues

**Error: "Module not found"**

* Check that your import paths match your project structure
* Ensure `utils/shared.ts` and `utils/constant.ts` exist

**Error: "Failed to get key hash for address"**

* Verify your wallet addresses are valid testnet addresses
* Check that wallet files contain proper JSON format
* Ensure addresses start with `addr_test1`

**Error: "API call failed: Input validation failed"**

* Usually means wallet address parsing failed
* Double-check wallet file format and addresses

**Error: "Unable to build tx"**

* Ensure customer wallet has sufficient ADA for fees
* Check that API key is valid
* Verify network connectivity

***

### Full Example Script

For complete, fully-annotated examples see the examples repository:

[Deno Example](https://github.com/Cardano-Forge/anvil-api-examples/blob/main/documentation-references/cip25.ts)

[HTMX + Hono + Weld Example](https://github.com/Cardano-Forge/anvil-api-examples/tree/main/minting-platform-cip25)

[Next.js + Weld Example](https://github.com/Cardano-Forge/anvil-api-examples/tree/main/nextjs-minting-platform-cip25)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.ada-anvil.io/guides/nft-and-ft/mint-nft-cip-25/deno-and-fetch.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
