Deno & Fetch
A Deno-based script for minting CIP-68 assets on the Cardano blockchain using the Anvil API. This guide provides a complete example for building, signing, and submitting a transaction to mint a CIP-68
Quick-Start Example
This streamlined tutorial shows how to mint a CIP-68 NFT on Cardano using Deno + Fetch and the Anvil API.
We'll:
Load wallets (Customer, Policy, Metadata Manager)
Create a native script using our Native Script utilities
Build a mint payload that creates both tokens (
100
+222
) in the same transaction.Call
transactions/build
Sign with the Policy & Customer (
skeys
) keys. Customer in the backend for simplicity.Submit the transaction
Verify on-chain that the assets are minted:
The reference token is sent to the metadata manager wallet
The user token is sent to the customer wallet
Prerequisites
Three Wallets – You'll need three wallets with these fields:
Customer Wallet: Pays fees, receives user token (label 222)
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...
)
Metadata Manager Wallet: Receives reference token (label 100)
base_address_preprod
: Testnet address (addr_test1...
)skey
: Signing key (optional for this script. Used when updating metadata)
Create wallets with our Wallet CLI. Ensure customer wallet has ADA for fees.
Anvil API Key – A valid Anvil API key. See Authentication.
Utility Helpers – Import helpers from the utilities-functions 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, etc.)
│ └── constant.ts # API configuration (URLs, headers)
├── wallet-customer.json # Customer wallet (pays fees, receives user token)
├── wallet-policy.json # Policy wallet (controls minting policy)
└── wallet-meta-manager.json # Metadata manager wallet (receives reference token)
Quick-Start Script
import { Buffer } from "node:buffer";
import {
FixedTransaction,
PrivateKey,
} from "npm:@emurgo/[email protected]";
import {
timeToSlot,
getKeyhash,
createNativeScript,
} 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"));
const metaManagerWallet = JSON.parse(Deno.readTextFileSync("wallet-meta-manager.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);
const counter = Date.now();
const assetName = `anvilapicip68_${counter}`;
// Build mint payload
const buildBody = {
changeAddress: customerWallet.base_address_preprod,
mint: [
{
// Reference token - label 100, sent to Metadata-Manager wallet
version: "cip68",
assetName: { name: assetName, format: "utf8", label: 100 },
metadata: {
name: `anvil-api-${counter}`,
image: "ipfs://YOUR_IPFS_HASH_HERE",
mediaType: "image/png",
description: "Anvil API CIP-68 Mint Example",
},
policyId: nativeScript.hash,
quantity: 1,
destAddress: metaManagerWallet.base_address_preprod,
},
{
// User token - label 222, sent to Customer wallet
version: "cip68",
assetName: { name: assetName, format: "utf8", label: 222 },
policyId: nativeScript.hash,
quantity: 1,
destAddress: customerWallet.base_address_preprod,
},
],
preloadedScripts: [nativeScript],
};
// Build transaction
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"));
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 for detailed API endpoint information and examples.
The utility files provide these key functions:
timeToSlot(date)
- Converts timestamps to Cardano slotsgetKeyhash(address)
- Extracts payment key hash from addressescreateNativeScript(keyHash, ttl)
- Creates time-locked native scriptsAPI configuration - Anvil API endpoints and headers
💡 Tip: The anvil-api-examples repository contains the most up-to-date utility functions and is the recommended source.
Running the Script
# 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
andutils/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
CIP-68 Specific Notes
Two tokens are minted in the same transaction:
Reference token (label 100) - Contains metadata, sent to metadata manager wallet
User token (label 222) - The actual NFT, sent to customer wallet
Full Example Script
For complete, fully-annotated examples see the examples repository:
Last updated
Was this helpful?