BigInt Methods
Sia supports arbitrary-precision integers through JavaScript's native BigInt type. This is useful for values that exceed the 53-bit safe integer limit of Number, such as cryptographic values, blockchain amounts, or large counters. Available as both class methods and standalone functions:
// Class API
import { Sia } from "@timeleap/sia";
// Functional API (tree-shakeable)
import { Buffer, addBigInt, readBigInt } from "@timeleap/sia";
addBigInt(n) / readBigInt()
Writes or reads a BigInt value. The value is encoded as a variable-length big-endian byte array with an 8-bit length prefix.
addBigInt(n: bigint): Sia
readBigInt(): bigint
| Parameter | Type | Description |
|---|---|---|
n | bigint | The BigInt value to serialize |
Returns (add): this (for chaining)
Returns (read): bigint
Throws: "BigInt too large for this simple implementation" if the encoded byte representation exceeds 255 bytes.
Encoding Format
BigInt values are encoded using the following steps:
- The BigInt is converted to a hexadecimal string
- The hex string is padded to even length if needed
- Each pair of hex digits becomes one byte (big-endian order)
- The byte array is written using
addByteArray8, which prepends a 1-byte length prefix
The wire format is:
[1 byte: length] [N bytes: big-endian value]
For example, the value 123456789012345678901234567890 encodes as:
[13] [05 8D 15 E1 76 28 0F 09 AA CE 7B 22 52]
^ ^--- 13 bytes of big-endian data ----^
|
length prefix
big.Int.Bytes() encoding for cross-language
compatibility.Limitations
- Maximum encoded size is 255 bytes (limited by the 8-bit length prefix from
addByteArray8). This supports integers up to 2^2040 - 1, which is sufficient for most practical use cases. - Only non-negative values are supported. The encoding does not include a sign bit.
- The value
0nencodes as a zero-length byte array (1 byte total for the prefix).
const value = -123456789n;
sia.addBool(value < 0n).addBigInt(value < 0n ? -value : value);
Example
import { Sia } from "@timeleap/sia";
// A value too large for Number
const largeValue = BigInt("123456789012345678901234567890");
const sia = new Sia();
sia.addBigInt(largeValue);
sia.seek(0);
const result = sia.readBigInt();
console.log(result === largeValue); // true
console.log(result.toString()); // "123456789012345678901234567890"
Use Cases
Cryptographic Values
import { Sia } from "@timeleap/sia";
// 256-bit cryptographic hash as BigInt
const hash = BigInt(
"0xd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
);
const sia = new Sia();
sia.addBigInt(hash);
const bytes = sia.toUint8Array();
console.log(bytes.length); // 33 bytes (1 prefix + 32 value)
Token Amounts
import { Sia } from "@timeleap/sia";
// ERC-20 token amounts often exceed Number.MAX_SAFE_INTEGER
const amount = BigInt("1000000000000000000"); // 1 token with 18 decimals
const sia = new Sia();
sia.addAscii8("TRANSFER").addBigInt(amount).addByteArrayN(new Uint8Array(20)); // recipient address
const bytes = sia.toUint8Array();
// Deserialize
const reader = new Sia(bytes);
const action = reader.readAscii8();
const tokenAmount = reader.readBigInt();
const recipient = reader.readByteArrayN(20);
console.log(action); // "TRANSFER"
console.log(tokenAmount.toString()); // "1000000000000000000"
Comparison with Integer Methods
| Method | Type | Range | Bytes |
|---|---|---|---|
addUInt64 | number | 0 to 2^53 - 1 | 8 (fixed) |
addInt64 | number | -(2^53 - 1) to 2^53 - 1 | 8 (fixed) |
addBigInt | bigint | 0 to 2^2040 - 1 | 1 + N (variable) |
Use addUInt64/addInt64 when your values fit within the safe integer range for better performance and fixed-size encoding. Use addBigInt when you need arbitrary precision.