Skip to main content

Amounts & Denominations

DEMOS uses two denominations for native tokens: The conversion factor is exposed as OS_PER_DEM = 10n ** 9n.
The OS denomination ships behind the osDenomination fork. Pre-fork nodes accept only whole-DEM amounts on the wire (legacy number shape). Post-fork nodes accept full sub-DEM precision as bigint OS. The SDK detects the active wire format automatically — see Fork detection below.

Passing amounts to transfer and pay

Demos.transfer(to, amount) and its alias Demos.pay(to, amount) accept either:
  • bigint (preferred) — the amount in OS
  • number (legacy, deprecated) — the amount in whole DEM, auto-converted to OS internally
denomination.demToOs(input) accepts a number or string and returns a bigint in OS.
The number overload is deprecated. New code should pass bigint OS amounts. The legacy path remains for v2 callers and will be removed in v4.

The denomination module

The SDK exposes a small set of helpers under denomination:

Fork detection

The SDK exposes the node’s fork-activation status through Demos.getNetworkInfo():
The first call hits the node’s getNetworkInfo RPC. The result is cached on the Demos instance for its lifetime, keyed by the active RPC URL. To re-detect after a node upgrade, construct a fresh Demos instance. Failure modes:
  • If the node is unreachable or returns a malformed response, getNetworkInfo() returns null.
  • The SDK assumes pre-fork wire format in that case and emits a one-time console.warn recommending the operator upgrade the target node.
  • Transient outages are recovered via a 30-second TTL on the failure memo, so the SDK retries automatically.
You don’t normally need to call getNetworkInfo() yourself — transfer/pay/sign consult the cached fork status automatically. Calling it is useful when you want to display fork status to your users or branch your application logic.

Sub-DEM precision guard

When the connected node is pre-fork and your code submits a bigint OS amount that carries sub-DEM precision (i.e. amount % OS_PER_DEM !== 0n), the SDK refuses to sign the transaction and throws SubDemPrecisionError instead. This prevents silent truncation on the legacy DEM-number wire.
SubDemPrecisionError exposes:
  • amountOs: bigint — the OS amount the caller passed
  • subDemRemainderOs: bigint — the portion smaller than 1 DEM (i.e. amount % OS_PER_DEM)
The guard is inert on post-fork nodes — full sub-DEM precision is accepted natively.

Reading balances

Demos.getAddressInfo(address) returns the balance in OS as a bigint on post-fork nodes. The SDK widens the wire balance field to number | string and normalizes it internally, so you always receive a bigint from the public API.

Migration cheat-sheet

The legacy number API still works against pre-fork nodes for whole-DEM amounts. Sub-DEM precision and post-fork wire format require the bigint OS shape.