> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kynesys.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> Track the latest updates, improvements, and new features in the DEMOS SDK.

# 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](/sdk/websdk/transactions/denominations) for the full developer guide.

<Note>
  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.
</Note>

### 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`.

```ts theme={null}
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.

```ts theme={null}
// 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](/sdk/websdk/validator-staking/overview) and [Governance](/sdk/websdk/governance/overview).

### 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](/sdk/websdk/transactions/broadcasting-a-transaction#error-types).

### `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](/sdk/web2/identities/human-passport).

* `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](/sdk/web2/identities/ethos).

* `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](/sdk/web2/identities/nomis).
* TRON multichain support (PR #56). See [TRON](/sdk/cross-chain/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](/sdk/cross-chain/near) 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](/sdk/cross-chain/btc) 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](/sdk/cross-chain/xrpl) 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](/sdk/web2/identities/github) for details

#### Discord Identity Support

Full Discord identity verification:

* Message-based proof verification
* Support for all Discord domains (standard, PTB, Canary, legacy)
* See [Discord identity documentation](/sdk/web2/identities/discord) for details

### 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](https://www.npmjs.com/package/@kynesyslabs/demosdk-http) on NPM.

```ts theme={null}
import { demos } from "@kynesyslabs/demosdk-http/websdk"
```

### Connecting to a node

To connect to a node, use the `connect` method.

```ts theme={null}
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).

```ts theme={null}
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.

```ts theme={null}
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.

```ts theme={null}
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.

```ts theme={null}
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,
})
```

<Info>
  The process of converting a mnemonic to a keypair is defined at `Cryptography.newFromSeed` (in `@/encryption/Cryptography.ts`).
</Info>

<Info>
  You can get the address of the connected wallet using the `demos.getAddress()` method.
</Info>

With the wallet connected, you can now send authenticated requests to the node.

```ts theme={null}
const validityData = await demos.confirm(tx)
```

### Resetting the demos object

Once you're done, you can reset the demos object.

```ts theme={null}
demos.disconnect()
```

<Warning>
  Calling `demos.disconnect` won't log out the `DemosWebAuth` instance. You need to call `identity.logout()` to reset that.
</Warning>

## 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.

```ts theme={null}
// from:
DemosTransactions.sign(raw_tx: Transaction)

// to:
DemosTransactions.sign(raw_tx: Transaction, keypair: IKeyPair)
```

<Info>
  You can use the keypair connected to the demos object with `DemosTransactions.sign` you can call `demos.tx.sign(tx)` instead.
</Info>

#### 2. prepareWeb2Payload

The `prepareWeb2Payload` method now requires payload parameters and a keypair for signing the `Transaction`.

```ts theme={null}
// from:
prepareWeb2Payload(
    action = "GET",
    url = "https://icanhazip.com",
    ...
)

// to:
prepareWeb2Payload(
    params: IPrepareWeb2PayloadParams = {
        action: "GET",
        url: "https://icanhazip.com",
        ...
    },
    keypair: IKeyPair,
)
```

<Info>
  To use the keypair connected to the demos object with `prepareWeb2Payload`, you can call `demos.web2.preparePayload(params)` instead.
</Info>

#### 3. prepareXMPayload

The `prepareXMPayload` method now requires a `XMScript` and a keypair for signing the `Transaction`.

```ts theme={null}
// from:
prepareXMPayload(xm_payload: XMScript)

// to:
prepareXMPayload(xm_payload: XMScript, keypair: IKeyPair)
```

<Info>
  To use the keypair connected to the demos object with `prepareXMPayload`, you can call `demos.xm.preparePayload(xm_payload)` instead.
</Info>

#### 4. Wallet.transfer

```ts theme={null}
// from:
Wallet.transfer(to: Address, amount: number)

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