Acme.Net.Sdk 1.0.0

dotnet add package Acme.Net.Sdk --version 1.0.0
                    
NuGet\Install-Package Acme.Net.Sdk -Version 1.0.0
                    
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="Acme.Net.Sdk" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Acme.Net.Sdk" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Acme.Net.Sdk" />
                    
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 Acme.Net.Sdk --version 1.0.0
                    
#r "nuget: Acme.Net.Sdk, 1.0.0"
                    
#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 Acme.Net.Sdk@1.0.0
                    
#: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=Acme.Net.Sdk&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Acme.Net.Sdk&version=1.0.0
                    
Install as a Cake Tool

OpenDLT Accumulate C# SDK

Production-ready .NET SDK for the Accumulate blockchain protocol. Supports V2 and V3 JSON-RPC APIs, Ed25519 signing, automatic signer version tracking via SmartSigner, and a complete set of transaction builders for all account and token operations.

Features

  • Smart Signing: Automatic signer version tracking with SmartSigner
  • Complete Protocol Coverage: All transaction types including identity, token, data, and key management operations
  • Dual API Support: Both V2 and V3 JSON-RPC endpoints through a unified Accumulate client
  • Transaction Builders: Static TxBody factory methods for all transaction types
  • Key Management: KeyManager for querying key page state and managing multi-sig configurations
  • Helper Utilities: AccumulateHelper for balance polling, oracle queries, and credit math
  • Canonical JSON: Deterministic JSON serialization for protocol compatibility
  • Network Ready: Mainnet, Testnet (Kermit), and local DevNet support
  • Cross-Platform: Runs on any platform supporting .NET 9.0

Requirements

Installation

Clone the repository and build:

git clone --recursive https://gitlab.com/accumulatenetwork/sdk/acme.net.git
cd acme.net
dotnet build src/Acme.Net.Sdk/Acme.Net.Sdk.csproj

To reference from your own project:

dotnet add reference path/to/src/Acme.Net.Sdk/Acme.Net.Sdk.csproj

Submodule Setup

Test vectors are stored in a git submodule. If you cloned without --recursive:

git submodule add https://gitlab.com/accumulatenetwork/sdk/test-data.git test/vectors
git submodule update --init --recursive

Quick Start

using Acme.Net.Sdk;
using Acme.Net.Sdk.Protocol;
using Acme.Net.Sdk.Protocol.Generated;
using Acme.Net.Sdk.Signing;

// Connect to Kermit testnet
using var client = new Accumulate("https://kermit.accumulatenetwork.io");

// Generate key pair and derive lite account URLs
var kp = AccKeyPairGenerator.GenerateSignatureKeyPair(SignatureType.ED25519);
var lid = Principal.ComputeUrl(kp.GetPublicKey());
var lta = Principal.ComputeUrl(kp.GetPublicKey(), new Url("acc://ACME"));

Console.WriteLine($"Lite Identity: {lid}");
Console.WriteLine($"Lite Token Account: {lta}");

// Query account
var account = await client.V3.QueryAccountAsync(lta.String());

Smart Signing API

The SmartSigner class handles signer version tracking, transaction hashing, signing, submission, and delivery polling in a single call:

using Acme.Net.Sdk;
using Acme.Net.Sdk.Protocol;
using Acme.Net.Sdk.Protocol.Generated;
using Acme.Net.Sdk.Signing;
using Acme.Net.Sdk.Transactions;

// Connect to testnet
using var client = new Accumulate("https://kermit.accumulatenetwork.io");

var kp = AccKeyPairGenerator.GenerateSignatureKeyPair(SignatureType.ED25519);
var lid = Principal.ComputeUrl(kp.GetPublicKey());
var lta = Principal.ComputeUrl(kp.GetPublicKey(), new Url("acc://ACME"));

// Create SmartSigner - automatically queries and tracks signer version
var signer = new SmartSigner(client.V3, kp, lid.String());

// Sign, submit, and wait for delivery in one call
var result = await signer.SignSubmitAndWaitAsync(
    principal: lta.String(),
    body: TxBody.SendTokensSingle(
        toUrl: "acc://recipient.acme/tokens",
        amount: "100000000"  // 1 ACME
    ),
    memo: "Payment"
);

if (result.Success)
    Console.WriteLine($"Transaction delivered: {result.TxId}");

SmartSigner Methods

Method Description
SignAsync Sign a transaction and return the envelope without submitting
SignAndSubmitAsync Sign and submit, return the raw response
SignSubmitAndWaitAsync Sign, submit, and poll until delivered or timeout
AddKeyAsync Add a key to the signer's key page
SetThresholdAsync Set the multi-sig threshold on the signer's key page
GetSignerVersionAsync Query and cache the signer version
InvalidateCache Clear cached version and credit balance

Transaction Builders

Build transaction bodies using the static TxBody factory class. Each method returns a Dictionary<string, object?> matching the Accumulate JSON wire format:

using Acme.Net.Sdk.Transactions;

// Send tokens
TxBody.SendTokensSingle("acc://recipient/tokens", "100000000");

// Send to multiple recipients
TxBody.SendTokens(new List<TxRecipient>
{
    new("acc://alice/tokens", "50000000"),
    new("acc://bob/tokens", "50000000"),
});

// Add credits (requires oracle price)
TxBody.AddCredits("acc://my-identity", creditAmount.ToString(), oracle);

// Create ADI
TxBody.CreateIdentity("acc://my-adi.acme", "acc://my-adi.acme/book", publicKeyHashHex);

// Create token account
TxBody.CreateTokenAccount("acc://my-adi.acme/tokens", "acc://ACME");

// Create custom token
TxBody.CreateToken("acc://my-adi.acme/mytoken", "MTK", precision: 8,
    supplyLimit: "100000000000000");

// Issue tokens (from token issuer)
TxBody.IssueTokens("acc://my-adi.acme/token-acct", "50000000000");

// Burn tokens
TxBody.BurnTokens("1000000");

// Create data account
TxBody.CreateDataAccount("acc://my-adi.acme/data");

// Write data (hex-encoded entries)
TxBody.WriteData(new List<string> { dataHex });

// Write data to a specific account
TxBody.WriteDataTo("acc://recipient.acme/data", new List<string> { dataHex });

// Key page operations
TxBody.UpdateKeyPage(new List<Dictionary<string, object?>>
{
    TxBody.AddKeyOperation(keyHashHex),
    TxBody.SetThresholdOperation(2),
});

// Create key book and key page
TxBody.CreateKeyBook("acc://my-adi.acme/book2", publicKeyHashHex);
TxBody.CreateKeyPage(new List<KeySpecParams> { new(keyHashHex) });

// Account auth
TxBody.UpdateAccountAuth(operations);
TxBody.LockAccount(height: 100);

// Faucet
TxBody.AcmeFaucet("acc://lite-token-account/acme");

Helper Utilities

The AccumulateHelper class provides mid-level convenience methods:

using Acme.Net.Sdk.Helpers;

var helper = new AccumulateHelper(client);

// Poll until balance appears (with timeout)
long balance = await helper.PollForBalanceAsync(ltaUrl, timeout: TimeSpan.FromSeconds(60));

// Query balance and credits
long bal = await helper.GetBalanceAsync("acc://my-adi.acme/tokens");
long credits = await helper.GetCreditsAsync("acc://my-adi.acme/book/1");

// Get oracle price and compute credit costs
int oracle = await helper.GetOracleAsync();
long acmeAmount = AccumulateHelper.CreditsToAcme(10000, oracle);

// Wait for a transaction to be delivered
var txResult = await helper.WaitForTxAsync(txId, timeout: TimeSpan.FromSeconds(30));

Key Management

The KeyManager class queries key page state:

using Acme.Net.Sdk.Signing;

var keyManager = new KeyManager(client.V3, "acc://my-adi.acme/book/1");

var state = await keyManager.GetKeyPageStateAsync();
Console.WriteLine($"Version: {state.Version}");
Console.WriteLine($"Threshold: {state.AcceptThreshold}");
Console.WriteLine($"Keys: {state.Keys.Count}");
Console.WriteLine($"Credits: {state.CreditBalance}");

foreach (var key in state.Keys)
    Console.WriteLine($"  Key Hash: {key.KeyHash}");

Add keys and set thresholds via SmartSigner:

var adiSigner = new SmartSigner(client.V3, adiKeyPair, keyPageUrl);

// Add a new key
var keyHash = SHA256.HashData(newKeyPair.GetPublicKey());
await adiSigner.AddKeyAsync(keyHash);

// Set 2-of-3 multi-sig threshold
await adiSigner.SetThresholdAsync(2);

Network Endpoints

using Acme.Net.Sdk;

// Public networks
using var mainnet = new Accumulate("https://mainnet.accumulatenetwork.io");
using var testnet = new Accumulate("https://kermit.accumulatenetwork.io");

// Local development
using var devnet = Accumulate.Devnet();  // http://localhost:26660

// Custom host and port
using var local = Accumulate.Local(port: 26660);

The unified Accumulate client exposes both API versions:

client.V2  // AccumulateV2Client - legacy JSON-RPC (faucet, execute, query)
client.V3  // AccumulateV3Client - current JSON-RPC (submit, query, node-info)

Supported Signature Types

Type Enum Value Wire Name Status
Ed25519 ED25519 = 2 ed25519 Full signing support
Legacy Ed25519 LEGACY_ED25519 = 1 legacyED25519 Protocol defined
RCD1 RCD1 = 3 rcd1 Protocol defined
BTC BTC = 4 btc Protocol defined
BTC Legacy BTC_LEGACY = 5 btcLegacy Protocol defined
ETH ETH = 6 eth Protocol defined
Delegated DELEGATED = 7 delegated Protocol defined
RSA-SHA256 RSA_SHA256 = 9 rsaSha256 Protocol defined
ECDSA-SHA256 ECDSA_SHA256 = 10 ecdsaSha256 Protocol defined

Examples

Complete working examples are provided in examples/v3/. All examples run real on-chain operations against the Kermit testnet:

Example Description
Example01_LiteIdentities Lite identity creation, faucet funding, credits, lite-to-lite token transfer
Example02_AccumulateIdentities ADI creation via SmartSigner
Example03_AdiTokenAccounts ADI token account creation and token transfers
Example04_DataAccountsEntries Data account creation, writing and querying data entries
Example05_AdiToAdiTransfer Full ADI-to-ADI token transfer workflow
Example06_CustomTokens Custom token issuer creation, token issuance, and custom token transfers
Example08_QueryTxSignatures V3 query APIs: accounts, chains, pending transactions
Example09_KeyManagement Key export/import, adding keys to key pages, multi-sig thresholds
Example10_UpdateKeyPageThreshold Adding multiple keys and setting 2-of-3 threshold
Example11_MultiSignatureTypes Signature type enumeration and wire name lookups
Example12_QuickstartDemo Wallet creation, faucet, canonical JSON, network endpoints
Example13_AdiToAdiTransferWithHeaderOptions ADI-to-ADI transfer with memo in transaction header

Run any example:

dotnet run --project examples/v3/Example01_LiteIdentities/Example01_LiteIdentities.csproj

Project Structure

src/Acme.Net.Sdk/
├── Accumulate.cs              # Unified client entry point (V2 + V3)
├── Api/                       # API client implementations
│   └── V2/                    # V2 response models
├── Codec/
│   └── TransactionCodec.cs    # Binary TLV encoding and transaction hashing
├── Core/
│   └── NetworkEndpoint.cs     # Network endpoint configuration
├── Exceptions/                # AccumulateException hierarchy
├── Helpers/
│   ├── AccumulateHelper.cs    # Balance polling, oracle queries, credit math
│   └── QuickStart.cs          # Rapid development helper
├── Protocol/
│   ├── Principal.cs           # Lite identity/token URL derivation
│   ├── SignatureType.cs       # Signature type enum (17 types)
│   ├── TransactionTypeCode.cs # Transaction type codes (33 types)
│   ├── Url.cs                 # Accumulate URL handling
│   ├── VoteType.cs            # Vote type enum
│   ├── Generated/             # Generated protocol classes
│   │   └── Protocol/          # Transaction body types (23 types)
│   └── Signing/               # Low-level transaction signing
├── Rpc/
│   ├── AsyncRPCClient.cs      # Async JSON-RPC transport
│   ├── RPCClient.cs           # Sync JSON-RPC transport
│   └── Models/                # RPC request/response models
├── Signing/
│   ├── AccKeyPairGenerator.cs # Ed25519 key pair generation
│   ├── SignatureKeyPair.cs    # Key pair management
│   ├── SmartSigner.cs         # Auto-version signer with submit+wait
│   ├── KeyManager.cs          # Key page state queries
│   └── Signer.cs              # Low-level signing operations
├── Support/
│   ├── CanonicalJson.cs       # Deterministic JSON serialization
│   ├── Marshaller.cs          # Binary TLV field encoding
│   └── HashUtils.cs           # SHA-256 and Merkle tree utilities
├── Transactions/
│   ├── TxBody.cs              # Static transaction body factory (all types)
│   ├── BuildContext.cs        # Transaction header metadata
│   └── *Builder.cs            # Typed transaction builders
├── V2/
│   └── AccumulateV2Client.cs  # V2 JSON-RPC client
├── V3/
│   └── AccumulateV3Client.cs  # V3 JSON-RPC client
└── Wallet/
    ├── Wallet.cs              # Wallet management with encryption
    └── FileSystemWalletStorage.cs

examples/v3/                   # 12 complete working examples
test/
├── Acme.Net.Sdk.Tests/        # Unit and integration tests
└── vectors/                   # Protocol test vectors (git submodule)

Building

# Build the SDK
dotnet build src/Acme.Net.Sdk/Acme.Net.Sdk.csproj

# Build and run an example
dotnet run --project examples/v3/Example01_LiteIdentities/Example01_LiteIdentities.csproj

Running Tests

# Run all tests
dotnet test

# Run test vector verification only
dotnet test --filter FullyQualifiedName~TransactionHasherVectorTests

Test vectors are sourced from the shared test-data repository and verify transaction hashing compatibility with the reference Go implementation.

Dependencies

Package Version Purpose
Newtonsoft.Json 13.0.3 JSON serialization
NSec.Cryptography 24.4.0 Ed25519 signing and key derivation

Error Handling

using Acme.Net.Sdk.Exceptions;
using Acme.Net.Sdk.Signing;

try
{
    var result = await signer.SignSubmitAndWaitAsync(principal, body);
    if (!result.Success)
        Console.WriteLine($"Transaction failed: {result.Error}");
}
catch (AccumulateException ex)
{
    Console.WriteLine($"SDK error: {ex.Message}");
}
catch (Acme.Net.Sdk.Rpc.RPCException ex)
{
    Console.WriteLine($"RPC error: {ex.Message}");
}

The TransactionResult returned by SignSubmitAndWaitAsync contains:

Property Type Description
Success bool Whether the transaction was delivered successfully
TxId string? The transaction ID (acc://... URL)
Error string? Error message if the transaction failed
Response JsonElement? Raw JSON response from the server

License

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

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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.0.0 32 2/27/2026