Evolution SDK
Encoding

Plutus Types

Pre-built type-safe schemas for common Cardano data structures

Plutus Types

Pre-built, battle-tested schemas for core Cardano data structures: credentials, addresses, values, output references, and CIP-68 metadata.

These types are exported from @evolution-sdk/evolution/core/plutus and match the on-chain Plutus specification exactly—use them to eliminate encoding errors and ensure validator compatibility.

Available Types

TypeUse CaseImport
CredentialReference wallets or scriptsimport { Credential } from "@evolution-sdk/evolution/core/plutus"
AddressPayment destinations with optional stakingimport { Address } from "@evolution-sdk/evolution/core/plutus"
ValueADA and native token quantitiesimport { Value } from "@evolution-sdk/evolution/core/plutus"
OutputReferenceIdentify specific UTxOsimport { OutputReference } from "@evolution-sdk/evolution/core/plutus"
CIP68MetadataNFT/FT metadata following CIP-68import { CIP68Metadata } from "@evolution-sdk/evolution/core/plutus"

Quick Start

import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

// Use pre-built Credential type
const : . = {
  : {
    : ..("abc123def456abc123def456abc123def456abc123def456abc123de")
  }
}

// Encode to CBOR
const  = ..()

Working with Codecs

All types provide codec methods for encoding and decoding. Choose based on your needs:

Note: Credential exports CredentialCodec (along with related codecs like PaymentCredentialCodec), while other types export just Codec. All provide the same encoding/decoding methods.

When building transactions: Use toCBORBytes() for binary data When storing/transmitting: Use toCBORHex() for hex strings
When debugging: Use toData() to inspect PlutusData structure When decoding: Use fromCBORHex() or fromCBORBytes() with matching format

import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

const : . = {
  : {
    : {
      : ..("abc123def456abc123def456abc123def456abc123def456abc123de")
    }
  },
  : 
}

// Encode to hex (for APIs, storage)
const  = ..()

// Encode to bytes (for transactions)
const  = ..()

// Decode from hex
const  = ..()

// Inspect as PlutusData (debugging)
const  = ..()

Credential

Represents ownership—either a verification key (wallet) or script (smart contract).

When to use: Reference who can spend funds or participate in staking. Required in addresses, multi-sig validators, and authorization checks.

import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

// Wallet credential
const : . = {
  : {
    : ..("abc123def456abc123def456abc123def456abc123def456abc123de")
  }
}

// Smart contract credential
const : . = {
  : {
    : ..("def456abc123def456abc123def456abc123def456abc123def456ab")
  }
}

Address

Cardano address with payment credential and optional stake credential.

When to use: Specify transaction outputs, script addresses, or beneficiaries in datums.

import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

// Base address (with staking)
const : . = {
  : {
    : {
      : ..("abc123def456abc123def456abc123def456abc123def456abc123de")
    }
  },
  : {
    : {
      : {
        : {
          : ..("def456abc123def456abc123def456abc123def456abc123def456ab")
        }
      }
    }
  }
}

Address Variants

import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

// Enterprise address (no staking)
const : . = {
  : {
    : {
      : ..("123456789abc123456789abc123456789abc123456789abc12345678")
    }
  },
  : 
}

// Pointer address (stake reference)
const : . = {
  : {
    : {
      : ..("abc123def456abc123def456abc123def456abc123def456abc123de")
    }
  },
  : {
    : {
      : 12345678n,
      : 2n,
      : 0n
    }
  }
}

Value

Multi-asset value representing ADA and native tokens as nested maps.

When to use: Transaction outputs, locked funds in datums, token quantities in minting/burning.

import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

// ADA only
const : . = new ([
  [new (), new ([
    [new (), 5000000n] // 5 ADA in lovelace
  ])]
])

// Multi-asset value (ADA + tokens)
const  = ..("a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8")

const : . = new ([
  // ADA (empty policyId/assetName)
  [new (), new ([
    [new (), 2000000n]
  ])],
  // Custom tokens
  [, new ([
    [..("MyToken"), 100n],
    [..("MyNFT"), 1n]
  ])]
])

OutputReference

Uniquely identifies a UTxO by transaction hash and output index.

When to use: Lock specific UTxOs in datums (escrow), prevent double-spending, reference the "original" UTxO in state updates.

import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

const : . = {
  : ..(
    "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
  ),
  : 0n
}

CIP68Metadata

Reference token metadata following CIP-68 standard with versioning and extensibility.

When to use: Minting NFTs or fungible tokens following the CIP-68 standard for on-chain metadata.

CIP-68 Token Labels

LabelTypeDescription
100Reference NFTImmutable metadata, always 1 quantity
222User NFTMutable metadata, user-held token
333Reference FTFungible token metadata
444Reference RFTRich fungible token (advanced features)
import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

// NFT metadata (label 222)
const  = ..([
  [..("name"), ..("SpaceAce #4242")],
  [..("image"), ..("ipfs://QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco")],
  [..("rarity"), ..("legendary")],
  [..("attributes"), ..([
    [..("class"), ..("explorer")],
    [..("power"), 9000n]
  ])]
])

const : . = {
  : ,
  : 1n,
  : []
}

// FT metadata (label 333) with decimals
const  = ..([
  [..("name"), ..("MyToken")],
  [..("ticker"), ..("MTK")],
  [..("decimals"), 6n],
  [..("url"), ..("https://mytoken.io")]
])

const : . = {
  : ,
  : 1n,
  : [
    ..([[..("mutable"), 1n]]) // custom extension
  ]
}

Real-World Examples

Escrow Script Datum

Time-locked escrow that holds funds for a beneficiary until a deadline. The validator checks the deadline has passed and the beneficiary signed before releasing funds.

import { , ,  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

interface EscrowDatum {
  : .
  : bigint
  : .
  : .
}

const : EscrowDatum = {
  : {
    : {
      : {
        : ..("abc123def456abc123def456abc123def456abc123def456abc123de")
      }
    },
    : 
  },
  : 1735689600000n,
  : new ([
    [new (), new ([[new (), 10000000n]])] // 10 ADA
  ]),
  : {
    : ..("a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"),
    : 2n
  }
}

Multi-Sig Validator Redeemer

Threshold signature validator requiring M-of-N signers. The redeemer specifies which credentials must sign and how many signatures are needed (e.g., 2 of 3).

import {  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

interface MultiSigRedeemer {
  : .[]
  : bigint
}

const : MultiSigRedeemer = {
  : [
    {
      : {
        : ..("abc123def456abc123def456abc123def456abc123def456abc123de")
      }
    },
    {
      : {
        : ..("def456abc123def456abc123def456abc123def456abc123def456ab")
      }
    },
    {
      : {
        : ..("123456789abc123456789abc123456789abc123456789abc12345678")
      }
    }
  ],
  : 2n // 2 of 3
}

NFT Minting with CIP-68

Complete CIP-68 NFT mint creating both reference token (label 100, immutable metadata) and user token (label 222, transferable). Reference token stays locked at script address.

import { ,  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

// Metadata for both reference and user tokens
const  = ..([
  [..("name"), ..("CryptoKitty #42")],
  [..("image"), ..("ipfs://Qm...")],
  [..("dna"), ..("0xabc123...")],
  [..("traits"), ..([
    [..("fur"), ..("tabby")],
    [..("eyes"), ..("blue")]
  ])]
])

const : . = {
  ,
  : 1n,
  : []
}

// Mint value: reference (100) + user token (222)
const  = ..("a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8")
const  = ..("CryptoKitty42")

// CIP-68 token name encoding: label prefix + asset name
const  = new ([0x00, 0x0f, 0x42, 0x00]) // (100)
const  = new ([0x00, 0x0f, 0x42, 0x02])      // (222)

const : . = new ([
  [, new ([
    [new ([..., ...]), 1n],
    [new ([..., ...]), 1n]
  ])]
])

DEX Order Datum

Decentralized exchange limit order specifying what assets are offered, what's requested in return, and whether partial fills are allowed. Owner can cancel anytime.

import { ,  } from "@evolution-sdk/evolution/core/plutus"
import {  } from "@evolution-sdk/evolution"

interface DexOrderDatum {
  : .
  : .
  : .
  : boolean
}

const : DexOrderDatum = {
  : {
    : {
      : ..("abc123def456abc123def456abc123def456abc123def456abc123de")
    }
  },
  : new ([
    [new (), new ([[new (), 100000000n]])] // 100 ADA
  ]),
  : new ([
    [..("token_policy_id_28_bytes_hex_encoded_here_abcd"), new ([
      [..("USDC"), 10000000n] // 10 USDC (6 decimals)
    ])]
  ]),
  : true
}

Best Practices

Use as building blocks: Import and compose these types—don't recreate Credential or Address types yourself. They match Plutus exactly.

Match validator types: Your smart contract must expect these exact structures. Field names and order matter for CBOR encoding.

Test with real data: Verify encoding/decoding with actual blockchain data to catch edge cases before deployment.

Leverage type safety: Let TypeScript catch errors at compile time. If it type-checks with these types, CBOR encoding will be correct.

Next Steps