Api

Byte Array Methods

Methods for serializing and deserializing raw byte arrays with or without length prefixes, and controlling memory allocation behavior.

Sia provides methods for writing and reading raw Uint8Array data. Byte array methods come in two flavors: with a length prefix (self-describing) and without a length prefix (fixed-size). All methods are available as both class methods and standalone functions:

// Class API
import { Sia } from "@timeleap/sia";

// Functional API (tree-shakeable)
import { Buffer, addByteArray8, readByteArray8 } from "@timeleap/sia";

With Length Prefix

These methods prepend the byte array's length before the data, so the reader knows how many bytes to consume. The number suffix indicates the bit width of the length prefix.

addByteArray8(bytes) / readByteArray8(asReference?)

Writes or reads a byte array with an 8-bit (1 byte) length prefix. Maximum array length: 255 bytes.

addByteArray8(bytes: Uint8Array): Sia
readByteArray8(asReference?: boolean): Uint8Array
ParameterTypeDefaultDescription
bytesUint8ArrayThe byte array to write
asReferencebooleanfalseIf true, returns a subarray (zero-copy)
const sia = new Sia();
const data = new Uint8Array([1, 2, 3, 4, 5]);
sia.addByteArray8(data);
sia.seek(0);
const result = sia.readByteArray8();
console.log(result); // Uint8Array [1, 2, 3, 4, 5]

addByteArray16(bytes) / readByteArray16(asReference?)

Writes or reads a byte array with a 16-bit (2 byte) length prefix. Maximum array length: 65,535 bytes.

addByteArray16(bytes: Uint8Array): Sia
readByteArray16(asReference?: boolean): Uint8Array
ParameterTypeDefaultDescription
bytesUint8ArrayThe byte array to write
asReferencebooleanfalseIf true, returns a subarray (zero-copy)
const sia = new Sia();
const data = new Uint8Array([10, 20, 30, 40, 50]);
sia.addByteArray16(data);
sia.seek(0);
const result = sia.readByteArray16();
console.log(result); // Uint8Array [10, 20, 30, 40, 50]

addByteArray32(bytes) / readByteArray32(asReference?)

Writes or reads a byte array with a 32-bit (4 byte) length prefix. Maximum array length: ~4 GB.

addByteArray32(bytes: Uint8Array): Sia
readByteArray32(asReference?: boolean): Uint8Array
ParameterTypeDefaultDescription
bytesUint8ArrayThe byte array to write
asReferencebooleanfalseIf true, returns a subarray (zero-copy)
const sia = new Sia();
const data = new Uint8Array(100).map((_, i) => i);
sia.addByteArray32(data);
sia.seek(0);
const result = sia.readByteArray32();
console.log(result.length); // 100

addByteArray64(bytes) / readByteArray64(asReference?)

Writes or reads a byte array with a 64-bit (8 byte) length prefix.

addByteArray64(bytes: Uint8Array): Sia
readByteArray64(asReference?: boolean): Uint8Array
ParameterTypeDefaultDescription
bytesUint8ArrayThe byte array to write
asReferencebooleanfalseIf true, returns a subarray (zero-copy)
const sia = new Sia();
const data = new Uint8Array(50).map((_, i) => (i * 2) % 256);
sia.addByteArray64(data);
sia.seek(0);
const result = sia.readByteArray64();
console.log(result.length); // 50

Without Length Prefix

addByteArrayN(bytes) / readByteArrayN(length, asReference?)

Writes or reads a byte array without any length prefix. You must know the exact length at read time.

addByteArrayN(bytes: Uint8Array): Sia
readByteArrayN(length: number, asReference?: boolean): Uint8Array
ParameterTypeDefaultDescription
bytesUint8ArrayThe byte array to write
lengthnumberExact number of bytes to read
asReferencebooleanfalseIf true, returns a subarray (zero-copy)

Throws: "Not enough data to read byte array" if there are insufficient bytes to read.

This is useful when the byte length is implied by the protocol (e.g., a 32-byte public key always has a known size).

const sia = new Sia();

// Write a 32-byte public key (no length prefix needed)
const publicKey = new Uint8Array(32).fill(0xab);
sia.addByteArrayN(publicKey);

sia.seek(0);

// Read exactly 32 bytes
const key = sia.readByteArrayN(32);
console.log(key.length); // 32

The asReference Parameter

All readByteArray* methods accept an optional asReference parameter that controls memory allocation behavior.

When asReference is false (default), readByteArray* returns a copy of the data using slice(). This is safe to store, modify, and pass around independently.When asReference is true, it returns a subarray that shares memory with the Sia buffer. This avoids a memory allocation but means changes to the original buffer will affect the returned array.
Copy (default)
const sia = new Sia();
sia.addByteArray8(new Uint8Array([1, 2, 3]));
sia.seek(0);

// Returns an independent copy
const copy = sia.readByteArray8(false);
copy[0] = 99; // Does NOT affect the Sia buffer
Reference (zero-copy)
const sia = new Sia();
sia.addByteArray8(new Uint8Array([1, 2, 3]));
sia.seek(0);

// Returns a view into the same memory
const ref = sia.readByteArray8(true);
// ref shares memory with sia.content — use immediately

When to use asReference = true:

  • Decoding performance is critical and you will consume the data immediately
  • You are reading data only to pass it to another function (e.g., TextDecoder.decode())
  • You are building a streaming pipeline where copies are wasteful

When to use the default (false):

  • You need to store the result for later use
  • The Sia buffer may be reused or modified
  • You are using the default shared buffer

Length Prefix Sizes

MethodPrefix SizeMax Array Length
addByteArray81 byte255 bytes
addByteArray162 bytes65,535 bytes
addByteArray324 bytes~4.29 GB
addByteArray648 bytes~2^53 bytes
addByteArrayN0 bytesCaller-specified

Complete Example

Serializing a message with a public key, signature, and variable-length payload:

import { Sia } from "@timeleap/sia";

// Serialize a signed message
const sia = new Sia();

const publicKey = new Uint8Array(32).fill(0x01); // 32-byte Ed25519 key
const signature = new Uint8Array(64).fill(0x02); // 64-byte signature
const payload = new TextEncoder().encode("Transfer 100 tokens to Alice");

sia
  .addByteArrayN(publicKey) // Fixed 32 bytes — no prefix needed
  .addByteArrayN(signature) // Fixed 64 bytes — no prefix needed
  .addByteArray16(payload); // Variable length — needs a prefix

const bytes = sia.toUint8Array();
console.log(bytes.length);
// 32 + 64 + 2 (prefix) + 28 (payload) = 126 bytes

// Deserialize
const reader = new Sia(bytes);

const readKey = reader.readByteArrayN(32);
const readSig = reader.readByteArrayN(64);
const readPayload = reader.readByteArray16();

console.log(new TextDecoder().decode(readPayload));
// "Transfer 100 tokens to Alice"