@ergots/scorex
v0.1.0
Published
Pure-TypeScript Scorex wire codec (VLQ, ZigZag VLQ, ByteReader/Writer) plus Ergo block-Header / AutolykosSolution data types shared across @ergots/* packages.
Downloads
79
Maintainers
Readme
@ergots/scorex
Pure-TypeScript Scorex wire-codec layer, block-Header types, and Autolykos v2 PoW verifier. Browser-compatible. Validated byte-for-byte against sigma-rust (ergo-chain-types + sigma-ser, branch integration/ergots).
This package is the shared foundation for @ergots/nipopow and @ergots/ergoscript: it provides the ByteReader / ByteWriter classes, VLQ + ZigZag-VLQ encode/decode, the Header and AutolykosSolution types, digest-length constants, and the Autolykos v2 proof-of-work verifier (verifyAutolykosV2 and decodeCompactBits). Extracting this layer removes duplicate codec implementations across packages and provides a stable, single-source-of-truth for the Ergo block-header wire format.
Install
Currently a workspace package; not yet published to npm.
# Within the ergots monorepo workspace:
npm install @ergots/scorexPublic API
Codec layer
import { ByteReader, ByteWriter, ReaderError, MAX_ARRAY_LENGTH } from '@ergots/scorex';
import { encodeVlqU, decodeVlqU, encodeVlqZigZag, decodeVlqZigZag, readVlqU32 } from '@ergots/scorex';
const r = new ByteReader(bytes);
const n = r.readVlqU(); // plain unsigned VLQ -> number
const s = r.readVlqS(); // ZigZag VLQ -> number (signed)
const big = r.readVlqBigInt(); // plain unsigned VLQ -> bigint (64-bit safe)
const opt = r.readOption(sub => sub.readU8()); // null | T
const arr = r.readArray(sub => sub.readU8()); // T[]
const w = new ByteWriter();
w.writeVlqU(42);
w.writeOption(null, (sub, v) => sub.writeU8(v));
w.writeArray([1, 2, 3], (sub, v) => sub.writeU8(v));
const out = w.toBytes(); // Uint8ArrayBlock Header types and codecs
import { parseHeader, serializeHeader, serializeHeaderWithoutPow, deriveHeaderId } from '@ergots/scorex';
import type { Header, AutolykosSolution } from '@ergots/scorex';
const header = parseHeader(reader); // derives id in-process; not read from wire
const bytes = serializeHeader(header);
const id = deriveHeaderId(header); // blake2b256(serializeHeader(header)); 32 bytesDigest helpers
import { BLOCK_ID_LEN, DIGEST32_LEN, AD_DIGEST_LEN, EC_POINT_LEN, readFixed, writeFixed } from '@ergots/scorex';Autolykos v2 PoW verifier
import { verifyAutolykosV2, decodeCompactBits, AutolykosV1NotSupportedError } from '@ergots/scorex';
const ok: boolean = verifyAutolykosV2(header); // throws AutolykosV1NotSupportedError on v1 headers
const target: bigint = decodeCompactBits(header.nBits); // Bitcoin-compact difficulty -> 256-bit targetVerifies an Autolykos v2 proof-of-work solution against the header's self-declared nBits target. v1 headers throw a typed error (sigma-rust parity — neither sigma-rust nor ergo-node-rust verify v1 PoW; v1 is JVM-only territory).
See facts/scorex.md for the full interface contract: all method signatures, type invariants, VLQ semantics, error codes, and source mapping to sigma-rust.
Browser compatibility
Runs unchanged in evergreen browsers and Node >= 20. No Buffer, no node:crypto, no dynamic Node built-ins, no WASM. ESM-only.
All codec functions are pure and synchronous: bytes in, structured result out. No I/O, no clock, no storage.
What this package does NOT do
SValue/SType/Expr/ErgoBoxtypes. Package-specific to@ergots/ergoscript.NipopowProof/AvlTreeData/Operationtypes. Package-specific to their respective packages.- base58 / base58check. Single-consumer in
@ergots/ergoscript; not promoted to shared layer.
Reference implementation
This package ports the Scorex wire-codec layer and Header types from sigma-rust (sigma-ser/src/vlq_encode.rs, ergo-chain-types/src/header.rs, branch integration/ergots). Every Header and AutolykosSolution test asserts byte-equality against fixtures generated by the sigma-rust reference.
See facts/scorex.md for the load-bearing interface contract and source-mapping table.
License
MIT
