Chrysalis.Tx 1.3.0-alpha

This is a prerelease version of Chrysalis.Tx.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Chrysalis.Tx --version 1.3.0-alpha
                    
NuGet\Install-Package Chrysalis.Tx -Version 1.3.0-alpha
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Chrysalis.Tx" Version="1.3.0-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Chrysalis.Tx" Version="1.3.0-alpha" />
                    
Directory.Packages.props
<PackageReference Include="Chrysalis.Tx" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Chrysalis.Tx --version 1.3.0-alpha
                    
#r "nuget: Chrysalis.Tx, 1.3.0-alpha"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Chrysalis.Tx@1.3.0-alpha
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Chrysalis.Tx&version=1.3.0-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Chrysalis.Tx&version=1.3.0-alpha&prerelease
                    
Install as a Cake Tool

<div align="center"> <img src="assets/banner.png" alt="Chrysalis Banner" width="100%">

<a href="https://www.nuget.org/packages/Chrysalis"> <img src="https://img.shields.io/nuget/v/Chrysalis.svg?style=flat-square" alt="NuGet"> </a> <a href="https://github.com/SAIB-Inc/Chrysalis/blob/main/LICENSE.md"> <img src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" alt="License"> </a> <a href="https://github.com/SAIB-Inc/Chrysalis/fork"> <img src="https://img.shields.io/github/forks/SAIB-Inc/Chrysalis.svg?style=flat-square" alt="Forks"> </a> <a href="https://github.com/SAIB-Inc/Chrysalis/stargazers"> <img src="https://img.shields.io/github/stars/SAIB-Inc/Chrysalis.svg?style=flat-square" alt="Stars"> </a> <a href="https://github.com/SAIB-Inc/Chrysalis/graphs/contributors"> <img src="https://img.shields.io/github/contributors/SAIB-Inc/Chrysalis.svg?style=flat-square" alt="Contributors"> </a> <br> <a href="https://dotnet.microsoft.com/download"> <img src="https://img.shields.io/badge/.NET-10.0-512BD4?style=flat-square" alt=".NET"> </a> <a href="https://cardano.org/"> <img src="https://img.shields.io/badge/Cardano-Compatible-0033AD?style=flat-square" alt="Cardano"> </a> </div>

📖 Overview

Chrysalis is a native .NET toolkit for Cardano blockchain development, providing everything needed to build applications on Cardano. From CBOR serialization to transaction building and smart contract interaction, Chrysalis offers a complete solution for .NET developers.

Key Components:

  • 📦 Serialization - Efficient CBOR encoding/decoding for Cardano data structures
  • 🔄 Node Communication - Direct interaction with Cardano nodes through Ouroboros mini-protocols
  • 🔑 Wallet Management - Address generation and key handling
  • 💳 Transaction Building - Simple and advanced transaction construction
  • 📜 Smart Contract Integration - Pure managed Plutus VM with CEK machine for script evaluation
  • 🧠 Plutus VM - Full UPLC interpreter in C# — no native dependencies, no FFI

✨ Features

  • 🔐 Type-Safe Data Models - Strong typing for all Cardano blockchain structures
  • High Performance - Optimized for speed and efficiency
  • 🧩 Modular Architecture - Use only what you need
  • 🚀 Modern C# API - Takes advantage of the latest .NET features
  • 🔗 Complete Cardano Support - Works with all major Cardano eras and protocols

📥 Installation

# Install the main package
dotnet add package Chrysalis

Or install individual components:

dotnet add package Chrysalis.Cbor
dotnet add package Chrysalis.Network
dotnet add package Chrysalis.Tx
dotnet add package Chrysalis.Plutus
dotnet add package Chrysalis.Wallet

🧩 Architecture

Chrysalis consists of several specialized libraries:

Module Description
Chrysalis.Cbor CBOR serialization for Cardano data structures
Chrysalis.Cbor.CodeGen Source generation for optimized serialization code
Chrysalis.Network Implementation of Ouroboros mini-protocols
Chrysalis.Tx Transaction building and submission
Chrysalis.Plutus Pure managed UPLC/CEK machine for Plutus scripts
Chrysalis.Wallet Key management and address handling

💻 Usage Examples

📦 CBOR Serialization

Define and use CBOR-serializable types with attribute-based serialization:

// Define CBOR-serializable types
[CborSerializable]
[CborConstr(0)]
public partial record AssetDetails(
    [CborOrder(0)] byte[] PolicyId,
    [CborOrder(1)] AssetClass Asset,
    [CborOrder(2)] ulong Amount
): CborBase;

[CborSerializable]
[CborList]
public partial record AssetClass(
    [CborOrder(0)] byte[] PolicyId,
    [CborOrder(1)] byte[] AssetName
) : CborBase;

// Deserialize from CBOR hex
var data = "d8799f581cc05cb5c5f43aac9d9e057286e094f60d09ae61e8962ad5c42196180c9f4040ff1a00989680ff";
AssetDetails details = CborSerializer.Deserialize<AssetDetails>(data);

// Serialize back to CBOR
byte[] serialized = CborSerializer.Serialize(details);
Extension Method Pattern

Chrysalis uses extension methods extensively to provide clean access to nested data structures:

// Without extensions, deep property access is verbose and differs by era
var hash = transaction.TransactionBody.Inputs.GetValue()[0].TransactionId;

// With extension methods, access is simplified and era-agnostic
var hash = transaction.TransactionBody.Inputs().First().TransactionId();

// Extensions support common operations
Transaction signedTx = transaction.Sign(privateKey);

🔑 Wallet Management

Generate and manage addresses and keys:

// Create wallet from mnemonic
var mnemonic = Mnemonic.Generate(English.Words, 24);

var accountKey = mnemonic
            .GetRootKey()
            .Derive(PurposeType.Shelley, DerivationType.HARD)
            .Derive(CoinType.Ada, DerivationType.HARD)
            .Derive(0, DerivationType.HARD);

var privateKey = accountKey
            .Derive(RoleType.ExternalChain)
            .Derive(0);

var paymentKey = privateKey.GetPublicKey();

var stakingKey = accountKey
            .Derive(RoleType.Staking)
            .Derive(0)
            .GetPublicKey();

// Generate address
var address = Address.FromPublicKeys(
    NetworkType.Testnet,
    AddressType.BasePayment,
    paymentKey,
    stakingKey
);

string bech32Address = address.ToBech32();

Console.WriteLine($"Bech32 Address: {bech32Address}");

🔄 Node Communication

Connect directly to a Cardano node:

try {
    // Connect to a local node
    NodeClient client = await NodeClient.ConnectAsync("/ipc/node.socket");
    await client.StartAsync(2);

    // Query UTXOs by address
    var addressBytes = Convert.FromHexString("00a7e1d2e57b1f9aa851b08c8934a315ffd97397fa997bb3851c626d3bb8d804d91fa134757d1a41b0b12762f8922fe4b4c6faa5ffec1bc9cf");
    var utxos = await client.LocalStateQuery.GetUtxosByAddressAsync([addressBytes]);

    // Synchronize with the chain
    var tip = await client.LocalStateQuery.GetTipAsync();
    Console.WriteLine($"Chain tip: {tip}");

    // Available mini-protocols - accessed as properties
    var localTxSubmit = client.LocalTxSubmit;
    var localStateQuery = client.LocalStateQuery;
    var localTxMonitor = client.LocalTxMonitor;
}
catch (InvalidOperationException ex) {
    Console.WriteLine($"Connection failed: {ex.Message}");
}
catch (Exception ex) {
    Console.WriteLine($"Protocol error: {ex.Message}");
}

💳 Transaction Building

Build and sign transactions with the fluent API or template builder:

// Simple transaction using template builder
var senderAddress = address.ToBech32();
var receiverAddress = "addr_test1qpcxqfg6xrzqus5qshxmgaa2pj5yv2h9mzm22hj7jct2ad59q2pfxagx7574360xl47vhw79wxtdtze2z83k5a4xpptsm6dhy7";
var provider = new Blockfrost("apiKeyHere");

var transfer = TransactionTemplateBuilder<ulong>.Create(provider)
    .AddStaticParty("sender", senderAddress, true)
    .AddStaticParty("receiver", receiverAddress)
    .AddInput((options, amount) =>
    {
        options.From = "sender";
    })
    .AddOutput((options, amount) =>
    {
        options.To = "receiver";
        options.Amount = new Lovelace(amount);
    })
    .Build();

// Execute the template with a specific amount
Transaction tx = await transfer(5_000_000UL);
Transaction signedTx = tx.Sign(privateKey);

📜 Smart Contract Interaction

Interact with and validate Plutus scripts:

var provider = new Blockfrost("project_id");
var ownerAddress = "your address";
var alwaysTrueValidatorAddress = "your validator address";

var spendRedeemerBuilder = (_, _, _) =>
{
    // Custom Logic and return type as long as it inherits from CborBase
    // ex: returns an empty list
    return new PlutusConstr([]);
};

var lockTxHash = "your locked tx hash";
var scriptRefTxHash = "your script ref tx hash";

var unlockLovelace = TransactionTemplateBuilder<UnlockParameters>.Create(provider)
    .AddStaticParty("owner", ownerAddress, true)
    .AddStaticParty("alwaysTrueValidator", alwaysTrueValidatorAddress)
    .AddReferenceInput((options, unlockParams) =>
    {
        options.From = "alwaysTrueValidator";
        options.UtxoRef = unlockParams.ScriptRefUtxoOutref;
    })
    .AddInput((options, unlockParams) =>
    {
        options.From = "alwaysTrueValidator";
        options.UtxoRef = unlockParams.LockedUtxoOutRef;
        options.SetRedeemerBuilder(spendRedeemerBuilder);
    })
    .Build();


var unlockParams = new(
    new TransactionInput(Convert.FromHexString(lockTxHash), 0),
    new TransactionInput(Convert.FromHexString(scriptRefTxHash), 0)
);

var unlockUnsignedTx = await unlockLovelace(unlockParams);
var unlockSignedTx = unlockUnsignedTx.Sign(privateKey);
var unlockTxHash = await provider.SubmitTransactionAsync(unlockSignedTx);

Console.WriteLine($"Unlock Tx Hash: {unlockTxHash}");
CIP Implementation Support

Chrysalis supports various Cardano Improvement Proposals (CIPs), including:

// CIP-68 NFT standard implementation
var nftMetadata = new Cip68<PlutusData>(
    Metadata: metadata,
    Version: 1,
    Extra: null
);

🧠 Plutus VM — Pure Managed Script Evaluation

Chrysalis includes a complete UPLC (Untyped Plutus Lambda Calculus) interpreter written entirely in C#. No Haskell, no Rust, no native dependencies — just managed .NET code.

Given a transaction and its resolved UTxOs, Chrysalis can evaluate all Plutus scripts and return exact execution units:

// Evaluate all scripts in a transaction — pure managed C#
IReadOnlyList<EvaluationResult> results = ScriptContextBuilder.EvaluateTx(
    body, witnessSet, utxos, SlotNetworkConfig.Mainnet);

foreach (var result in results)
{
    Console.WriteLine($"Tag: {result.RedeemerTag}, Index: {result.Index}");
    Console.WriteLine($"  Memory: {result.ExUnits.Mem}, Steps: {result.ExUnits.Steps}");
}

The evaluation pipeline:

  1. ScriptContext building — Constructs the full Plutus V3 ScriptContext (TxInfo, ScriptPurpose, ScriptInfo) from Codec types, ported from Aiken
  2. Script resolution — Finds scripts from the witness set or UTxO script references
  3. Flat decoding — Decodes the UPLC program from Cardano's flat binary encoding
  4. CEK machine — Executes the program with all 94 Plutus V3 builtins including BLS12-381 cryptographic primitives
  5. ExUnits tracking — Returns precise memory and CPU step consumption

The VM passes 999/999 UPLC conformance tests covering all Plutus versions (V1–V3).

The transaction builder uses this automatically — no external evaluator needed:

var template = TransactionTemplateBuilder<MyParams>.Create(provider)
    .AddInput((options, p) =>
    {
        options.From = "validator";
        options.SetRedeemerBuilder((_, _, _) => new PlutusConstr([]));
    })
    .Build();

// Scripts are evaluated in pure C# during transaction building
Transaction tx = await template(myParams);

⚡ Performance

.NET can compete with Rust and Go. Chrysalis proves it.

Benchmarks compare Chrysalis against Pallas (Rust) and Gouroboros (Go) — the two most established Cardano client libraries in systems languages — on Conway-era blocks against a local Cardano Preview testnet node.

N2N (TCP) — Pipelined Header Sync from origin (apples-to-apples):

blk/s
Chrysalis (.NET) ~40,000
Gouroboros (Go) ~14,500
Pallas (Rust) ~722

Chrysalis is 2.8x faster than Go and 55x faster than Rust on raw pipelined header throughput — same pipeline depth (100), same workload, same node.

N2N (TCP) — Full Block Download + Deserialization from origin:

blk/s Notes
Chrysalis (.NET) ~9,500 Pipelined ChainSync + BlockFetch + full deserialization
Gouroboros (Go) Cannot run concurrent ChainSync + BlockFetch (node queue overflow)
Pallas (Rust) ~722 Sequential (no pipelining)

N2C (Unix Socket) — 10,000 blocks, sequential:

With Deserialization Network Only
Pallas (Rust) 3,097 blk/s 3,280 blk/s
Chrysalis (.NET) 2,747 blk/s 2,977 blk/s
Gouroboros (Go) 2,735 blk/s

N2C is bottlenecked by the node, not the client — all three converge around 2,700–3,300 blk/s. Chrysalis reaches 89% of Rust here.

How:

  • Batch burst pipelining — send N requests, drain N responses, BlockFetch the batch. Eliminates per-block round-trip latency
  • Zero-copy deserializationReadOnlyMemory<byte> throughout the pipeline, no intermediate allocations
  • Source-generated CBOR dispatch — compile-time probe-based union resolution via PeekState/PeekTag instead of try-catch
  • System.IO.Pipelines — backpressure-aware async I/O with minimal buffer copies

Benchmarks run on AMD Ryzen 9 9900X3D, .NET 10. Full results and methodology in benchmarks/BENCHMARKS.md.

🔄 Cardano Era Support

Chrysalis provides comprehensive support for Cardano's evolution:

<table> <thead> <tr> <th>Era</th> <th>Phase</th> <th>Status</th> <th colspan="4">Feature Support</th> </tr> <tr> <th></th> <th></th> <th></th> <th align="center">Serialization</th> <th align="center">Block Processing</th> <th align="center">Transaction Building</th> <th align="center">Script Evaluation</th> </tr> </thead> <tbody> <tr> <td><strong>Byron</strong></td> <td>Foundation</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">❌</td> <td align="center">❌</td> </tr> <tr> <td><strong>Shelley</strong></td> <td>Decentralization</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">❌</td> </tr> <tr> <td><strong>Allegra</strong></td> <td>Token Locking</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">❌</td> </tr> <tr> <td><strong>Mary</strong></td> <td>Multi-Asset</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">❌</td> </tr> <tr> <td><strong>Alonzo</strong></td> <td>Smart Contracts</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> </tr> <tr> <td><strong>Babbage/Vasil</strong></td> <td>Scaling</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> </tr> <tr> <td><strong>Conway</strong></td> <td>Governance</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> <td align="center">✅</td> </tr> </tbody> </table>

Legend:

  • ✅ Fully Supported
  • 🚧 Planned for Future Release
  • ❌ Not Supported Yet

📚 Documentation

For detailed documentation on each component:

Note: The documentation is currently in development. In the meantime, this README and the code examples provide a good starting point.

🤝 Contributing

We welcome contributions! To get started:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'feat: add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

Please make sure to update tests as appropriate.

📄 License

This project is licensed under the MIT License - see the LICENSE.md file for details.


<div align="center"> <p>Made with ❤️ by <a href="https://saib.dev">SAIB Inc</a> for the Cardano community</p> </div>

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.7.10-alpha 104 4/27/2026
1.7.9-alpha 58 4/24/2026
1.7.8-alpha 60 4/8/2026
1.7.7-alpha 60 4/2/2026
1.7.6-alpha 61 4/1/2026
1.7.5-alpha 61 3/31/2026
1.7.4-alpha 57 3/30/2026
1.7.3-alpha 57 3/22/2026
1.7.2-alpha 59 3/19/2026
1.7.1-alpha 56 3/19/2026
1.7.0-alpha 53 3/19/2026
1.6.0-alpha 65 3/18/2026
1.5.0-alpha 62 3/14/2026
1.4.0-alpha 66 3/12/2026
1.3.0-alpha 61 3/11/2026
1.2.3-alpha 59 3/9/2026
1.2.2-alpha 52 3/9/2026