# Creating Native Scripts

## Introduction

This guide provides step-by-step instructions for creating native scripts using the Anvil API's utility endpoints. For conceptual information about native scripts, their structure, and common patterns, see the [Native Scripts Overview](/guides/nft-and-ft/native-scripts.md).

## Workflow Overview

The process of creating and using native scripts with the Anvil API follows these key steps:

1. Parse Wallet Address - obtain key hash(es) for signature requirements (supports multisig with multiple addresses)
2. Convert DateTime to Slot - create a time constraint (optional but recommended)
3. Create JSON Native Script - combine key hash(s) and time constraints
4. Convert to Native Script and get policy ID - use the Anvil API to create a machine-readable format
5. Use in Transaction - include the script when minting tokens

## Prerequisites

* An Anvil API key
* A wallet address for signing transactions
* Basic understanding of [native scripts](/guides/nft-and-ft/native-scripts.md) and their role in minting tokens

## Using the Utils Endpoints

The Anvil API provides several utility endpoints to assist with creating and managing native scripts:

| Endpoint                          | Description                                                          |
| --------------------------------- | -------------------------------------------------------------------- |
| `/utils/addresses/parse`          | Parses an address and returns its payment and stake credentials      |
| `/utils/native-scripts/parse`     | Returns information about a provided native script (e.g., policy ID) |
| `/utils/native-scripts/serialize` | Creates a native script from it's JSON schema definition             |
| `/utils/network/time-to-slot`     | Converts a date/time to a Cardano slot number                        |
| `/utils/network/slot-to-time`     | Converts a Cardano slot number to a date/time                        |

## Step-by-Step Guide to Creating a Native Script for Minting rules.

### Step 1: Obtain a key used for policy actions.

To create a signature-based native script, you first need to obtain the key hash of the wallet that will sign the minting transactions. You can get this by parsing a wallet address using the address parsing endpoint:

```typescript
// Example request
await fetch('https://preprod.api.ada-anvil.app/v2/services/utils/addresses/parse', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Api-Key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({
    address: 'stake_address_or_payment_address_here'
  })
});

// Example response
{
  "payment": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "stake": "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"
}
```

The `payment` value from the response is what you'll use as the `keyHash` in your native script.

### Step 2: Convert Time to Slot (Optional)

To add a time constraint to your native script, convert a future DateTime to a Cardano slot number:

```typescript
// Example request
await fetch('https://preprod.api.ada-anvil.app/v2/services/utils/network/time-to-slot', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Api-Key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({
    timestamp: '2030-01-01T00:00:00Z'
  })
});

// Example response
{
  "slot": 98765432
}
```

This slot number will be used in your native script to create a time-limited minting policy.

### Step 3: Create JSON Native Script

Now that you have both the key hash (from Step 1) and optionally a slot number for time constraint (from Step 2), you can create the JSON structure for your native script.

Native scripts in the Anvil API follow a specific JSON structure that maps to Cardano's native script format. Each script uses a discriminated union with a `type` field that determines the script's behavior.

Here's how to combine the signature requirement and time constraint into a complete native script:

```json
{
  "type": "all",
  "scripts": [
    {
      "type": "sig",
      // Required Key hash from Step 1
      "keyHash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
    },
    {
      "type": "before",
      // Required Slot number from Step 2
      "slot": 98765432
    }
  ]
}
```

This JSON structure represents a native script that requires both the signature from the specified key hash AND the transaction to be submitted before the specified slot number.

### Step 4: Serialize the Native Script via API

While the JSON representation is a clear way to define the native script, it must be serialized into a specific hex format to be included in a transaction. The Anvil API provides a utility endpoint to handle this conversion. Here's how you can call the API with the JSON native script from Step 3:

```typescript
// The JSON native script from Step 3
const nativeScriptJSON = {
  type: "all",
  scripts: [
    {
      type: "sig",
      // Required Key hash from Step 1
      keyHash: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
    },
    {
      type: "before",
      // Required Slot number from Step 2
      slot: 98765432
    }
  ]
};

async function serializeNativeScript(nativeScriptJSON) {
  const response = await fetch("https://preprod.api.ada-anvil.app/v2/services/utils/native-scripts/serialize", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Api-Key": "YOUR_API_KEY"
    },
    body: JSON.stringify({ schema: nativeScriptJSON }),
  });

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`API call failed: ${errorText}`);
  }

  const { script, policyId } = await response.json();
    
  console.log("CBOR Hex-encoded Script:", script);
  console.log("Policy ID:", policyId);

  return { script, policyId };
}

// Get the serialized script and policy ID
const { script: hexEncodedScript, policyId } = await serializeNativeScript(nativeScriptJSON);
```

The API returns two crucial pieces of information:

1. **`script`**: The CBOR hex-encoded native script. This is what you will include in the transaction body.
2. **`policyId`**: The unique identifier for your native script, derived from hashing the script.

### Step 5: Use in Transaction

The final step is to use your native script when building transactions that mint or burn assets. You'll include the native script in the `preloadedScripts` section of your transaction request:

```typescript
const data = {
  changeAddress: "addr_test...",
  utxos: ["8282...", "8282..."],
  mint: [
    {
      version: "cip25",
      assetName: { name: "MyAsset", format: "utf8" },
      metadata: {
        name: "My Asset",
        image: ["ipfs://Qm..."],
        // Additional metadata fields
      },
      policyId, // The policy ID from Step 4
      quantity: 1,

      // Destination address for the minted asset
      destAddress: "addr_test..."
    }
  ],
  // This is required for the first mint transaction. Anvil API will fetch the scripts from the provided policy ID for any subsequent transactions.
  preloadedScripts: [
    {
      type: "simple",
      script: {
        // Your native script from Step 3
        type: "all",
        scripts: [
          {
            type: "sig",
            keyHash: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
          },
          {
            type: "before",
            slot: 98765432
          }
        ]
      },
      hash: policyId // The policy ID from Step 4
    }
  ]
};

const tx = await fetch(`https://preprod.api.ada-anvil.app/v2/services/transactions/build`, {
  method: "POST",
  body: JSON.stringify(data),
  headers: {
    "Content-Type": "application/json",
    "X-Api-Key": "YOUR_API_KEY"
  }
});
```

This transaction, when signed and submitted, will mint a new asset under the policy ID you generated.

## Additional Native Script Patterns

For more native script patterns including multi-signature policies, threshold requirements, and complex logical combinations, see the [Native Scripts Overview](/guides/nft-and-ft/native-scripts.md#common-native-script-patterns).

## Conclusion

You now have a complete native script that can be used for minting tokens. The script includes both signature requirements and time constraints, providing security and immutability for your token collection.

For security considerations, best practices, and additional script patterns, refer to the [Native Scripts Overview](/guides/nft-and-ft/native-scripts.md).

## Related Resources

* [Native Scripts](/guides/nft-and-ft/native-scripts.md)
* [Minting a CIP-25 NFT](/guides/nft-and-ft/mint-nft-cip-25.md)
* [Minting a CIP-68 NFT](/guides/nft-and-ft/mint-nft-cip-68.md)


---

# 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/native-scripts/create-native-script.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.
