Skip to main content

Changelog

v3.1.0

May 7, 2026 Polish release on top of v3.0.0. Bug fix for serializer key ordering and JSDoc/type accuracy improvements.

Fixes

  • fix(serializer): preserve transaction_fee source key order via spread, ensuring stable wire serialization.
  • docs+types: JSDoc accuracy fix, return type fix, and stale comment cleanup across the public API surface.

v3.0.0

May 7, 2026 Major release. Introduces sub-DEM denomination via the osDenomination fork. 1 DEM = 10^9 OS, exposed through a new denomination module and bigint-aware public API. See Amounts & Denominations for the full developer guide.
v3.0.0 was first published as 3.0.0-rc.1 on May 7, 2026 and promoted to 3.0.0 the same release window. The two share the same feature set; v3.1.0 then layered on the serializer fix above.

New denomination module

Exports: demToOs, osToDem, parseOsString, toOsString, formatDem, MIN_AMOUNT_OS, ZERO_OS, plus constants OS_DECIMALS = 9 and OS_PER_DEM = 10n ** 9n.
import { denomination } from "@kynesyslabs/demosdk"

const amountOs = denomination.demToOs("1.5")        // 1_500_000_000n
const amountDem = denomination.osToDem(amountOs)    // "1.5"

Public API widened to bigint

Demos.transfer and Demos.pay now accept number | bigint. bigint (OS) is the preferred form going forward — number (whole DEM) continues to work but is deprecated and will be removed in v4.
// preferred
await demos.transfer(to, 1_500_000_000n)        // 1.5 DEM in OS

// still accepted, deprecated
await demos.transfer(to, 1)                      // 1 DEM

Fork detection: Demos.getNetworkInfo()

New RPC Demos.getNetworkInfo(): Promise<NetworkInfo | null> reports whether the connected node is post-fork. Results are cached per RPC URL with a 30-second failure-TTL recovery window so transient errors don’t pin a node to “unknown” forever.

SubDemPrecisionError

Thrown when a caller submits sub-DEM precision against a pre-fork node, where the value would otherwise silently truncate. Carries amountOs and subDemRemainderOs for diagnostics.

Wire format widening

TransactionContent.amount, TxFee.*, RawTransaction.{amount,networkFee,rpcFee,additionalFee}, and StatusNative.balance now accept number | string. The SDK normalizes everything to bigint internally.

Dual-format serializerGate

The serializer emits the wire shape that matches the cached fork status of the target node, so the same client transparently talks to pre-fork and post-fork validators.

Bug fixes carried in v3.0

  • STORAGE_PROGRAM_CONSTANTS.FEE_PER_CHUNK corrected from 1n to OS_PER_DEM. Pre-v3.0 this was a 10⁹× under-billing of storage chunk fees.
  • getAddressInfo(...).balance now returns bigint OS on post-fork nodes.

v2.12.2

May 6, 2026 Validator staking, on-chain governance, and a TS strict-mode fix. Brings PR #84 (feat-upgradable-network) into a minor release. See Validator Staking and Governance.

Validator staking

  • New DemosTransactions.stake(amount: string, connectionUrl: string, demos) — bigint-encoded amount string in OS; connectionUrl is required on first stake.
  • New DemosTransactions.unstake(demos) and DemosTransactions.claimUnstakedAmount(demos).
  • New read methods on Demos: getValidatorInfo(address), getValidators(blockNumber?), getStakedAmount(address).

On-chain governance

  • New DemosTransactions.proposeNetworkUpgrade(params, demos)params.proposalId (UUID), params.proposedParameters: Partial<NetworkParameters>, params.rationale (≤ 1024 bytes), params.effectiveAtBlock. Only active validators may propose.
  • New DemosTransactions.voteOnUpgrade(proposalId, approve, demos) — one vote per proposal; voter must be in the snapshot validator set.
  • New read methods on Demos: getNetworkParameters(), getActiveProposals(), getProposalVotes(id), getUpgradeHistory().

Other

  • Replace Math.random() with crypto.getRandomValues() for secure random generation across multiple modules.
  • Validate network parameters before caching (_getNetworkParametersCached).
  • Simplify stake() validation; add JSDoc to internal helpers.
  • Preserve Partial<NetworkParameters> typing in proposeNetworkUpgrade.
  • Remove invalid override modifier on the cause property in error classes (TS strict-mode fix).

v2.12.1

May 5, 2026 Transport-layer hardening and deterministic broadcast helpers. See Broadcasting a Transaction.

broadcastAndWait

  • New Demos.broadcastAndWait(validityData, opts?) — deterministic tx-inclusion polling. Throws BroadcastTimeoutError on timeout. Returns { broadcast, status: { state, blockNumber? } }.
  • Lower-level DemosTransactions.broadcastAndWait adds an opt-in failFastOnBroadcastError flag that throws BroadcastFailedError immediately when the broadcast can’t reach the node (ECONNREFUSED, ENOTFOUND). HTTP 5xx is not treated as fail-fast — the server did answer.

Transport layer

  • HTTP Retry-After header support (seconds or HTTP-date).
  • MAX_BACKOFF_MS = 8000 cap on exponential backoff so a misbehaving node can’t stall a single call indefinitely.
  • Accurate attempt count in TransportError.
  • Stop forwarding rpcCall’s retries argument into the _doPost transport budget — retry budgets no longer multiply across layers.

New error class

  • TransportError (in @kynesyslabs/demosdk/websdk) carrying attempts and cause.

v2.12.0

May 1, 2026 Adds the foundational denomination utilities that v3.0.0 builds on, plus storage-program test cleanup.
  • New denomination module with DEM/OS conversion utilities (consumed publicly starting in v3.0.0).
  • Updated storage program test names for clarity.

v2.11.6

April 20, 2026
  • Add sign and read methods to demos.storagePrograms for streamlined storage-program transaction construction.

v2.11.5

March 26, 2026 L2PS messaging client and protocol types (PR #82, feat/l2ps-messaging-types).
  • New L2PS class exported from @kynesyslabs/demosdk/l2ps.
    • Factory: L2PS.create(privateKey?, iv?).
    • Registry: getInstance, getInstances, hasInstance, removeInstance.
  • Instance methods:
    • encryptTx(tx, senderIdentity?) — wraps a transaction in L2PSEncryptedPayload. The wrapped tx type becomes l2psEncryptedTx.
    • decryptTx(encryptedTx) — recovers the inner transaction.

v2.11.4

March 16, 2026
  • fix(abstraction): export IdentityAttestationPayload and IdentityCommitmentPayload from the /abstraction barrel.

v2.11.3

March 16, 2026 Multi-instance crypto isolation.
  • Per-Demos-instance _cryptoInstanceId (UUID) — fixes identity bleed across multiple Demos instances in the same process. Previously the encryption singleton could leak state between independently-constructed clients.
  • Additional small bugfixes around the encryption singleton.

v2.11.2

March 4, 2026 Human Passport identity integration (PR #73). See Human Passport identity.
  • Identities.getHumanPassportScore(demos, address)
  • Identities.getHumanPassportIdentities(demos, demosAddress)
  • Identities.addHumanPassportIdentity(demos, payload) — supports api and onchain verification methods. Default score threshold is 20. Throws if verificationMethod === "onchain" and chainId == null.
  • Identities.removeHumanPassportIdentity(demos, address)

v2.11.1

March 3, 2026 Ethos identity integration (PR #74). See Ethos identity.
  • Identities.getEthosScore(demos, walletAddress)
  • Identities.getEthosIdentities(demos, address?)
  • Identities.addEthosIdentity(demos, payload) — EVM-only with payload validation.
  • Identities.removeEthosIdentity(demos, payload)

v2.11.0

February 22, 2026 Foundational housekeeping release ahead of the identity wave (Ethos, Human Passport, L2PS messaging) that lands across v2.11.1–v2.11.5.
  • Initial token structure scaffolding.
  • Solana contract_write test cleanup.
  • Jest tsconfig fixes.

v2.10.2

February 13, 2026
  • Update addWeb2IdentityViaTLSN method (PR #77). Generic Web2 identity assignment via TLSNotary, exposed as addWeb2IdentityViaTLSN(context, url, proof, demos) and removeWeb2IdentityViaTLSN(context, demos).

v2.10.1

February 12, 2026
  • refactor: change node-forge import from namespace to default to fix L2PS imports under stricter bundler resolution (PR #76).

v2.10.0

February 10, 2026 Identity-via-TLSNotary suite (PR #75). Adds add/remove methods for several identity providers attested via TLSNotary proofs.
  • addGithubIdentityViaTLSN / removeGithubIdentityViaTLSN
  • addDiscordIdentityViaTLSN / removeDiscordIdentityViaTLSN
  • addTelegramIdentityViaTLSN / removeTelegramIdentityViaTLSN
  • Nomis identity helpers: getNomisScore, addNomisIdentity, removeNomisIdentity. See Nomis identity.
  • TRON multichain support (PR #56). See TRON.

December 2024 Updates

December 2024

New Chain Support

Several new blockchain networks have been added to the cross-chain SDK:

NEAR Protocol

Full support for NEAR blockchain including:
  • Token transfers with preparePay and preparePays
  • Account creation and deletion
  • Message signing and verification
  • See NEAR documentation for details

Cosmos Hub (ATOM)

IBC-compatible Cosmos Hub support:
  • Native ATOM transfers via IBC SDK
  • Uses existing IBC infrastructure with Cosmos-specific configuration
  • Testnet: rpc.provider-sentry-01.ics-testnet.polypore.xyz
  • Mainnet: cosmos-rpc.publicnode.com

Bitcoin (BTC)

SegWit (P2WPKH) Bitcoin support:
  • Native BTC transfers
  • UTXO management and balance checking
  • See BTC documentation for details

Polygon (Amoy Testnet)

EVM-compatible Polygon support:
  • Polygon Amoy testnet for development
  • Polygon mainnet support
  • Chain ID: 137 (mainnet), 80002 (Amoy)

XRP Ledger Send Functionality

Enhanced XRPL support with full send capabilities:
  • Token transfers via preparePay
  • Multiple transfer support via preparePays
  • See XRPL documentation for details

Identity Verification Updates

GitHub OAuth Flow

New OAuth-based identity verification for GitHub:
  • Seamless one-click authentication
  • Node-signed attestations with 5-minute validity
  • Complementary to existing gist-based verification
  • See GitHub identity documentation for details

Discord Identity Support

Full Discord identity verification:

Infrastructure Improvements

  • Improved error handling in multichain executors
  • Enhanced logging with log rotation support
  • Node diagnostic tooling (node-doctor)

The HTTP Rewrite

August 20th, 2024 The SDK with the HTTP rewrite of the demos object is published at @kynesyslabs/demosdk-http on NPM.
import { demos } from "@kynesyslabs/demosdk-http/websdk"

Connecting to a node

To connect to a node, use the connect method.
const rpc_url = "http://localhost:53550"

await demos.connect(rpc_url)
assert(demos.connected === true)
This will ping the rpc and return a true if the rpc is found, or throw an error. Once connected, you can now make unauthenticated requests (node calls).
const lastBlockHash = await demos.getLastBlockHash()

Connecting a wallet

To make authenticated calls to the node (eg. confirming or broadcasting transactions), you need to connect a keypair to the demos object.
const identity = demos.DemosWebAuth.getInstance()
await identity.create()

const pubKey = await demos.connectWallet(identity.keypair.privateKey)
assert(demos.walletConnected === true)
You can also connect a wallet using a mnemonic.
const mnemonic = "property gym walk decorate laundry grab cabin outer artist nest castle vote"

const pubKey = await demos.connectWallet(mnemonic, {
    isSeed: true,
})
Or if you have a bip39 seed.
const mnemonic = "property gym walk decorate laundry grab cabin outer artist nest castle vote"
const seed = bip39.mnemonicToSeedSync(mnemonic)

const pubKey = await demos.connectWallet(seed, {
    isSeed: true,
})
The process of converting a mnemonic to a keypair is defined at Cryptography.newFromSeed (in @/encryption/Cryptography.ts).
You can get the address of the connected wallet using the demos.getAddress() method.
With the wallet connected, you can now send authenticated requests to the node.
const validityData = await demos.confirm(tx)

Resetting the demos object

Once you’re done, you can reset the demos object.
demos.disconnect()
Calling demos.disconnect won’t log out the DemosWebAuth instance. You need to call identity.logout() to reset that.

Decoupling DemosWebAuth from the websdk

August 30th, 2024 We’ve decoupled the DemosWebAuth from the helper methods and objects in the websdk. That simply means that you’ll now need to pass the keypair to the methods that need it, instead of them reference the global DemosWebAuth instance. Here’s a list of affected methods:

1. DemosTransactions.sign

This method was previously using the global DemosWebAuth instance to sign transactions. Now you need to pass the keypair to the method.
// from:
DemosTransactions.sign(raw_tx: Transaction)

// to:
DemosTransactions.sign(raw_tx: Transaction, keypair: IKeyPair)
You can use the keypair connected to the demos object with DemosTransactions.sign you can call demos.tx.sign(tx) instead.

2. prepareWeb2Payload

The prepareWeb2Payload method now requires payload parameters and a keypair for signing the Transaction.
// from:
prepareWeb2Payload(
    action = "GET",
    url = "https://icanhazip.com",
    ...
)

// to:
prepareWeb2Payload(
    params: IPrepareWeb2PayloadParams = {
        action: "GET",
        url: "https://icanhazip.com",
        ...
    },
    keypair: IKeyPair,
)
To use the keypair connected to the demos object with prepareWeb2Payload, you can call demos.web2.preparePayload(params) instead.

3. prepareXMPayload

The prepareXMPayload method now requires a XMScript and a keypair for signing the Transaction.
// from:
prepareXMPayload(xm_payload: XMScript)

// to:
prepareXMPayload(xm_payload: XMScript, keypair: IKeyPair)
To use the keypair connected to the demos object with prepareXMPayload, you can call demos.xm.preparePayload(xm_payload) instead.

4. Wallet.transfer

// from:
Wallet.transfer(to: Address, amount: number)

// to:
Wallet.transfer(to: Address, amount: number, keypair: IKeyPair)