strictencode
v0.0.2
Published
Deterministic binary encoding for RGB protocol compliance - JavaScript implementation of StrictEncode
Maintainers
Readme
StrictEncode
Deterministic binary encoding for RGB protocol compliance. JavaScript implementation of StrictEncode specification.
Features
- ✅ Deterministic: Same input always produces identical output
- ✅ Consensus-critical: Suitable for blockchain and smart contract applications
- ✅ RGB-compatible: Full support for RGB20 token contract encoding
- ✅ Type-safe: Comprehensive input validation and error handling
- ✅ Well-tested: 100% test coverage with comprehensive test vectors
- ✅ Dual module: Works with both ES modules and CommonJS
Installation
npm install strictencodeQuick Start
import { StrictEncoder, RGB20Encoder } from 'strictencode';
// Basic encoding
const encoder = new StrictEncoder();
encoder.encodeU32(1000000).encodeString("RGB20");
console.log(encoder.toHex()); // "40420f000552474232"
// RGB20 asset specification
const assetSpec = {
ticker: "NIATCKR",
name: "NIA asset name",
precision: 8,
details: null
};
const encoded = RGB20Encoder.encodeAssetSpec(assetSpec);
console.log(encoded); // "074e494154434b520e4e4941206173736574206e616d650800"Core Types
StrictEncoder
The main encoding class supporting all primitive types:
const encoder = new StrictEncoder();
// Integers (little-endian)
encoder.encodeU8(255); // Single byte: ff
encoder.encodeU16(65535); // Two bytes: ffff
encoder.encodeU32(1000000); // Four bytes: 40420f00
encoder.encodeU64(1000000n); // Eight bytes: 40420f0000000000
// Boolean
encoder.encodeBool(true); // Single byte: 01
// Variable-length integers (LEB128)
encoder.encodeLeb128(128); // Multi-byte: 8001
// Strings (LEB128 length + UTF-8)
encoder.encodeString("RGB"); // 03524742
// Collections
encoder.encodeVec([1, 2, 3], (item) => encoder.encodeU8(item));
encoder.encodeOption("test", (value) => encoder.encodeString(value));
// Get results
console.log(encoder.toHex()); // Hex string
console.log(encoder.toBytes()); // Uint8ArrayLEB128 Encoding
Variable-length encoding for efficient integer storage:
encoder.encodeLeb128(7); // Single byte: 07
encoder.encodeLeb128(128); // Multi-byte: 8001
encoder.encodeLeb128(200); // Multi-byte: c801String Encoding
Length-prefixed UTF-8 strings:
encoder.encodeString(""); // Empty: 00
encoder.encodeString("RGB"); // Short: 03524742
encoder.encodeString("A".repeat(200)); // Long: c801414141... (LEB128 length)Option Encoding
Nullable value encoding:
encoder.encodeOption(null, () => {}); // None: 00
encoder.encodeOption("test", (v) => encoder.encodeString(v)); // Some: 010474657374RGB20 Support
AssetSpec Encoding
const spec = {
ticker: "BTC", // Asset symbol
name: "Bitcoin", // Full name
precision: 8, // Decimal places
details: null // Optional details
};
const encoded = RGB20Encoder.encodeAssetSpec(spec);ContractTerms Encoding
const terms = {
text: "Standard RGB20 token contract",
media: null // Optional media reference
};
const encoded = RGB20Encoder.encodeContractTerms(terms);Amount Encoding
// Token amounts as 64-bit integers
const encoded = RGB20Encoder.encodeAmount(1000000);
console.log(encoded); // "40420f0000000000"Complete Genesis Structure
const genesis = RGB20Encoder.createGenesis({
assetSpec: {
ticker: "TESTCOIN",
name: "Test Coin",
precision: 8
},
contractTerms: {
text: "Test contract terms"
},
amount: 21000000,
utxo: "abc123...def:0"
});
// Ready for contract ID generation
const serialized = JSON.stringify(genesis, Object.keys(genesis).sort());
const contractId = sha256(serialized);API Reference
StrictEncoder Methods
| Method | Description | Example |
|--------|-------------|---------|
| encodeU8(value) | Encode 8-bit unsigned integer | encoder.encodeU8(255) |
| encodeU16(value) | Encode 16-bit unsigned integer (LE) | encoder.encodeU16(65535) |
| encodeU32(value) | Encode 32-bit unsigned integer (LE) | encoder.encodeU32(1000000) |
| encodeU64(value) | Encode 64-bit unsigned integer (LE) | encoder.encodeU64(1000000n) |
| encodeBool(value) | Encode boolean value | encoder.encodeBool(true) |
| encodeLeb128(value) | Encode variable-length integer | encoder.encodeLeb128(128) |
| encodeString(str) | Encode UTF-8 string | encoder.encodeString("test") |
| encodeOption(value, fn) | Encode optional value | encoder.encodeOption(null, () => {}) |
| encodeVec(array, fn) | Encode array/vector | encoder.encodeVec([1,2], encodeU8) |
| encodeHashMap(map, fn) | Encode sorted map | encoder.encodeHashMap({0:"a"}, encodeStr) |
RGB20Encoder Methods
| Method | Description | Returns |
|--------|-------------|---------|
| encodeAssetSpec(spec) | Encode asset specification | Hex string |
| encodeContractTerms(terms) | Encode contract terms | Hex string |
| encodeAmount(amount) | Encode token amount | Hex string |
| encodeGlobalState(state) | Encode complete state | Hex string |
| createGenesis(config) | Create genesis structure | Object |
Type IDs
import { RGB20_TYPE_IDS } from 'strictencode';
console.log(RGB20_TYPE_IDS.ASSET_SPEC); // 2000
console.log(RGB20_TYPE_IDS.CONTRACT_TERMS); // 2001
console.log(RGB20_TYPE_IDS.AMOUNT); // 2002Test Vectors
The package includes comprehensive test vectors from the StrictEncode specification:
// Standard RGB20 test case
const spec = {
ticker: "NIATCKR",
name: "NIA asset name",
precision: 8,
details: null
};
const encoded = RGB20Encoder.encodeAssetSpec(spec);
// Result: "074e494154434b520e4e4941206173736574206e616d650800"Testing
# Run tests
npm test
# Watch mode
npm run test:watch
# Coverage report
npm run test:coverageCommonJS Support
The package provides both ES modules and CommonJS builds:
// ES modules
import { StrictEncoder, RGB20Encoder } from 'strictencode';
// CommonJS
const { StrictEncoder, RGB20Encoder } = require('strictencode');Error Handling
All methods include comprehensive validation:
try {
encoder.encodeU8(256); // Invalid range
} catch (error) {
console.log(error.message); // "Invalid u8 value: 256. Must be integer 0-255"
}
try {
RGB20Encoder.encodeAssetSpec({}); // Missing required fields
} catch (error) {
console.log(error.message); // "ticker must be a non-empty string"
}Specification Compliance
This implementation follows the StrictEncode specification developed by the LNP/BP Standards Association. Key compliance features:
- ✅ Little-endian integer encoding
- ✅ LEB128 variable-length integers
- ✅ Length-prefixed UTF-8 strings
- ✅ Deterministic HashMap key ordering
- ✅ Option tag-based encoding
- ✅ RGB20 contract structure support
Related Projects
- baid64 - URL-safe Base64 encoding with checksums
- RGB Protocol - Smart contracts for Bitcoin & Lightning
- rust-rgb20 - Reference RGB20 implementation
Contributing
Pull requests welcome! Please ensure:
- All tests pass (
npm test) - Code follows existing style
- New features include tests
- Documentation is updated
License
Apache-2.0
Acknowledgments
Based on the StrictEncode specification by Dr. Maxim Orlovsky and the LNP/BP Standards Association. Developed for the RGB smart contracts ecosystem.
