npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@constellation-network/metagraph-sdk

v0.2.0

Published

TypeScript SDK for signing data transactions on Constellation data metagraphs built with metakit

Readme

Constellation Metagraph SDK - TypeScript

TypeScript SDK for signing data and currency transactions on Constellation Network metagraphs built with the metakit framework.

Scope: This SDK supports both data transactions (state updates) and metagraph token transactions (value transfers). This SDK implements the standardized serialization, hashing, and signing routines defined by metakit and may not be compatible with metagraphs using custom serialization.

Installation

npm install @constellation-network/metagraph-sdk

Quick Start

import {
  createSignedObject,
  verify,
  generateKeyPair
} from '@constellation-network/metagraph-sdk';

// Generate a key pair
const keyPair = generateKeyPair();
console.log('Address:', keyPair.address);

// Sign data
const data = { action: 'UPDATE', payload: { key: 'value' } };
const signed = createSignedObject(data, keyPair.privateKey);

// Verify
const result = verify(signed);
console.log('Valid:', result.isValid);

Namespaced Imports

The SDK also provides organized namespaces for cleaner imports:

import { wallet, data, currency, network, jlvm } from '@constellation-network/metagraph-sdk';

// Wallet operations
const kp = wallet.generateKeyPair();

// Data signing
const signed = data.createSignedObject({ action: 'test' }, kp.privateKey);
const result = data.verify(signed);

// Currency transactions (shorter names)
const tx = currency.createTransaction(params, kp.privateKey, lastRef);

// JSON Logic VM
const answer = jlvm.jsonLogic.apply({ '+': [1, 2] }, {});

Features

  • Data Transactions: Sign and verify metagraph state updates for submission to data L1 endpoints
  • Currency Transactions: Create and sign metagraph token transfers (v2 format)
  • Network Operations: Submit transactions and query metagraph nodes via MetagraphClient (supports ML0, CL1, DL1 layers)
  • Multi-signature Support: Add multiple signatures to transactions for multi-party authorization
  • JSON Logic VM: Evaluate JSON Logic expressions compatible with the Scala metakit implementation
  • Cross-language Compatible: Works seamlessly with Python, Rust, Go, and Java implementations

API Reference

Data Transactions

High-Level API

createSignedObject<T>(value, privateKey, options?)

Create a signed object with a single signature. The returned object includes a mode field that enables auto-verification.

// Standard signing
const signed = createSignedObject({ action: 'test' }, privateKey);

// DataUpdate signing (for L1 submission)
const signed = createSignedObject(
  { action: 'test' },
  privateKey,
  { mode: 'dataUpdate' }  // or legacy: { isDataUpdate: true }
);

addSignature<T>(signed, privateKey, options?)

Add an additional signature to an existing signed object. Inherits the signing mode from the existing object.

let signed = createSignedObject(data, party1Key);
signed = addSignature(signed, party2Key);
// signed.proofs.length === 2

batchSign<T>(value, privateKeys, options?)

Create a signed object with multiple signatures at once.

const signed = batchSign(data, [key1, key2, key3]);
// signed.proofs.length === 3

verify<T>(signed, isDataUpdate?)

Verify all signatures on a signed object. When the object has a mode field (set by createSignedObject/addSignature/batchSign), verification automatically uses the correct mode.

const result = verify(signed);
if (result.isValid) {
  console.log('All signatures valid');
} else {
  console.log('Invalid proofs:', result.invalidProofs);
}

Low-Level Primitives

canonicalize<T>(data)

Canonicalize JSON data according to RFC 8785.

const canonical = canonicalize({ b: 2, a: 1 });
// '{"a":1,"b":2}'

toBytes<T>(data, mode?)

Convert data to binary bytes for signing. Accepts SigningMode ('standard' | 'dataUpdate') or boolean.

// Regular encoding
const bytes = toBytes(data);

// DataUpdate encoding (with Constellation prefix)
const updateBytes = toBytes(data, 'dataUpdate');

hash<T>(data) / hashBytes(bytes)

Compute SHA-256 hash.

const hashResult = hash(data);
console.log(hashResult.value);  // 64-char hex
console.log(hashResult.bytes);  // Uint8Array

sign<T>(data, privateKey) / signDataUpdate<T>(data, privateKey)

Sign data and return a proof.

const proof = sign(data, privateKey);
// { id: '...', signature: '...' }

signHash(hashHex, privateKey)

Sign a pre-computed hash.

const hashResult = hash(data);
const signature = signHash(hashResult.value, privateKey);

Wallet Utilities

generateKeyPair()

Generate a new random key pair.

const keyPair = generateKeyPair();
// { privateKey, publicKey, address }

keyPairFromPrivateKey(privateKey)

Derive a key pair from an existing private key.

const keyPair = keyPairFromPrivateKey(existingPrivateKey);

getPublicKeyId(privateKey)

Get the public key ID (128 chars, no 04 prefix) for use in proofs.

const id = getPublicKeyId(privateKey);

Types

type SigningMode = 'standard' | 'dataUpdate';

interface SignatureProof {
  id: string;        // Public key (128 chars)
  signature: string; // DER signature hex
}

interface Signed<T> {
  value: T;
  proofs: SignatureProof[];
  mode?: SigningMode;  // Auto-detected by verify()
}

interface KeyPair {
  privateKey: string;
  publicKey: string;
  address: string;
}

interface Hash {
  value: string;      // 64-char hex
  bytes: Uint8Array;  // 32 bytes
}

interface VerificationResult {
  isValid: boolean;
  validProofs: SignatureProof[];
  invalidProofs: SignatureProof[];
}

interface TransactionReference {
  hash: string;
  ordinal: number;
}

interface CurrencyTransaction {
  value: {
    source: string;        // DAG address
    destination: string;   // DAG address
    amount: number;        // Amount in smallest units (1e-8)
    fee: number;           // Fee in smallest units
    parent: TransactionReference;
    salt: string;
  };
  proofs: SignatureProof[];
}

interface TransferParams {
  destination: string;     // DAG address
  amount: number;          // Amount in token units (e.g., 100.5)
  fee?: number;            // Fee in token units (defaults to 0)
}

interface TransferResult {
  hash: string;            // Hash returned by L1 node
  transaction: CurrencyTransaction;
  reference: TransactionReference;  // For chaining subsequent transfers
}

Currency Transactions

createCurrencyTransaction(params, privateKey, lastRef)

Create a metagraph token transaction.

import { createCurrencyTransaction } from '@constellation-network/metagraph-sdk';

const tx = createCurrencyTransaction(
  {
    destination: 'DAG...recipient',
    amount: 100.5,  // 100.5 tokens
    fee: 0,
  },
  privateKey,
  { hash: 'abc123...', ordinal: 5 }  // Last transaction reference
);

createCurrencyTransactionBatch(transfers, privateKey, lastRef)

Create multiple token transactions in a batch.

const transfers = [
  { destination: 'DAG...1', amount: 10 },
  { destination: 'DAG...2', amount: 20 },
  { destination: 'DAG...3', amount: 30 },
];

const txns = createCurrencyTransactionBatch(
  transfers,
  privateKey,
  { hash: 'abc123...', ordinal: 5 }
);

signCurrencyTransaction(transaction, privateKey)

Add an additional signature to a currency transaction (for multi-sig).

let tx = createCurrencyTransaction(params, key1, lastRef);
tx = signCurrencyTransaction(tx, key2);
// tx.proofs.length === 2

verifyCurrencyTransaction(transaction)

Verify all signatures on a currency transaction.

const result = verifyCurrencyTransaction(tx);
console.log('Valid:', result.isValid);

hashCurrencyTransaction(transaction)

Hash a currency transaction.

const hash = hashCurrencyTransaction(tx);
console.log('Hash:', hash.value);

getTransactionReference(transaction, ordinal)

Get a transaction reference for chaining transactions.

const ref = getTransactionReference(tx, 6);
// Use ref as lastRef for next transaction

Utility Functions

// Validate DAG address
isValidDagAddress('DAG...');  // true/false

// Convert between token units and smallest units
tokenToUnits(100.5);    // 10050000000
unitsToToken(10050000000);  // 100.5

// Token decimals constant
TOKEN_DECIMALS;  // 1e-8

Network Operations

The SDK provides a unified MetagraphClient that targets any metagraph layer — Currency L1 (CL1), Data L1 (DL1), or Metagraph L0 (ML0). Available methods are guarded by layer type at runtime.

import { MetagraphClient, createMetagraphClient } from '@constellation-network/metagraph-sdk/network';

// Currency L1 — token transfers
const cl1 = createMetagraphClient('http://localhost:9300', 'cl1');

// Data L1 — metagraph state updates
const dl1 = createMetagraphClient('http://localhost:9400', 'dl1');

// Metagraph L0 — cluster operations
const ml0 = createMetagraphClient('http://localhost:9200', 'ml0');

Currency Operations (CL1)

High-level transfer API:

// Single transfer — fetches last ref, signs, and submits automatically
const result = await cl1.transfer(
  { destination: 'DAG...recipient', amount: 100.5 },
  privateKey
);
console.log('Submitted:', result.hash);

// Chain another transfer using the returned reference
const result2 = await cl1.transfer(
  { destination: 'DAG...other', amount: 50 },
  privateKey,
  { lastRef: result.reference }
);

// Batch transfers — auto-chained sequentially
const results = await cl1.transferBatch(
  [
    { destination: 'DAG...1', amount: 10 },
    { destination: 'DAG...2', amount: 20 },
  ],
  privateKey
);

Low-level methods:

// Get last transaction reference for an address
const lastRef = await cl1.getLastReference('DAG...');

// Submit a signed transaction
const result = await cl1.postTransaction(signedTx);
console.log('Transaction hash:', result.hash);

// Check pending transaction status
const pending = await cl1.getPendingTransaction(result.hash);
if (pending) {
  console.log('Status:', pending.status);  // 'Waiting' | 'InProgress' | 'Accepted'
}

Data Operations (DL1)

// Estimate fee for data submission
const feeInfo = await dl1.estimateFee(signedData);
console.log('Fee:', feeInfo.fee, 'Address:', feeInfo.address);

// Submit signed data
const result = await dl1.postData(signedData);
console.log('Data hash:', result.hash);

Common Operations (All Layers)

// Check node health
const isHealthy = await cl1.checkHealth();

// Get cluster information
const info = await ml0.getClusterInfo();

Network Types

type LayerType = 'ml0' | 'cl1' | 'dl1';

interface MetagraphClientConfig {
  baseUrl: string;    // Node URL
  layer: LayerType;   // Target layer
  timeout?: number;   // Request timeout in ms (default: 30000)
}

interface PostTransactionResponse {
  hash: string;
}

interface PendingTransaction {
  hash: string;
  status: 'Waiting' | 'InProgress' | 'Accepted';
  transaction: CurrencyTransaction;
}

interface EstimateFeeResponse {
  fee: number;
  address: string;
}

interface PostDataResponse {
  hash: string;
}

class NetworkError extends Error {
  statusCode?: number;
  response?: string;
}

Usage Examples

Data Transactions

Submit DataUpdate to L1

import { createSignedObject } from '@constellation-network/metagraph-sdk';
import { createMetagraphClient } from '@constellation-network/metagraph-sdk/network';

// Your metagraph data update
const dataUpdate = {
  action: 'TRANSFER',
  from: 'address1',
  to: 'address2',
  amount: 100
};

// Sign as DataUpdate
const signed = createSignedObject(dataUpdate, privateKey, {
  mode: 'dataUpdate'
});

// Submit to data-l1 using the client
const dl1 = createMetagraphClient('http://l1-node:9300', 'dl1');
const result = await dl1.postData(signed);
console.log('Submitted with hash:', result.hash);

Multi-Signature Workflow

import { createSignedObject, addSignature, verify } from '@constellation-network/metagraph-sdk';

// Party 1 creates and signs
let signed = createSignedObject(data, party1Key);

// Party 2 adds signature
signed = addSignature(signed, party2Key);

// Party 3 adds signature
signed = addSignature(signed, party3Key);

// Verify all signatures — mode auto-detected
const result = verify(signed);
console.log(`${result.validProofs.length} valid signatures`);

Currency Transactions

High-Level Transfer

import { generateKeyPair } from '@constellation-network/metagraph-sdk';
import { createMetagraphClient } from '@constellation-network/metagraph-sdk/network';

const cl1 = createMetagraphClient('http://localhost:9300', 'cl1');
const sender = generateKeyPair();

// One-line transfer
const result = await cl1.transfer(
  { destination: 'DAG...recipient', amount: 100.5 },
  sender.privateKey
);
console.log('Transaction hash:', result.hash);

Low-Level Transaction Creation

import {
  generateKeyPair,
  createCurrencyTransaction,
  verifyCurrencyTransaction,
} from '@constellation-network/metagraph-sdk';
import { createMetagraphClient } from '@constellation-network/metagraph-sdk/network';

// Set up CL1 client
const cl1 = createMetagraphClient('http://localhost:9300', 'cl1');

// Generate keys
const senderKey = generateKeyPair();
const recipientKey = generateKeyPair();

// Get last transaction reference from the network
const lastRef = await cl1.getLastReference(senderKey.address);

// Create transaction
const tx = createCurrencyTransaction(
  {
    destination: recipientKey.address,
    amount: 100.5,  // 100.5 tokens
    fee: 0,
  },
  senderKey.privateKey,
  lastRef
);

// Verify locally before submitting
const result = verifyCurrencyTransaction(tx);
console.log('Transaction valid:', result.isValid);

// Submit to network
const response = await cl1.postTransaction(tx);
console.log('Transaction hash:', response.hash);

// Poll for status
const pending = await cl1.getPendingTransaction(response.hash);
console.log('Status:', pending?.status);

Batch Token Transactions

import { createCurrencyTransactionBatch } from '@constellation-network/metagraph-sdk';

const lastRef = { hash: 'abc123...', ordinal: 10 };

const transfers = [
  { destination: 'DAG...1', amount: 10, fee: 0 },
  { destination: 'DAG...2', amount: 20, fee: 0 },
  { destination: 'DAG...3', amount: 30, fee: 0 },
];

// Create batch (transactions are automatically chained)
const txns = createCurrencyTransactionBatch(
  transfers,
  privateKey,
  lastRef
);

console.log(`Created ${txns.length} transactions`);

Multi-Signature Token Transaction

import {
  createCurrencyTransaction,
  signCurrencyTransaction,
  verifyCurrencyTransaction,
} from '@constellation-network/metagraph-sdk';

// Create transaction with first signature
let tx = createCurrencyTransaction(
  { destination: 'DAG...', amount: 1000, fee: 0 },
  party1PrivateKey,
  lastRef
);

// Add second signature
tx = signCurrencyTransaction(tx, party2PrivateKey);

// Add third signature
tx = signCurrencyTransaction(tx, party3PrivateKey);

// Verify all signatures
const result = verifyCurrencyTransaction(tx);
console.log(`${result.validProofs.length} valid signatures`);

Development

# Install dependencies
npm install

# Run tests
npm test

# Build
npm run build

License

Apache-2.0