@stoachain/ouronet-core
v4.3.6
Published
Ouronet-specific business logic for the Ouronet protocol on StoaChain — interactions/* read+execute functions for the ouronet-ns Pact modules, the Codex encrypted-multi-wallet format, Ouronet protocol accounts and tokens. Depends on @stoachain/stoa-core f
Readme
@stoachain/ouronet-core
Ouronet protocol business logic on top of @stoachain/stoa-core — codex backup format, the 13 interactions/* Pact builders for the ouronet-ns modules, the STOA_AUTONOMIC_* autonomic accounts, and the cfm Pact-code assembler. Consumed by OuronetUI (browser SPA) and the AncientHolder HUB (Node.js server).
Chain-generic infrastructure (signing, wallet, crypto, network failover, gas, guard, errors, observability, dalos, reads, pact-format helpers) lives in the sibling @stoachain/stoa-core package — install both, or just this one if you only need the Ouronet-specific surface.
Status
4.3.6 on public npmjs — PATCH (atomic-triplet alignment with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-06-11. NO code changes in this package; version bumped solely to maintain the atomic-triplet invariant. The v4.3.6 change (a @stoachain/stoa-core auto-gas-limit floor fix in calculateAutoGasLimit) lives entirely in @stoachain/stoa-core. Functionally identical to 4.3.5. 829 specs pass.
4.3.5 on public npmjs — ADDITIVE (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected] — those two functionally identical to 4.3.4; only ouronet-core changed). Released 2026-06-10. Smart Ouronet Account deploy (buildDeploySmartAccountPactCode + getDeploySmartAccountInfo/…InfoOnly → C_DeploySmartAccount/URC_DeploySmartAccount); keyset-ref-aware activation (buildDeploy{Standard,Smart}AccountPactCode gained mode/keysetRef → (keyset-ref-guard "<ref>") in "existing" mode, preserving the keyset-ref guard type); and getIgnisBalance moved to tier T1 (balance reads belong there — at T5 the patron IGNIS balance stayed stale right after a transfer, falsely blocking spends). Pure additive — existing exports unchanged (deploy builders gained optional defaults). See CHANGELOG.
4.3.4 on public npmjs — PATCH (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-06-08. Bugfix — UrStoa vault-earnings hover unwrap. ouroPrimordialsFunctions.parseResponse routed urstoa-vault-earning-hover (a { decimal } object) through String() → "[object Object]" → 0, wrongly disabling the Dashboard UrStoa Collect button; it is now routed through supplyHoverVal (→ mayComeWithDeimal), matching the supply row. 822 specs pass. See CHANGELOG.
4.3.3 on public npmjs — Additive (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-30. New StoicTag + governor-rotation builders (buildRotateGovernorPactCode, buildNonKeyGuardExpr, buildReleaseStoicTagPactCode, buildRegisterStoicTagPactCode) + readers (getStoicTagInfo URC_0027c, getStoicTagSelectorData URC_0027b, getRegisterStoicTagInfo) + StoicTagSelectorData type, supporting the OuronetUI v1.2.5 StoicTag cycle. Bundles the never-published v4.3.2 frozen-keyset fix in resolveGuard / getKadenaAccountGuard (shallow-copy instead of mutating a frozen read result). Pure additive — no signature changes to existing exports. 822 specs pass. npm publishes 4.3.1 → 4.3.3 (4.3.2 was never tagged).
4.3.1 on public npmjs — PATCH (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-27. ESM extensionless-relative-import fix in emitted dist/**/*.js — same bug pattern as the sibling 4.3.1 packages. 40 source files updated, 90 imports rewritten. Strict ESM dynamic-imports (await import('@stoachain/ouronet-core/codex'), /pact, /constants, /interactions/*) now succeed under Node 22+. Peer-deps on @stoachain/kadena-stoic-legacy + @stoachain/stoa-core bumped 4.3.0 → 4.3.1. No API changes. 797/797 specs pass. See CHANGELOG.
4.3.0 on public npmjs — MINOR (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-25. Pure additive surface: 2 new account-rotation Pact builders — buildRotateGuardPactCode({ patron, account, mode, keysetRef?, safe }) (emits C_RotateGuard with runtime-conditional (read-keyset "ks") or (keyset-ref-guard "<ref>") expression) + buildRotateKadenaPactCode({ patron, account, newPaymentKey }) (emits C_RotateKadena, the kadena-ledger payment-key rotation Pact). MINOR over PATCH because these unlock a new categorised public consumer surface — the new sibling package @stoachain/[email protected]'s headless rotation modals — that wasn't reachable through the prior builder set. Deferred: buildRotateGovernorPactCode (Pact function exists on chain, Smart Account Σ. only, but no consumer UI ships it yet; lands when OuronetUI consumes it post-Phase-9-migration). Test count: 797 specs pass (was 788 in v4.2.2; +9 across the new builders). No signature changes to existing exports — consumers on 4.2.2 continue to work unchanged.
4.2.2 on public npmjs — PATCH (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-18. Pure additive surface: 4 new buildXxxPactCode helpers (ModifyCanChangeOwner, ModifyWeights, ToggleSwapCapability, ToggleAddLiquidity) + 5 new INFO readers (ChangeOwnership, ModifyCanChangeOwner, ModifyWeights, ToggleSwapCapability, ToggleAddLiquidity) + 4 new UR_* reads (getSwpairOwnerKonto, getSwpairCanChangeOwner, getSwpairCanSwap, getSwpairCanAdd), supporting the OuronetUI v1.0.8 cycle wiring the SWP-pair Liquidity-Pools-Management page buttons. Shipped mid-cycle at 5-of-11 buttons wired (Change Ownership from v1.0.7 + Modify Can Change Owner / Modify Weights / Toggle Swapping / Toggle Provisioning) to validate the cascade on devwallet before the remaining 6 land in v4.2.3. Test count: ~796 specs pass (was 776 in v4.2.1; +20 across the new builders). No signature changes to existing exports — consumers on 4.2.1 continue to work unchanged.
4.2.1 on public npmjs — PATCH (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-16. Pure additive surface: 23 new buildXxxPactCode helpers + 1 INFO reader (getChangeOwnershipInfo) + 1 unprotected read helper (getSwpairOwnerKonto), supporting the OuronetUI v1.0.7 Phase-3b strategy migration cycle (every legacy executeXxx direct-helper caller — 14 modals — migrated onto the canonical useCFMStrategy + buildXxxPactCode pattern). New families: SWP (ChangeOwnership), TS01-C2.LQD (Wrap + Unwrap families with composite-create-account variants), TS01-C1.DALOS (DeployStandardAccount), TS01-C3.SWP liquidity + swap (AddLiquidity, RemoveLiquidity, 4 swap variants), TS02-C1.DPSF + TS02-C2.DPNF (token-set creation), coin.C_URV (Stake / Unstake / Collect), coin.C_UR (4 native UR transfer variants). Test count: 776 specs pass (was 710 in v4.2.0; +66 across the new builders). No signature changes to existing exports — consumers on 4.2.0 continue to work unchanged.
4.2.0 on public npmjs — MINOR (atomic with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-09. Closes 6 audit findings: F-ARCH-001 (Phase 1 dex god-file split — ~10 entity-oriented files + thin re-export shim), F-ARCH-002 (Phase 2 ouro god-file split + chain/UI surgical separation — ~11 entity-oriented files + thin re-export shim), F-ARCH-003 (Phase 3 parameterized liquidity executor — 5 thin wrappers + 1 internal executeLiquidityOp, LOC reduction ~600 → ~200), F-API-002 (Phase 4 — 12 functions honor declared Promise<T | null> contract, return null on RPC failure instead of rethrowing), F-API-018 (Phase 5 readonly sweep — ~50 public-type fields in codex/types.ts and all *Params interfaces), F-TEST-006 (Phase 7 — +127 specs across 6 modules: infoOneFunctions, coilFunctions, kpayFunctions, pensionFunctions, activateFunctions, guardFunctions). NEW deliverable: INTEGRATION-GUIDE.md at repo root — comprehensive cold-start consumer onboarding doc, 13 sections, full v4.0 → v4.1 → v4.2 architectural arc. 8 new v4-2-0-*.test.ts regression-lock files. Test count: 710 specs pass (was ~330 in v4.1.1). Cross-reference: see MIGRATION-v4.2.md at the monorepo root.
v4.3.6 — atomic-triplet alignment bump (atomic with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-06-11. NO code changes; the v4.3.6 change (a stoa-core auto-gas-limit floor fix in calculateAutoGasLimit) lives in @stoachain/stoa-core. Functionally identical to v4.3.5. 829 specs pass.
v4.3.5 — ADDITIVE (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-06-10. Smart Ouronet Account deploy builder (buildDeploySmartAccountPactCode + getDeploySmartAccountInfo/…InfoOnly); keyset-ref-aware activation (mode/keysetRef → (keyset-ref-guard "<ref>")); getIgnisBalance moved to tier T1 (fresh balance read). Pure additive. 829 specs pass.
v4.3.4 — PATCH bugfix (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-06-08. Routes the urstoa-vault-earning-hover { decimal } object through supplyHoverVal instead of String(), re-enabling the Dashboard UrStoa Collect button. 822 specs pass.
v4.3.3 — additive StoicTag + governor-rotation release (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-30. New builders buildRotateGovernorPactCode, buildNonKeyGuardExpr, buildReleaseStoicTagPactCode, buildRegisterStoicTagPactCode; new readers getStoicTagInfo, getStoicTagSelectorData, getRegisterStoicTagInfo; new StoicTagSelectorData type. Bundles the never-published v4.3.2 frozen-keyset fix (resolveGuard / getKadenaAccountGuard shallow-copy). Pure additive — no signature changes to existing exports. 822 specs pass.
v4.3.1 — ESM packaging fix (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-27. Fixes extensionless relative imports in emitted dist/**/*.js that broke await import('@stoachain/ouronet-core/...') under Node 22+ strict ESM. 40 source files updated, 90 imports rewritten. Per TypeScript's recommended .js-suffix-in-source ESM pattern. Peer-deps on @stoachain/kadena-stoic-legacy + @stoachain/stoa-core bumped 4.3.0 → 4.3.1. No API changes; 797/797 specs pass.
v4.3.0 — additive account-rotation release (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-25. 2 new buildXxxPactCode helpers — buildRotateGuardPactCode (emits C_RotateGuard with runtime-conditional guard expression switched by mode: "define" | "existing"; the safe boolean is emitted as a bare Pact literal) and buildRotateKadenaPactCode (emits C_RotateKadena, the kadena-ledger payment-key rotation Pact). Supporting the new sibling package @stoachain/[email protected]'s headless <RotateGuardModal> + <RotatePaymentKeyModal> (<RotateSovereignModal> uses the pre-existing buildRotateSovereignPactCode). Pure additive — no signature changes to existing exports. Test count: 797 (was 788 in v4.2.2; +9 across the new builders). Deferred: buildRotateGovernorPactCode lands when OuronetUI consumes it post-migration.
v4.2.2 — additive SWP-pair management release (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-18. 4 new buildXxxPactCode helpers (ModifyCanChangeOwner, ModifyWeights, ToggleSwapCapability, ToggleAddLiquidity) + 5 new INFO readers + 4 new UR_* reads, supporting the OuronetUI v1.0.8 cycle wiring the SWP-pair Liquidity-Pools-Management page buttons. Shipped mid-cycle at 5-of-11 buttons wired; remaining 6 (Modify Amplifier, Activate Frozen LP, Activate Sleeping LP, Update Special Fee Targets, Update Pending Branding, Upgrade Branding) will land in v4.2.3. Pure additive — no signature changes to existing exports. Test count: ~796 (was 776 in v4.2.1; +20 across the new builders + UR reads).
v4.2.1 — additive strategy-migration release (atomic-triplet with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-16. 23 new buildXxxPactCode helpers + 1 INFO reader + 1 unprotected read helper, supporting the OuronetUI v1.0.7 Phase-3b strategy migration cycle (14 modals migrated off legacy executeXxx direct-helper paths onto useCFMStrategy + buildXxxPactCode). New families: SWP C_ChangeOwnership + getSwpairOwnerKonto; TS01-C2.LQD Wrap{Stoa,UrStoa} + Unwrap{Stoa,UrStoa} (simple + composite-with-create-account variants); TS01-C1.DALOS DeployStandardAccount; TS01-C3.SWP AddLiquidity + RemoveLiquidity + 4 swap variants (single/multi × with/no-slippage); TS02-C1.DPSF + TS02-C2.DPNF CreateSet + CreateSetNFT; coin.C_URV Stake + Unstake + Collect (simple + WithCreateAccount); coin.C_UR NativeUrTransfer / Transmit (+ their Anew variants). Composite-shape builders (Unwrap/Collect/Anew family) require the call site to addData("ks", { keys: [<pub>], pred: "keys-all" }). Pure additive — no signature changes to existing exports. Test count: 776 (was 710 in v4.2.0; +47 from cfm-builders test growth + ~19 from related coverage). All builders fully tested with canonical-shape + argument-ORDER + module/function-name guards.
v4.2.0 — architectural-closures + INTEGRATION-GUIDE deliverable. MINOR (atomic with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-09. Lands the v4.2.0 audit-closures release: 6 audit findings closed in this package — F-ARCH-001 (Phase 1): dex god-file split (~600 LOC interactions/dexFunctions.ts decomposed into ~10 entity-oriented files: dexSwapPairCalcFunctions, dexSwapPairExecFunctions, dexLiquidityCalcFunctions, dexLiquidityExecFunctions, dexFuelCalcFunctions, dexFuelExecFunctions, dexDashboardFunctions, dexAccountSuppliesFunctions, dexCappedInverseFunctions, dexTypes); old import path @stoachain/ouronet-core/interactions/dexFunctions continues to work as thin re-export shim. F-ARCH-002 (Phase 2): ouro god-file split + chain/UI surgical separation (~2200 LOC interactions/ouroFunctions.ts → ~11 entity-oriented files; chain-side and UI-side surfaces cleanly separated per the locked principle); thin re-export shim preserved. F-ARCH-003 (Phase 3): parameterized liquidity executor — executeAddLiquiditySingle, executeAddLiquidity, executeSpecialAddLiquidity, executeFuel, executeRemoveLiquidity consolidated into 5 thin wrappers + 1 internal executeLiquidityOp (LOC reduction ~600 → ~200); public function signatures preserved verbatim — zero consumer impact. F-API-002 (Phase 4): 12 swap-calc and dashboard-read functions whose declared return type was Promise<T | null> now honor that contract — they return null on RPC failure (with logger.error invoked first) instead of rethrowing. Existing try/catch consumer patterns continue to work; new code can rely on the static-type signature with the if (result === null) pattern. Affected: getSWPairDashboardInfo, getPoolPreviewData, getSWPairMultiDashboardInfo, getSwpairInternalDashboard, calculateDirectSwap, calculateInverseSwap, calculateDirectSwapB, calculateInverseSwapB, getCappedInverseAmount, getUserAccountSupplies, plus 2 dashboard-read functions. F-API-018 (Phase 5): aggressive readonly sweep across ~50 public-type fields in codex/types.ts and all *Params interfaces. TypeScript-only signal — no runtime change. Switch in-place mutations to immutable spread copy: const updatedParams = { ...params, account: 'k:...' };. F-TEST-006 (Phase 7): +127 specs across 6 modules (infoOneFunctions / coilFunctions / kpayFunctions / pensionFunctions / activateFunctions / guardFunctions); the audit's stated 37 untested functions corrected to 38 (guardFunctions.describeKeyset was missed by the 2026-05-05 audit; absorbed by Phase 7 as +1 function = +3 it-blocks). NEW deliverable: INTEGRATION-GUIDE.md at repo root — comprehensive cold-start consumer onboarding doc, 13 mandated sections covering the full v4.0 → v4.1 → v4.2 architectural arc (install + peer-deps, the 3-package atomic-release model, subpath imports per package, the 5 typed error classes, the 7-entity Ouronet taxonomy, the 3 pluggable seams setPactReader/KeyResolver+PactClient/BalanceResolver, codex backup format "1.2", smart-account auth, gas calibration, full quick-start example). Doc-validity test (tests/v4-2-0-integration-guide-validity.test.ts) verifies all cited subpaths resolve, all cited error classes import, all cited seam functions are exported. 8 new v4-2-0-*.test.ts regression-lock files in this package. Test count: 710 specs pass (was ~330 in v4.1.1; +127 from Phase 7 + ~250 from Phases 1-5 + 8 regression-lock specs). Cross-reference: MIGRATION-v4.2.md for the v4.1.x → v4.2.0 transition guide, INTEGRATION-GUIDE.md for cold-start onboarding.
4.1.1 on public npmjs — PATCH (atomic with @stoachain/[email protected] + @stoachain/[email protected]). Released 2026-05-08. Closes audit findings: F-ERR-022 (fabricated "0" fallbacks in kadenaFunctions dropped — typed KadenaShapeError thrown instead), F-API-005 (getSublimateInfo dedup with deprecation shim), F-API-006 (describeKeyset dedup), F-API-007 (EncryptedDataV1 collapse), F-SEC-007 (codex strict-shape with CodexUnknownFieldError), F-BUG-010 (migrateSeedType strict throw with UnknownSeedTypeError), F-API-014 (getSparksBalance return type narrowed). New file: src/interactions/errors.ts (KadenaShapeError). No breaking changes — getSublimateInfo deprecation shim preserves backward compatibility. ~330 specs pass.
4.1.0 on public npmjs — MIGRATION (atomic with @stoachain/[email protected] + @stoachain/[email protected]). Retargets all 12 internal @kadena/* imports in src/interactions/ to the new sibling subpaths under @stoachain/kadena-stoic-legacy. Drops the three @kadena/* peer-dep declarations; bumps @stoachain/stoa-core peer-dep 4.0.1 → 4.1.0 (atomic-version invariant); adds @stoachain/kadena-stoic-legacy: "4.1.0". No interactions-surface change for consumers — every Pact.builder call site rewires under the hood. Test count: 261 (was 218; +43 from new tests/v4-1-0-no-kadena-imports.test.ts runtime regression-lock).
4.0.1 on public npmjs — PATCH, cosmetic (published-metadata cleanup). Strips the redundant devDependencies block from package.json. Pre-v4.0.1 the manifest carried @stoachain/stoa-core: "*" (workspace-resolution plumbing — meaningless on a published artifact since the peerDependency already pins @stoachain/[email protected]) plus duplicates of the @kadena/* peer entries. The npmjs.com page now shows the cleaner shape: zero dependencies, just the canonical peerDependencies. Atomic-version invariant: peer-dep on @stoachain/stoa-core bumped from 4.0.0 to 4.0.1 (both packages always release at the same version). NO source-code change. NO behaviour change. 218/218 tests pass.
v4.0.0 — MAJOR, breaking (monorepo split + deprecated-alias removal). v4.0.0 is the structural refactor that v3.3.8 set up. The single @stoachain/ouronet-core package was split into two atomic-release npm packages under the new StoaChain/stoa-js GitHub monorepo: @stoachain/stoa-core (chain-generic foundation) + @stoachain/ouronet-core (Ouronet protocol, this package). Both packages release atomically out of the monorepo at the same version — a single vX.Y.Z git tag publishes both. Removed the v3.3.8-deprecated aliases (KADENA_BASE_URL, PACT_URL, GAS_STATION, NATIVE_TOKEN_VAULT) and the duplicate IKadenaKeypair interface in interactions/ouroFunctions.ts. Consumers using only the Ouronet-specific surface (codex, interactions, the ouronet-ns namespace) can keep this package and bump the version. Consumers using chain-generic surfaces must add @stoachain/stoa-core and update the import paths — see MIGRATION-v4.md at the monorepo root for the full upgrade map. 703/703 tests pass across both packages (485 in stoa-core, 218 in ouronet-core; up from v3.3.8's 698 because the F-ARCH-011/F-ARCH-012 v3.3.8 regression locks now live alongside their stoa-core SUTs — every prior test preserved). Also pinned all @kadena/* + @noble/curves + @scure/bip39 + @stoachain/dalos-crypto peer/dev deps to exact versions (no ^) — prep work for v4.1.0's selective vendoring of @kadena/client (supply-chain hardening after Kadena LLC's dissolution).
v3.3.8 — MINOR, additive
(documentation/deprecation cleanup pass). Closes 5
LOW-severity findings from the 2026-05-05 audit's "v3.x
deprecation cleanup" + "v3.x conventions alignment" + "v3.x
API hygiene" themes in a single bundled release.
F-API-015 rewrote stale strict-parameter JSDoc on
src/dalos/account.ts:42-45 (the parameter never existed in
the CreateAccountOptions type union; new doc explains the
actual mode-vs-primitive throw contract).
F-API-016 added export to the CoilConfig interface in
src/interactions/coilFunctions.ts:17 — consumers holding a
CoilConfig value (e.g. from COIL_CONFIGS.ouroToAuryn)
could USE it but couldn't TYPE-ANNOTATE a parameter or local
with CoilConfig without re-declaring the shape; now they can.
F-SEC-005 / F-ARCH-014 added @deprecated JSDoc to
KADENA_BASE_URL redirecting consumers to the failover-aware
getActivePactUrl(chainId) / getActiveSpvUrl(chainId) (or
the same-subpath thin wrappers getPactUrl(chainId) /
getSpvUrl(chainId)); removal scheduled for v4.0.0. The
constant was pinned to node2.stoachain.com and bypassed the
v2.1.0 failover layer.
F-ARCH-011 consolidated normalizeKeysetRef deep-import
in src/interactions/ouroFunctions.ts:10 to the ../guard
barrel, matching the project's subpath-import discipline.
F-ARCH-012 converted 19 single-quoted string literals to
double quotes in src/dalos/account.ts — the file was the
only remaining drift after v3.1.1's fix to
src/dalos/index.ts. Pure stylistic; TypeScript treats the
two forms as identical string literals at the type level.
NO breaking change, NO observable runtime behavior
change, 698/698 tests pass (was 695 in v3.3.7; +3 from
the new tests/v3-3-8-doc-cleanup.test.ts regression-lock
file). One new public-API export (CoilConfig interface).
3.3.7 — MINOR, additive (security
pass). Closes two MEDIUM security findings from the
2026-05-05 audit in a single bundled release: F-SEC-003
(seam-setter input validation) and F-SEC-004 (V1-fallback
security advisory). F-SEC-003 adds two new typed errors —
InvalidPactReaderError (rejects non-function values passed to
setPactReader) and InvalidLoggerError (rejects null /
undefined / non-object inputs and any object whose warn or
error are non-callable, passed to setLogger). Both extend
TypeError so existing consumer instanceof TypeError catches
are unchanged. Pre-v3.3.7 the misconfigurations only surfaced
later as _reader is not a function / _logger.warn is not a
function at the first call site, far from the boot wiring;
v3.3.7 surfaces them at the boot site. F-SEC-004 wires a
one-shot getLogger().warn(...) security advisory into the
V1-decrypt path (V1 = PBKDF2-SHA256 / 10,000 iterations; OWASP
2023+ recommends 600,000) — fires on the FIRST V1 envelope
decoded per process lifetime, stays silent after that so a
codex with 100 V1 entries logs ONE warning, not 100. Adds two
new public-API rich variants decryptStringV2WithDetails and
smartDecryptWithDetails that return {plaintext, wasLegacyV1}
for the per-call programmatic signal — consumers can react by
re-encrypting affected entries to V2 in-place. JSDoc CVE-style
risk documentation added to EncryptedDataV1,
decryptStringV2, and smartDecrypt. NO breaking change,
695/695 tests pass (was 674 in v3.3.6; +21 from
tests/v3-3-7-seam-validators.test.ts (11) +
tests/v3-3-7-v1-warning.test.ts (10)). v3.3.0 contract test
locking the byte-identical setLogger requires a non-null
Logger message preserved verbatim — the new
InvalidLoggerError extends TypeError to keep that contract
intact.
3.3.6 — MINOR, additive (performance
pass). Closes three MEDIUM performance findings from the
2026-05-05 audit in a single bundled release:
F-PERF-008 — added "sideEffects": false to package.json
(the audit's "single most impactful tree-shaking fix"; lets
downstream bundlers prune unused barrel imports from the
16-subpath exports map; verified safe via top-level-mutation
grep across src/);
F-PERF-003 — memoized 8 RegExp allocations per call in
coilFunctions.getCoilPreviewGeneric to a per-targetTokenName
Map<string, CoilPatternSet> cache (the audit's literal
suggested fix "hoist to module-level const" doesn't apply
because patterns interpolate targetTokenName from config,
but the cache form achieves the same outcome — steady-state
allocation cost is 0 RegExp objects per call after warm-up);
F-PERF-004 — parallelized ouroFunctions.getOuronetKdaDetails
from sequential await getKadenaAccountOwner() →
await getKadenaAccountGuard() to a single
Promise.all([owner, guard]) (verified independent: probes
DALOS.UR_AccountKadena vs DALOS.UR_AccountGuard with no
causal dependency; halves happy-path latency from 2 sequential
RPC roundtrips to 1 parallel roundtrip).
All three are low-risk, behaviorally identical to v3.3.5.
Consumer-side impact: smaller OuronetUI bundle sizes (F-PERF-008,
exact savings bundler-config-dependent); faster
getOuronetKdaDetails (F-PERF-004, ~half wall-clock); no
observable difference for getCoilPreviewGeneric (F-PERF-003,
internal-only). NO public API change, 674/674 tests pass
(was 672 in v3.3.5; +2 from the new
tests/v3-3-6-perf-pass.test.ts regression-lock file). Locks
both F-PERF-008 (expect(pkg.sideEffects).toBe(false) strict
equality) and F-PERF-004 (counting reader proves both
UR_AccountKadena AND UR_AccountGuard reads still happen,
catching a regression that accidentally drops one of the reads).
3.3.5 — MINOR, additive (test-only).
Closes audit finding F-TEST-006 (MEDIUM, testing-auditor) —
six interaction modules previously had insufficient runtime
coverage: three with zero runtime tests at all
(pensionFunctions, guardFunctions, infoOneFunctions) and
three with compile-only tests (coilFunctions,
kpayFunctions, activateFunctions are all type-checked at
tests/types.test.ts:44-47 via expectTypeOf, but the functions
never actually execute in the test suite). Compile-only tests
prove the type signature matches consumer expectations but do
NOT prove the function executes correctly — a bug that swapped
two argument-string concatenations, forgot to await a Promise,
or mis-routed the pactRead call would all type-check cleanly
while producing wrong runtime behaviour. v3.3.5 closes the gap
with tests/v3-3-5-smoke.test.ts — 12 new it-blocks across 6
describe groups, one happy-path + one error-path test per
module, picking the simplest representative read-only function
from each: pensionFunctions.getHibernateFee (the ONLY of the 6
with a non-null error path — graceful-degradation fallback
formula 0.12 - 0.000008 * lockDays clamped non-negative);
guardFunctions.getRotateGuardInfo;
infoOneFunctions.getCoilPreviewInfo (locks the
{result: ...} envelope wrap contract);
coilFunctions.getCoilPreviewGeneric (the ONLY of the 6 that
rethrows rather than returning null/fallback — locks the
rethrow contract that consumers depend on for try/catch flow);
kpayFunctions.getKpayData;
activateFunctions.getDeployStandardAccountInfoOnly. Strategy
mirrors v3.3.4: install a stubbed reader via setPactReader(...),
call SUT, assert. NO source-code change, NO public API
change, 672/672 tests pass (was 660 in v3.3.4; +12 from
the new test file). With v3.3.5 the v3.3.x audit-closure track
is COMPLETE — all MEDIUM testing findings from the 2026-05-05
audit are now closed (F-LOGGER-SEAM-001 → v3.3.0; F-TEST-002 →
v3.3.2; F-TEST-005 → v3.3.4; F-TEST-006 → v3.3.5).
3.3.4 — MINOR, additive (test-only).
Closes audit finding F-TEST-005 (MEDIUM, testing-auditor) —
the v3.0.0 nullable-widening sweep widened 16 read-side
interaction functions from Promise<T> → Promise<T | null>,
but only 3 of the 16 had a paired success-path test
(getStoaPriceUSD at tests/interactions-pricing.test.ts:80,
getLPTypeInfo's mixed-state lock at
interactions-balance-cluster.test.ts:137, and
getUrStoaGuard's 3-state contract at the same file:207). The
other 13 could not distinguish "always returns null" (silent
regression) from "returns null only on RPC failure" (correct
contract) — a future bug that returned null unconditionally
would slip past every existing test, surface only at consumer
runtime, and be caught only by chain-side breakage. v3.3.4
closes the gap with tests/v3-3-4-success-paths.test.ts —
13 new it-blocks across 6 describe groups, one per missing
function, each installing a successReader stub via
setPactReader(...) and asserting the parsed non-null return
value. The 13 functions: getTokenDecimals, getPoolTotalFee,
getDPTFMinMove (pricing-quartet missing 3); getIgnisBalance,
getAccountTokenSupply, getOuroDispoCapacity, getVirtualOuro
(string-balance cluster — none previously covered);
getUrStoaBalance and checkCoinAccountExists (urStoa pair);
validateLiquidity (mixed-shape success — locks the
valid:true ↔ error:undefined mutual exclusion that
distinguishes a successful liquidity check from an RPC-failure
one); getMaxBuyMovieBooster (locks Number.isFinite guard
against v2.x fabricated-0); getSWPSpawnLimit and
getSWPInactiveLimit (magic-string elimination — also asserts
expect(out).not.toBe("N/A") so the v3.0.0 BREAKING swap
cannot regress unnoticed). NO source-code change, NO
public API change, 660/660 tests pass (was 647 in v3.3.3;
+13 from the new test file).
3.3.3 — MINOR, additive (NEW PUBLIC
SURFACE — not a bug fix). Ships the multi-party
partial-signature workflow OuronetUI has been blocked on:
"Person A signs → exports → Person B imports → signs → exports →
Person C imports → signs → submits", with cross-party tamper
detection at every handoff. Builds on v3.3.2's locked
partial-signing primitive (signing with a subset of declared
signers fills only those slots; pre-existing slots stay intact
across re-signing passes) by wrapping it in a versioned export
envelope + slot-status helpers + Ed25519 sig-verification helper.
New src/signing/partialSig.ts module re-exported from
@stoachain/ouronet-core/signing, exposing 7 functions
(signPartial, serializePartialTransaction,
deserializePartialTransaction, getMissingSigners,
getFilledSigners, isFullySigned, verifyExistingSignatures)
- 2 typed errors (
InvalidEnvelopeError,TamperedHashError) + thePartialSigEnvelopeinterface. The envelope embeds bothcmdandhashso importers can verify integrity; if the cmd was tampered mid-flight,deserializePartialTransactionrejects withTamperedHashErrorcarrying bothexpectedandactualfor operator diagnosability. As a second layer,verifyExistingSignaturesrunsnacl.sign.detached.verifyon every filled slot — works for both nacl-direct (koala/foreign) and BIP32-WASM (chainweaver/eckowallet) sigs since both produce standard Ed25519 over the same canonical hash bytes. NO existing API changed, NO source-side behaviour change outside the new module, 647/647 tests pass (was 631 in v3.3.2; +16 from the newtests/partial-sig.test.ts).
3.3.2 — MINOR, additive (test-only).
Closes audit finding F-TEST-002 (HIGH) — the central signing
entry point universalSignTransaction in
src/signing/universalSign.ts had ZERO direct tests pre-v3.3.2.
The only mention in tests/ was a comment in
tests/signing.test.ts:5 stating "the full
universalSignTransaction is not exercised here";
tests/strategy.test.ts exercises a higher-level wrapper but only
covers seedType: "koala". The chainweaver / eckowallet / foreign
branches AND the seedType dispatcher itself were never
runtime-tested — a regression that mis-routed eckowallet →
koala (or any other dispatch error) would silently produce
wrong-shape signatures, surfaced only by chain-side "invalid
signature" rejection at consumer runtime. v3.3.2 adds
tests/universal-sign.test.ts with 9 new it-blocks covering
all three seedType branches with real-keypair round-trips
(koala via RFC-8032 vector, chainweaver/eckowallet via the
@kadena/hd-wallet vendor vector through
KadenaWalletBuilder.createWalletPairFromMnemonic), the
foreign-key onMissingKey callback (success and key-mismatch
error cases), the multi-signer mixed-seedType case, the
partial-signing primitive (foundation lock for v3.3.3's
multi-party signing public surface), and the
silent-skip-when-not-in-signers contract. NO source-code
change, NO public API change, 631/631 tests pass (was
622 in v3.3.1; +9 from the new test file).
3.3.1 — PATCH, workflow-only. Closes the
two carried-forward follow-ups that have appeared in every
pollinate run's "follow-ups" block since v3.0.0: (1) npm publish
now passes --provenance (and the workflow gains id-token:
write permission), so v3.3.1 onwards every release carries a
verifiable SLSA attestation linking the published tarball to the
exact GitHub Action run that produced it; (2) the gh release
create calls drop the --repo flag, eliminating the
gh release create --notes-from-tag --repo X flag-combination
incompatibility that the GitHub-hosted runners' gh-CLI image
rejected starting around 2026-04-30 (every v3.x release pre-v3.3.1
needed pollinate's REST-API fallback at Step 9c to create the
GitHub Release manually). Both fixes are workflow-file-only —
.github/workflows/publish.yml is the only file with a behaviour
change. NO source-code change, NO public API change,
622/622 tests pass unchanged. Consumers see byte-identical
package contents to v3.3.0; the difference is the v3.3.1
attestation badge on npmjs.com and a green-check on the GitHub
Action run page (vs the recurring red-X for the gh-CLI Release
step that every v3.x release pre-v3.3.1 produced).
3.3.0 — MINOR, additive (Logger interface
extension) + behaviour change (call-site routing) — first release
in the v3.3.x line. Closes the consolidated F-LOGGER-SEAM-001
finding flagged by all 8 audit agents at 9 distinct source sites
(highest-redundancy finding in the entire 2026-05-05 audit). Two
of the nine sites were already removed by v3.2.2's deletion of
executeAddLiquidityMultiStepComplete; v3.3.0 closes the remaining
seven by extending the Logger interface from {warn, error} to
{warn, error, info} and routing every surviving raw console.*
call in src/ through the seam (or deleting debug-leak
instrumentation that had no operational value). Post-v3.3.0
invariant: zero raw console.* call sites in src/ outside
the seam's own default-logger implementation, verified by a new
regression-lock test that scans the entire src/ tree on every run.
Backwards-compat: v3.2.x consumers wiring
setLogger({warn, error}) continue to work — the setter synthesises
an info wrapper that falls through to console.info for the new
channel; consumers that want full control pass
setLogger({warn, error, info}). 622/622 tests pass.
3.2.3 — MINOR, behaviour change — fourth
and final wave of the v3.2.x audit-cycle close-out track. Four
targeted bug fixes closing the highest-user-impact remaining
findings: F-BUG-002 (added creationTime: safeCreationTime()
to buildCrossChainTransfer setMeta block — the lone interactions
builder that omitted the helper after v2.3.0's sweep, causing
sporadic chain-side rejections under client clock drift); F-BUG-004
(rewrote fetchSpvProof to wrap in withFailover + add
AbortSignal.timeout(30s) per-attempt deadline — pre-v3.2.3 a
wedged primary node would hang the function indefinitely with the
user's KDA committed to kadena-xchain-gas escrow and no recovery
path, identified as the highest-impact bug in the entire audit);
F-SEC-002 (added URL parse + https: scheme allow-list to
setNodeConfig("custom", customUrl) — pre-v3.2.3 it accepted any
truthy string and assigned it to PRIMARY_HOST, allowing an
attacker-controlled custom-node setting to redirect every signed
transaction); and F-ERR-001 (added @throws JSDoc to
submitCrossChainTransfer, submitContinuation, and
listenForCompletion, documenting the
TIMEOUT-as-pending-not-failed contract that prevents user
double-pay on listen timeouts). With these four findings closed,
the v3.2.x sequence has remediated 15 of the audit's 62
confirmed findings across four ship cycles. 618/618 tests pass
(was 601 in v3.2.2; +17 new it-blocks). Next: v3.3.x for
logger-seam completion + test coverage; v4.0.0 for structural
decomposition + monorepo split + type consolidation.
3.2.2 — MINOR, public API removal —
third wave of the v3.2.x audit-cycle close-out track. Removes the
four executeAddLiquidityMultiStep* functions plus the
MultiStepAddLiquidityResult type from
src/interactions/addLiquidityFunctions.ts, along with the
unused _strategy parameter on executeAddLiquidity. Closes audit
findings F-ERR-005 (error.message.includes retry-loop crash on
non-Error throws), F-ERR-014 (listen-timeout vs submit-failure
conflation causing user double-pay risk), F-PERF-014 (4×
hardcoded 3-second sleeps adding ~6s wall-clock latency to every
successful flow), F-PERF-015 (retry-with-fixed-sleep against
string-matched error.message.includes("Cannot find module")
patterns), and F-API-026 (the always-"auto" _strategy
parameter on executeAddLiquidity was dead public surface). All
five findings closed by removal rather than fix — the
multi-step pipeline existed because the historical Kadena chainweb
gas limit (150k per block) couldn't fit a single-block
add-liquidity transaction; StoaChain's 2M-per-block chainweb fits
the entire flow in one transaction, so multi-step has been dead
code in OuronetUI since the gas-limit increase. Net code change:
−338 lines (1031 → 693 lines in addLiquidityFunctions.ts).
601/601 tests pass unchanged; no test exercised the removed
functions, which was itself a v3.2.x audit signal that the surface
was unused. The Pact-side multi-step contract
(TS01-CP.SWP|C_AddStandardLiquidity defpact) is still on chain
for historical interoperability — this package just stops exposing
the TypeScript wrappers around it. Strict-semver-wise this is a
breaking change requiring a MAJOR bump; classified MINOR for v3.2.2
because the removed functions had no known consumer (verified via
repo-wide grep + user confirmation that OuronetUI no longer uses
multi-step). v3.2.3 will land the targeted bug fixes
(creationTime, fetchSpvProof failover, setNodeConfig URL
validation).
3.2.1 — MINOR, behaviour change —
second wave of the v3.2.x audit-cycle close-out track. Puts the
v3.2.0 number-hygiene helpers (formatDecimalForPact,
formatIntegerForPact, ValidatedDecimal / ValidatedInteger
brand types) to work at the four chain-call sites the 2026-05-05
audit flagged: buildCrossChainTransfer (crossChainFunctions:92),
executeNativeUrStoaTransfer (urStoaFunctions:206),
executeStakeUrStoa (urStoaFunctions:441), and
executeUnstakeUrStoa (urStoaFunctions:497). Closes audit
findings F-SEC-001 (Pact-code injection via raw ${amount}
interpolation in urStoa stake/unstake) and F-BUG-003
(parseFloat(amount).toFixed(N) silent precision loss + silent
rounding). All four sites now route through the validated
formatter: malformed input throws synchronously before any chain
interaction begins; arbitrary-precision decimals (e.g., 39-digit
integer amounts that would overflow float64) round-trip
byte-identical; EU-locale comma input ("1,5") is normalised to
period; and the urStoa stake/unstake cap-arg now reuses the
validated string so pact-code and cap-arg are guaranteed to agree.
The numAmount field on StakeUrStoaParams / UnstakeUrStoaParams
is deprecated (still accepted, no longer read; will be removed in
v4.0.0). 601/601 tests pass. v3.2.2 will remove the dead
multi-step add-liquidity surface; v3.2.3 will land the targeted
bug fixes (creationTime, fetchSpvProof failover,
setNodeConfig URL validation).
3.2.0 — MINOR, additive release that opened
the v3.2.x audit-cycle close-out track with number-hygiene
infrastructure for Pact-bound integers and decimals.
formatDecimalForPact now accepts a single comma as decimal
separator (so European-locale UI text fields work without upstream
normalisation); a new sibling formatIntegerForPact(amount: string):
ValidatedInteger validates integer-typed Pact arguments without ever
round-tripping through float64 (arbitrary-precision-safe — a
100-digit integer string passes through byte-identical); two new
branded TypeScript types (ValidatedDecimal, ValidatedInteger)
prove "this string passed the formatter" at the type level so
downstream call sites get compile-time guarantees that consumer
input has been validated before it reaches Pact-code interpolation.
No consumer-visible behaviour changes — every previously-valid
input continues to produce byte-identical output. 593/593 tests
pass (was 565 in v3.1.1; +28 covering comma-normalisation,
arbitrary-precision round-trips with the explicit
truncation-at-maxDecimals lock, the new integer formatter, and the
brand-type compile contract). v3.2.1 will apply the new helpers at
the existing parseFloat(...).toFixed(N) call sites to close the
F-SEC-001 / F-BUG-003 precision-loss vectors; v3.2.2 will remove
the dead multi-step add-liquidity surface (chainweb's gas bump made
it obsolete); v3.2.3 will land the targeted bug fixes
(creationTime, fetchSpvProof failover, setNodeConfig URL
validation).
3.1.1 — PATCH, additive release that closed the
audit-cycle gaps identified by the post-v3.1.0-integration audit
(see CHANGELOG.md v3.1.1 entry for the full
per-finding trace). Three additive re-exports completed the
./dalos integration surface (InvalidBitStringError,
InvalidBitmapError, InvalidPrivateKeyError for typed
validation-failure discrimination + CoordAffine companion type
for SchnorrSignature); the src/dalos/ subdirectory was
realigned with CONVENTIONS.md (double-quoted imports, no .js
extensions); the v3.1.0 locale-determinism test assertion in
tests/gas.test.ts was tightened to strict equality (was a
substring regex that wouldn't detect a regression on a US-locale
CI host); a fresh tests/dalos-integration.test.ts block covered
the v3.1.0 Schnorr re-exports end-to-end. No runtime change for
any v3.1.0 consumer; v3.1.0 itself was committed locally
(bf10dc1) but never pushed to npm — the npm registry skips from
3.0.0 to 3.1.1.
3.1.0 (committed locally bf10dc1, never published) — MINOR,
additive release that upgrades @stoachain/dalos-crypto from
^1.2.0 to ^4.0.3 (covering
the v2.x/v3.x/v4.x line of the upstream package — Schnorr v2 wire
format, cofactor subgroup-membership hardening, generator-precompute
matrix cache, async signing surfaces, the v4.0.0 Elliptic-package
carve-out on the Go side, and the v4.0.3 LOW-band closures), exposes
the previously-internal Schnorr signature surface through the
./dalos subpath (schnorrSign / schnorrVerify and the browser-
friendly schnorrSignAsync / schnorrVerifyAsync async variants
that yield to the event loop on a fixed cadence; plus the typed
SchnorrSignError exception and the SchnorrSignature shape type),
and ships a small locale-determinism fix in formatMaxFee so the
ANU thousands separator is , on every host (was host-locale-
dependent — silently passed CI on en-US Linux while failing locally
on a German-locale host). 558/558 tests pass. No public surface
from prior versions changes shape; all additions are opt-in. Per
the upstream v4.0.0 changelog: TypeScript consumers see no breaking
surface changes across the dalos-crypto v1.2.0 → v4.0.3 jump (the
v4.0.0 major bump was driven entirely by a Go-reference
reorganisation that doesn't affect TS consumers). See
CHANGELOG.md for the full v3.1.0 entry.
3.0.0 — BREAKING major release closing M3 from the
2026-04-30 audit cycle (F-CORE-007 fabricated-fallback removal +
comprehensive HIGH-risk catalog sweep). This was the FIRST major
bump since v2.0.0 (2026-05-01) — downstream consumers
(OuronetUI, AncientHolder HUB) MUST update call sites to handle
null returns. 16 fabricated-fallback widenings land across 4
interaction files: 15 functions widen from Promise<T> to
Promise<T | null> so that consumers see RPC failures instead of
fabricated chain values (1.0 USD prices, "0" balances, sentinel
"N/A" strings, fake false existence flags), plus 1 mixed-shape
addition for validateLiquidity (preserves valid: boolean while
adding optional error?: string to distinguish RPC failure from
validation rejection). In lockstep, 14 NON-BREAKING logger-routing
additions across 5 files complete the silent-catch-elimination
sweep started in v2.3.0 — every previously-silent diagnostic catch
in src/interactions/* now routes through the
@stoachain/ouronet-core/observability getLogger().error() seam.
NO public-API removals (NFR-03): all 16 modified functions retain
their names and parameter signatures; only return types widen. See
CHANGELOG.md for the full v3.0.0 entry, and the
Migrating to v3.x H2 section below for per-cluster Before: /
After: migration patterns (Option B null-pattern locked decision
per Q3..Q11 of the requirements). The optional What's new in
v3.0.0 section ships a copy-paste example for adapting to nullable
returns.
Every piece of blockchain logic that used to live in OuronetUI has landed here: Pact builders, signing pipeline (CodexSigningStrategy + universalSignTransaction), encryption (V1 + V2 + smartDecrypt), guard analysis, gas calibration, codex codec, seed-type migration. OuronetUI is now a pure consumer.
As of the current v3.1.0 shipping line (originally introduced in
v1.3.0, dep range bumped to ^4.0.3 in v3.1.0), OuronetCore
integrates
@stoachain/dalos-crypto@^4.0.3
via the ./dalos subpath — consumers mint Ouronet accounts locally
(all six DALOS input modes: random, bitmap, bitstring, base-10,
base-49, seed words) without touching the retired
go.ouronetwork.io/api/generate endpoint. As of v3.1.0 the ./dalos
subpath also re-exports the lower-level Schnorr signature surface
(schnorrSign, schnorrVerify, plus browser-friendly
schnorrSignAsync / schnorrVerifyAsync variants, the typed
SchnorrSignError exception, and the SchnorrSignature shape type)
for advanced consumers who need direct access without going through
primitive.sign(...).
The per-version paragraphs below are compact deltas; for the full
authoritative per-version detail (Added / Changed / Fixed sections,
finding closures, file-level citations) see
CHANGELOG.md. The README mirrors the headline only
and points readers at the changelog for the rest.
v1.4.0 — AccountSelectorData now includes public-key,
sovereign, and governor for Smart Ouronet Account display (Σ.
prefix accounts with sovereign + governor authorisation paths).
v1.5.0 — re-exports Leto / Artemis / Apollo historical-curve
primitives + createGen1Primitive factory through the ./dalos
subpath. NOT registered in createDefaultRegistry() — Ouronet stays
Genesis-only; consumers opt in.
v1.6.0 — Smart Ouronet Account auth-path primitives. /guard
gains classifyGuardKind, extractKeysetFromGuard,
analyzeSmartAccountAuthPaths to discriminate the four guard shapes
and resolve the enforce-one over (account guard / sovereign /
governor). buildRotateSovereignPactCode is the first CFM function
targeting a Smart account's auth path.
v1.6.1 — every internal interactions/* helper now honors the
active failover node (no more createClient(PACT_URL) pinned to
node2).
v1.7.0 — IKadenaKeypair consolidated to a single canonical
declaration in src/signing/types.ts. The duplicate copies that lived
across interactions/* are replaced with import type re-exports.
Closes audit finding F-CORE-001 (CRITICAL).
v2.0.0 — wallet subpath layering restored + pactRead injection
seam fully adopted. Closes F-CORE-005 + F-CORE-006 (HIGH). Two
breaking changes for consumers — see migration guide below.
v2.0.1 — documentation/release-process patch. Adds CHANGELOG.md
to the npm tarball, auto-creates GitHub Releases on tag push, and
backfills Releases for v1.7.0 and v2.0.0. No runtime change.
v2.0.2 / v2.0.3 / v2.0.4 — release-pipeline hardening patches. No
runtime change. v2.0.2 added permissions: contents: write to
publish.yml for the GitHub Releases step. v2.0.3 introduced a
RELEASE_TOKEN PAT fallback expression to bypass org-locked
GITHUB_TOKEN write permissions. v2.0.4 triggered the workflow with
the secret installed.
v2.1.0 — reliability hardening release. New getFailoverClient(chainId, options?)
factory composes withFailover + per-tier timeout into one reusable
surface; all 81 legacy createClient(getPactUrl(chainId)) invocations
across the 11 interaction files now route through it (primary node
failure on any chain call now triggers automatic fallback retry).
Bounded timeouts on every chain-call tier (read 15s, submit 60s,
listen 180s, pollOne 30s) with Promise.race + AbortController
defence-in-depth. New runWithTimeout(operation, fn, timeoutMs)
helper, new createTimeoutError(...) factory returning a
SigningError { code: "TIMEOUT" }, new resetNodeFailover() export
for test isolation, new readTimeoutMs?: number option on
PactReader and rawCalibratedDirtyRead. MINOR, non-breaking —
existing imports continue to work; the new surface is opt-in.
v2.1.2 — concurrency-race correction in withFailover. PATCH, no
public API change. The retry guard now uses per-invocation captured
base URLs (attemptedBaseUrl AND attemptedPrimaryBaseUrl captured
at fn-entry as local consts) instead of reading the shared
module-level currentHost === PRIMARY_HOST at catch-time. This makes
the catch-block decision robust to concurrent module-state mutation
(sibling withFailover flip, mid-flight setNodeConfig, mid-flight
resetNodeFailover). Closes F-BUG-001. New module-private
getPrimaryBaseUrl() helper added to src/network/nodeFailover.ts;
not exported.
v2.2.0 — crypto error-taxonomy + test-coverage hardening release.
MINOR, additive. The ./crypto subpath gains three typed error
classes — WrongPasswordError, CorruptEnvelopeError,
UnsupportedFormatError — that discriminate decryption failure modes
(closes F-CORE-009). smartDecrypt switches to single-path dispatch
via the existing isEncryptedV2 shape predicate, eliminating the
~1.5s wall-time differential a wrong-password V1 input previously
exhibited (timing-leak fix); the V1 catch path no longer logs to
console.error and propagates the original failure via ES2022
Error.cause. Existing instanceof Error checks and error.message
access continue to work — the new typed-class discrimination is
opt-in. Test coverage expands across 4 previously-untested critical
surfaces (closes F-CORE-011, F-CORE-012): four new test files cover
the pactReader injection seam (tests/pact-reader.test.ts),
KadenaWalletBuilder mnemonic dispatch with vendor-vector pinning for
all three seed types (tests/wallet-builder.test.ts), every
documented branch of createSigningError + createSimulationError
(tests/transaction-errors.test.ts), and the codex seed-type
migration round-trip (tests/seed-type-migration.test.ts). Five
existing test files gain extensions: tests/encryption.test.ts,
tests/encryption-upgrade.test.ts, tests/codex-codec.test.ts,
tests/cfm-builders.test.ts, tests/pact-format.test.ts. F-CORE-010
(a proposed pactString charset/blocklist helper) was reviewed and
explicitly rejected — chain-side Pact validation already enforces
identifier rules, so a client-side blocklist would duplicate
authoritative server-side checks and risk silent drift if Pact's
grammar evolves. The decision is logged in CHANGELOG.md under a
### Rejected (decisions log) section.
v2.3.0 — medium-and-low audit closures release. MINOR, additive.
Closes 13 audit findings grouped into two milestones: M1 — 7
MEDIUM tier (F-CORE-013 codex shape validation; F-CORE-014
foreign-key resolver pre-flight in CodexSigningStrategy; F-CORE-015
safeCreationTime DRY refactor — 11 inline copies removed across
src/interactions/*Functions.ts, all routed through the canonical
declaration in src/pact/format.ts; F-CORE-016a tightened
classifyGuardKind requiring full minimal shape per kind; F-CORE-016b
new normalizeKeysetRef helper at the resolveGuard boundary;
F-CORE-016c SmartAccountAuthPathsAnalysis JSDoc enumerating 4
reachable states + optional firstSignableButUnsatisfied field;
F-CORE-017 typed UnknownPredicateError class re-exported from
./guard plus predicateRecognized: false bit on analyzeGuard's
returned analysis, replacing the previous silent console.warn
diagnostic) and M2 — 6 LOW tier (F-CORE-018a README header
version table refresh; F-CORE-018b CONTEXT.md interactions section
refresh covering v1.4 / v1.5 / v1.6 additions; F-CORE-019 catch-block
consistency in ouroFunctions.ts — all 7 affected catch sites now
route via getLogger().error(...) from ../observability; F-CORE-020
tier-semantics JSDoc on pactReader.ts and rawCalibratedRead.ts
enumerating the canonical T1=balance / T2=preview / T3=metadata /
T7=very-static mapping; F-CORE-021 dead try/catch wrapping
getLPTypeInfo's Promise.all removed (Option A — the
"comment as belt-and-braces" alternative was explicitly rejected);
F-CORE-022 central logger seam at ./observability with two-file
source layout src/observability/{index.ts,logger.ts}, Logger type
setLogger(throwsTypeError("setLogger requires a non-null Logger")on null/undefined input) +getLoggerexports, and a sweep that reroutes everyconsole.warn/console.errorinsrc/through the seam — verified bygrep -nE "console\.(warn|error)" src/returning ZERO matches outside the seam itself). Two new public surfaces ship in lockstep:UnknownPredicateErroron./guardand the./observabilitysubpath. All changes additive; no existing exports change shape.
v3.0.0 — fabricated-fallbacks-removal release. BREAKING.
Closes M3 from the 2026-04-30 audit cycle (lead finding F-CORE-007
HIGH plus the comprehensive ~24-site catalog sweep). First major
bump since v2.0.0. Phase 1 — critical pricing functions (4
BREAKING widenings): getStoaPriceUSD, getTokenDecimals,
getPoolTotalFee, getDPTFMinMove all widen from Promise<number>
to Promise<number | null>; the previous 1.0 / 0 / 8
fabrication sentinels are replaced with null, and
Number.isFinite() guards catch NaN from malformed chain data
(e.g. parseInt("abc", 10) or parseFloat(String(undefined))).
Phase 2 — catalog sweep + bonus extras + magic-strings (12
BREAKING widenings): the 4-function string-balance cluster
(getIgnisBalance, getAccountTokenSupply, getOuroDispoCapacity,
getVirtualOuro) widens uniformly to Promise<string | null>;
LPTypeInfo field types widen to boolean | null per inner flag
(Approach A — function return type unchanged; chain-failure-status
returns false, catch returns null, success returns true); the
urStoa trio (getUrStoaBalance, getUrStoaGuard,
checkCoinAccountExists) widens to nullable returns and
getUrStoaGuard drops its sentinel empty shape; validateLiquidity
gains an optional error?: string field on its mixed shape (preserves
valid: boolean — consumers route a populated error to the
network-failure banner and a valid: false with no error to the
validation-failure message); getMaxBuyMovieBooster widens to
Promise<number | null>; magic-string sentinels disappear from
getSWPSpawnLimit and getSWPInactiveLimit (now Promise<string |
null> — consumers swap === "N/A" for === null). Phase 3 —
logger parity (14 NON-BREAKING): getLogger().error("Error in
<funcName>:", error) routing lands in 14 previously-silent catches
across 5 files (dexFunctions.ts, ouroFunctions.ts,
activateFunctions.ts, infoOneFunctions.ts, and the
urStoaFunctions.ts private helpers verifyEd25519Sig +
describeKeyset) — completes the silent-catch elimination sweep
started in v2.3.0. NO public-API removals (NFR-03): all 16 modified
functions keep their names + parameter signatures; only return types
widen. See the new Migrating to v3.x H2 section below for
per-cluster Before: / After: migration patterns and the locked
Option B / Approach A / mixed-shape / 3-state-preservation /
magic-string-removal decisions (Q3..Q11) embedded verbatim.
v3.1.0 — dalos-crypto v4.0.3 integration + Schnorr surface
re-exports + locale-determinism fix. MINOR, additive. Bumps the
@stoachain/dalos-crypto dep from ^1.2.0 to ^4.0.3 (per the
upstream v4.0.0 changelog: TypeScript consumers see no breaking
surface changes across the v1.2.0 → v4.0.3 jump — the v4.0.0 major
bump was driven entirely by a Go-reference reorganisation, not the
TS port). The ./dalos subpath gains direct re-exports of the
Schnorr signature surface for advanced consumers:
schnorrSign / schnorrVerify for synchronous use; the
browser-friendly schnorrSignAsync / schnorrVerifyAsync async
variants that yield to the event loop on a fixed data-independent
cadence (the upstream package's REQ-14 yield-count constant-time
test verifies the cadence is data-independent and constant-time);
the typed SchnorrSignError exception class for instanceof catch
blocks; and the SchnorrSignature shape type for parameter typing.
The high-level primitive.sign(keyPair, message) path through the
registry is unchanged (it has always been Schnorr internally for
DalosGenesis); the new direct-access surface is opt-in and exists
mainly so OuronetUI's browser path can use the *Async variants to
keep INP under the 200 ms budget during signing. Also fixes
formatMaxFee in ./gas to pin its toLocaleString() call to
'en-US' so the ANU thousands separator is , on every host (was
host-locale-dependent — silently passed CI on en-US Linux while
failing locally on a German-locale host); the test suite was already
pinning the en-US shape, so this restores cross-host parity. NO
public-API removals or shape changes; all changes additive. See the
v3.1.0 CHANGELOG.md entry for the full per-symbol export list,
the audit-trail of the 18 dalos-crypto symbols verified
shape-compatible at upgrade time, and the verification-gate results
(typecheck + 558/558 tests + build all green).
v3.1.1 — pre-publish audit-cycle close-out for the v3.1.0
dalos-crypto integration. PATCH, additive. Closes 5 audit
findings the post-v3.1.0-integration audit (2026-05-05) flagged
against commit bf10dc1 before that commit reached npm: 3 typed
validation-error class re-exports added to ./dalos
(InvalidBitStringError, InvalidBitmapError,
InvalidPrivateKeyError — close F-BUG-005 by completing the
instanceof-discrimination surface); 1 type-only re-export added
(CoordAffine — closes F-API-024 by restoring the "single
integration surface" promise for SchnorrSignature.r); 1
stylistic alignment (src/dalos/{index,account}.ts converted
from single quotes + .js extensions to the codebase's standard
double quotes + bare relative imports — closes F-ARCH-012); 1
test-strictness fix (tests/gas.test.ts formatMaxFee assertion
tightened from toMatch(/10,000,000/) substring regex to strict
toBe("10,000,000") — closes F-TEST-001 so the v3.1.0
locale-determinism contract is actually locked); and 1 fresh
test block (tests/dalos-integration.test.ts gains coverage for
the v3.1.0 Schnorr re-exports — closes F-TEST-004 with 5
new it-blocks covering sign/verify round-trip, async variants,
SchnorrSignError class identity, and SchnorrSignature /
CoordAffine type-import compile probes). v3.1.0 was committed
locally (bf10dc1) but never pushed to npm, so the npm registry
goes from 3.0.0 straight to 3.1.1 with v3.1.0 visible only in
the GitHub commit history. 565/565 tests pass (was 558 in
v3.1.0; +7 = 1 new strict locale grouping-style sibling
assertion + 5 new Schnorr re-export it-blocks + 1 new
validation-error class probe).
v3.2.0 — number-hygiene infrastructure for the v3.2.x
audit-cycle close-out track. MINOR, additive. First wave of the
v3.2.x sequence (v3.2.0 = infrastructure / v3.2.1 = apply at call
sites / v3.2.2 = delete dead multi-step add liquidity / v3.2.3 =
targeted bug fixes). v3.2.0 lands three additive surfaces in the
./pact subpath: (1) formatDecimalForPact now accepts a single
comma as decimal separator and normalises it to a period before
validation, so European-locale UI inputs ("1,5", "0,9",
"1234,567890") work without upstream normalisation; multi-comma
strings ("1,234,567" thousand-separator-style) and mixed
period+comma strings ("1,5.6", "1.234,56") still throw because
they are ambiguous. (2) New formatIntegerForPact(amount: string):
ValidatedInteger sibling helper for integer-typed Pact arguments
— Pact distinguishes integers from decimals at the lexer level
(integer cap-args reject 1.0, accept 1); the new helper
validates ^\d+$ and returns the trimmed input verbatim with no
float round-trip, so 100-digit integer strings round-trip
byte-identical (versus Number(big) which collapses past
Number.MAX_SAFE_INTEGER ≈ 9.0e15). (3) Two new branded
TypeScript types ValidatedDecimal and ValidatedInteger (zero
runtime cost — just unique symbol brands on string) flow out
of the formatters; functions declared (amount: ValidatedDecimal)
=> Transaction cannot accidentally accept raw user input, and the
two brands are distinct types so the lexer-level int-vs-decimal
distinction is enforced at the function-boundary level. The
file-level JSDoc in src/pact/format.ts now spells out the
three-rule number-hygiene contract: strings in, strings out, never
round-trip through float64. NO consumer-visible behaviour change
— every previously-valid input produces byte-identical output;
the new surface is opt-in. v3.2.1 will adopt the new helpers at
the existing parseFloat(...).toFixed(N) and raw ${amount}
interpolation sites to close the F-SEC-001 / F-BUG-003
precision-loss vectors that the 2026-05-05 audit flagged.
v3.2.1 — applies the v3.2.0 number-hygiene helpers at the four
chain-call sites flagged by the 2026-05-05 audit. MINOR,
behaviour change. Closes F-SEC-001 (Pact-code injection vector
in urStoa stake/unstake's raw ${amount} interpolation) and
F-BUG-003 (parseFloat(amount).toFixed(N) silent precision loss
in buildCrossChainTransfer:92 and executeNativeUrStoaTransfer:206,
plus silent rounding 1.9999 → 2.000 in the urStoa transfer path).
All four sites now route through formatDecimalForPact(amount):
malformed input throws synchronously before any chain interaction
begins (counting-stub PactReader test proves the reader is never
invoked when the amount is malformed — validation is at the function
boundary, not deeper); arbitrary-precision decimals round-trip
byte-identical (39-digit integer amounts and 18-digit-fractional
decimals that pre-v3.2.1's float-based formatters would have
truncated or scientific-notation-mangled now reach the chain
intact); EU-locale comma input is auto-normalised to period (per
v3.2.0's relaxed input contract); and the urStoa stake/unstake
cap-args now reuse the same validated string as the pact-code
interpolation, so the coin.URV|STAKE / coin.URV|UNSTAKE cap-arg
and the executed coin.C_URV|Stake / coin.C_URV|Unstake decimal
literal are guaranteed to agree (was `String(numAm
