Documentation

TypeScript SDK

The @norn-protocol/sdk package provides wallet primitives, transaction builders, an RPC client, and WebSocket subscription helpers for building TypeScript/JavaScript applications on Norn.

Installation

npm install @norn-protocol/sdk

Or build from source:

cd sdk/typescript
npm install
npm run build

Wallet

The Wallet class manages Ed25519 key pairs.

import { Wallet, addressToHex } from "@norn-protocol/sdk";
 
// Generate a new wallet with a random private key
const wallet = Wallet.generate();
 
// Wallet properties are Uint8Array, not strings
wallet.privateKey; // Uint8Array (32 bytes)
wallet.publicKey;  // Uint8Array (32 bytes)
wallet.address;    // Uint8Array (20 bytes)
 
// Use convenience getters for hex strings
wallet.addressHex;   // "0x..." (20-byte hex with prefix)
wallet.publicKeyHex; // hex string (no prefix)
 
// Or use the utility function
addressToHex(wallet.address); // "0x..."

Creating Wallets

// From a hex-encoded private key (most common)
const wallet = Wallet.fromPrivateKeyHex("abcd1234...");
const wallet2 = Wallet.fromPrivateKeyHex("0xabcd1234..."); // 0x prefix OK
 
// From raw bytes
const keyBytes = new Uint8Array(32);
const wallet3 = Wallet.fromPrivateKey(keyBytes);
 
// Generate a random wallet
const wallet4 = Wallet.generate();

Signing

// Sign a message (returns 64-byte Uint8Array signature)
const signature = wallet.sign(messageBytes);

NornClient

The NornClient class provides RPC methods for reading chain state and submitting transactions.

import { NornClient } from "@norn-protocol/sdk";
 
const client = new NornClient({ url: "https://seed.norn.network" });
 
// With API key for mutation endpoints
const authedClient = new NornClient({
  url: "https://seed.norn.network",
  apiKey: "your-api-key",
  timeout: 15_000, // optional, default 10s
});

Read-Only Methods

// Get native NORN balance (tokenId is 32 zero bytes for native)
const nativeTokenId = "0x" + "00".repeat(32);
const balance = await client.getBalance("0x...", nativeTokenId);
 
// Get block by height
const block = await client.getBlock(42);
 
// Get detailed block transactions (transfers, token ops, names, looms)
const blockTxs = await client.getBlockTransactions(42);
 
// Get latest block
const latest = await client.getLatestBlock();
 
// Get weave state
const state = await client.getWeaveState();
 
// Get thread info and state
const thread = await client.getThread("0x...");
const threadState = await client.getThreadState("0x...");
 
// Resolve a NornName
const resolved = await client.resolveName("alice");
 
// List names owned by an address
const names = await client.listNames("0x...");
 
// Get token info
const token = await client.getTokenBySymbol("MTK");
const tokenById = await client.getTokenInfo("0x...");
 
// List tokens
const tokens = await client.listTokens(10, 0);
 
// Get loom info
const loom = await client.getLoomInfo("0x...");
 
// List looms
const looms = await client.listLooms(10, 0);
 
// Get node health and info
const health = await client.health();
const nodeInfo = await client.getNodeInfo();
 
// Get transaction history for an address
const history = await client.getTransactionHistory("0x...", 20, 0);
 
// Get recent transfers across all addresses
const recent = await client.getRecentTransfers(20, 0);
 
// Get a single transaction by knot ID
const tx = await client.getTransaction("0x...");
 
// Get fee estimate
const fees = await client.getFeeEstimate();
 
// Get validator set
const validators = await client.getValidatorSet();
 
// Get staking info
const staking = await client.getStakingInfo();
 
// Query a loom contract (read-only)
const queryResult = await client.queryLoom("0xloomId...", "0xinputHex...");
 
// Get metrics (Prometheus format)
const metrics = await client.getMetrics();

Mutation Methods

Mutation methods require signed transaction data (hex-encoded borsh). Use the transaction builders below to construct these.

// Submit a transfer
const result = await client.submitKnot(signedTransferHex);
 
// Register a name
const result = await client.registerName("alice", ownerHex, signedNameHex);
 
// Create a token
const result = await client.createToken(signedTokenDefHex);
 
// Mint / burn tokens
const result = await client.mintToken(signedMintHex);
const result = await client.burnToken(signedBurnHex);
 
// Deploy a loom (smart contract)
const result = await client.deployLoom(registrationHex);
 
// Upload bytecode to a loom
const result = await client.uploadBytecode(loomId, bytecodeHex, initMsgHex);
 
// Execute a loom contract
const result = await client.executeLoom(loomId, inputHex, senderHex);
 
// Request testnet faucet tokens
const result = await client.faucet("0xaddress...");

Transaction Builders

Build and sign transactions using the builder functions:

import {
  Wallet,
  NornClient,
  buildTransfer,
  buildNameRegistration,
  buildTokenDefinition,
  buildTokenMint,
  buildTokenBurn,
  parseAmount,
  formatAmount,
  addressToHex,
} from "@norn-protocol/sdk";
 
const wallet = Wallet.fromPrivateKeyHex("abcd1234...");
const client = new NornClient({ url: "https://seed.norn.network" });
 
// Build a transfer (NORN uses 12 decimals)
const transferHex = buildTransfer(wallet, {
  to: "0xrecipient...",
  amount: parseAmount("10.5"),     // converts "10.5" to bigint
  tokenId: "0x...",                // optional, defaults to native NORN
  memo: "payment",                 // optional
});
await client.submitKnot(transferHex);
 
// Register a NornName
const nameHex = buildNameRegistration(wallet, "alice");
await client.registerName("alice", wallet.addressHex, nameHex);
 
// Create a token
const tokenHex = buildTokenDefinition(wallet, {
  name: "My Token",
  symbol: "MTK",
  decimals: 8,
  maxSupply: 1000000n,
  initialSupply: 1000n,   // optional, defaults to 0
});
await client.createToken(tokenHex);
 
// Mint tokens
const mintHex = buildTokenMint(wallet, {
  tokenId: "0x...",
  to: "0xrecipient...",
  amount: 500n,
});
await client.mintToken(mintHex);
 
// Burn tokens
const burnHex = buildTokenBurn(wallet, {
  tokenId: "0x...",
  amount: 100n,
});
await client.burnToken(burnHex);

Amount Utilities

// Parse human-readable amount to raw bigint (default 12 decimals for NORN)
const raw = parseAmount("1.5");           // 1_500_000_000_000n
const raw8 = parseAmount("1.5", 8);       // 150_000_000n
 
// Format raw bigint to human-readable string
const human = formatAmount(1_500_000_000_000n);     // "1.5"
const human8 = formatAmount(150_000_000n, 8);       // "1.5"

WebSocket Subscriptions

Subscribe to real-time events using the SubscribeOptions object:

import {
  subscribeNewBlocks,
  subscribeTransfers,
  subscribeTokenEvents,
  subscribeLoomEvents,
  subscribePendingTransactions,
} from "@norn-protocol/sdk";
import type { SubscribeOptions } from "@norn-protocol/sdk";
 
const options: SubscribeOptions = {
  url: "ws://seed.norn.network:9944",
  onOpen: () => console.log("Connected"),
  onClose: () => console.log("Disconnected"),
  onError: (err) => console.error("Error:", err),
};
 
// Subscribe to new blocks
const blockSub = subscribeNewBlocks(options, (block) => {
  console.log("New block:", block.height);
});
 
// Subscribe to transfers (optional address filter)
const transferSub = subscribeTransfers(options, (tx) => {
  console.log("Transfer:", tx.from, "->", tx.to, tx.amount);
}, "0xaddressFilter...");
 
// Subscribe to token events (optional token ID filter)
const tokenSub = subscribeTokenEvents(options, (event) => {
  console.log("Token event:", event);
}, "0xtokenIdFilter...");
 
// Subscribe to loom execution events (optional loom ID filter)
const loomSub = subscribeLoomEvents(options, (event) => {
  console.log("Loom event:", event);
}, "0xloomIdFilter...");
 
// Subscribe to pending transactions
const pendingSub = subscribePendingTransactions(options, (event) => {
  console.log("Pending tx:", event);
});
 
// Unsubscribe when done
blockSub.unsubscribe();
transferSub.unsubscribe();
 
// Check if still connected
console.log(blockSub.isActive);

Address Utilities

The SDK exports helper functions for converting between Uint8Array addresses and hex strings:

import { addressToHex, hexToAddress, toHex, fromHex } from "@norn-protocol/sdk";
 
// Address (20 bytes) <-> hex string
const hex = addressToHex(wallet.address);   // "0x01010101..."
const addr = hexToAddress("0x01010101..."); // Uint8Array(20)
 
// General byte array <-> hex string
const hexStr = toHex(someBytes);     // hex string (no prefix)
const bytes = fromHex("abcd1234");   // Uint8Array

Exports

The SDK exports the following:

Classes

  • Wallet — Ed25519 key management
  • NornClient — JSON-RPC client with typed methods for all 40+ endpoints
  • Subscription — WebSocket subscription handle with unsubscribe() and isActive
  • BorshWriter, BorshReader — Borsh serialization helpers

Functions

  • blake3Hash, ed25519Sign, ed25519Verify — Cryptographic primitives
  • publicKeyFromPrivate, publicKeyToAddress — Key derivation
  • toHex, fromHex, addressToHex, hexToAddress — Encoding utilities
  • buildTransfer, buildNameRegistration, buildTokenDefinition, buildTokenMint, buildTokenBurn — Transaction builders
  • parseAmount, formatAmount — Amount conversion (human-readable ↔ raw bigint)
  • subscribeNewBlocks, subscribeTransfers, subscribeTokenEvents, subscribeLoomEvents, subscribePendingTransactions — WebSocket subscriptions

Types

  • SubscribeOptions — WebSocket connection options (url, onOpen?, onClose?, onError?)
  • NornClientOptions — RPC client options (url, apiKey?, timeout?)
  • BlockInfo, BlockTransactionsInfo, WeaveStateInfo, ThreadInfo, TokenInfo, LoomInfo — Chain state types
  • TransactionHistoryEntry, SubmitResult, ExecutionResult, QueryResult — Transaction types
  • AddressHex, HashHex, PubKeyHex, Amount — Type aliases