@ouronet/ouronet-core 4.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3043 -0
- package/README.md +1940 -0
- package/dist/codex/codec.d.ts +77 -0
- package/dist/codex/codec.js +123 -0
- package/dist/codex/errors.d.ts +14 -0
- package/dist/codex/errors.js +20 -0
- package/dist/codex/index.d.ts +27 -0
- package/dist/codex/index.js +25 -0
- package/dist/codex/seedTypeMigration.d.ts +35 -0
- package/dist/codex/seedTypeMigration.js +45 -0
- package/dist/codex/types.d.ts +100 -0
- package/dist/codex/types.js +19 -0
- package/dist/constants/index.d.ts +2 -0
- package/dist/constants/index.js +3 -0
- package/dist/constants/ouronet.d.ts +33 -0
- package/dist/constants/ouronet.js +59 -0
- package/dist/constants/tokenIds.d.ts +13 -0
- package/dist/constants/tokenIds.js +21 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +1 -0
- package/dist/interactions/activateFunctions.d.ts +67 -0
- package/dist/interactions/activateFunctions.js +154 -0
- package/dist/interactions/addLiquidityFunctions.d.ts +140 -0
- package/dist/interactions/addLiquidityFunctions.js +485 -0
- package/dist/interactions/coilFunctions.d.ts +73 -0
- package/dist/interactions/coilFunctions.js +213 -0
- package/dist/interactions/crossChainFunctions.d.ts +211 -0
- package/dist/interactions/crossChainFunctions.js +463 -0
- package/dist/interactions/dexAcquisitionPoolFunctions.d.ts +18 -0
- package/dist/interactions/dexAcquisitionPoolFunctions.js +18 -0
- package/dist/interactions/dexCollectablesFunctions.d.ts +28 -0
- package/dist/interactions/dexCollectablesFunctions.js +227 -0
- package/dist/interactions/dexFunctions.d.ts +23 -0
- package/dist/interactions/dexFunctions.js +23 -0
- package/dist/interactions/dexOrtoFungibleFunctions.d.ts +33 -0
- package/dist/interactions/dexOrtoFungibleFunctions.js +171 -0
- package/dist/interactions/dexParseFunctions.d.ts +150 -0
- package/dist/interactions/dexParseFunctions.js +316 -0
- package/dist/interactions/dexSwapPairAdminFunctions.d.ts +75 -0
- package/dist/interactions/dexSwapPairAdminFunctions.js +255 -0
- package/dist/interactions/dexSwapPairCalcFunctions.d.ts +55 -0
- package/dist/interactions/dexSwapPairCalcFunctions.js +218 -0
- package/dist/interactions/dexSwapPairDashboardFunctions.d.ts +47 -0
- package/dist/interactions/dexSwapPairDashboardFunctions.js +179 -0
- package/dist/interactions/dexSwapPairExecuteFunctions.d.ts +40 -0
- package/dist/interactions/dexSwapPairExecuteFunctions.js +301 -0
- package/dist/interactions/dexSwapPairSmartSwapFunctions.d.ts +25 -0
- package/dist/interactions/dexSwapPairSmartSwapFunctions.js +166 -0
- package/dist/interactions/dexTrueFungibleFunctions.d.ts +52 -0
- package/dist/interactions/dexTrueFungibleFunctions.js +220 -0
- package/dist/interactions/dexTypes.d.ts +465 -0
- package/dist/interactions/dexTypes.js +6 -0
- package/dist/interactions/errors.d.ts +12 -0
- package/dist/interactions/errors.js +13 -0
- package/dist/interactions/guardFunctions.d.ts +33 -0
- package/dist/interactions/guardFunctions.js +110 -0
- package/dist/interactions/index.d.ts +1 -0
- package/dist/interactions/index.js +20 -0
- package/dist/interactions/infoOneFunctions.d.ts +133 -0
- package/dist/interactions/infoOneFunctions.js +566 -0
- package/dist/interactions/kadenaFunctions.d.ts +11 -0
- package/dist/interactions/kadenaFunctions.js +40 -0
- package/dist/interactions/kpayFunctions.d.ts +45 -0
- package/dist/interactions/kpayFunctions.js +191 -0
- package/dist/interactions/ouroAccountFunctions.d.ts +64 -0
- package/dist/interactions/ouroAccountFunctions.js +229 -0
- package/dist/interactions/ouroBalanceFunctions.d.ts +39 -0
- package/dist/interactions/ouroBalanceFunctions.js +100 -0
- package/dist/interactions/ouroCoilFunctions.d.ts +33 -0
- package/dist/interactions/ouroCoilFunctions.js +190 -0
- package/dist/interactions/ouroFunctions.d.ts +23 -0
- package/dist/interactions/ouroFunctions.js +23 -0
- package/dist/interactions/ouroMovieBoosterFunctions.d.ts +18 -0
- package/dist/interactions/ouroMovieBoosterFunctions.js +203 -0
- package/dist/interactions/ouroPriceFunctions.d.ts +38 -0
- package/dist/interactions/ouroPriceFunctions.js +96 -0
- package/dist/interactions/ouroPrimordialsFunctions.d.ts +10 -0
- package/dist/interactions/ouroPrimordialsFunctions.js +480 -0
- package/dist/interactions/ouroRotateFunctions.d.ts +22 -0
- package/dist/interactions/ouroRotateFunctions.js +114 -0
- package/dist/interactions/ouroSubCompressFunctions.d.ts +23 -0
- package/dist/interactions/ouroSubCompressFunctions.js +191 -0
- package/dist/interactions/ouroTransferFunctions.d.ts +14 -0
- package/dist/interactions/ouroTransferFunctions.js +87 -0
- package/dist/interactions/ouroTypes.d.ts +113 -0
- package/dist/interactions/ouroTypes.js +6 -0
- package/dist/interactions/ouroUrStoaFunctions.d.ts +16 -0
- package/dist/interactions/ouroUrStoaFunctions.js +121 -0
- package/dist/interactions/ouroWrapFunctions.d.ts +22 -0
- package/dist/interactions/ouroWrapFunctions.js +234 -0
- package/dist/interactions/pensionFunctions.d.ts +12 -0
- package/dist/interactions/pensionFunctions.js +127 -0
- package/dist/interactions/urStoaFunctions.d.ts +104 -0
- package/dist/interactions/urStoaFunctions.js +475 -0
- package/dist/interactions/wrapFunctions.d.ts +46 -0
- package/dist/interactions/wrapFunctions.js +221 -0
- package/dist/pact/cfmBuilders.d.ts +807 -0
- package/dist/pact/cfmBuilders.js +812 -0
- package/dist/pact/index.d.ts +1 -0
- package/dist/pact/index.js +10 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,1940 @@
|
|
|
1
|
+
# @ouronet/ouronet-core
|
|
2
|
+
|
|
3
|
+
Ouronet protocol business logic on top of [`@stoachain/stoa-core`](https://www.npmjs.com/package/@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).
|
|
4
|
+
|
|
5
|
+
Chain-generic infrastructure (signing, wallet, crypto, network failover, gas, guard, errors, observability, dalos, reads, pact-format helpers) lives in the sibling [`@stoachain/stoa-core`](https://www.npmjs.com/package/@stoachain/stoa-core) package — install both, or just this one if you only need the Ouronet-specific surface.
|
|
6
|
+
|
|
7
|
+
> **Renamed.** This package was published as `@stoachain/ouronet-core` through 4.3.5. The
|
|
8
|
+
> code, version line, and release history continue unbroken under the `@ouronet` scope —
|
|
9
|
+
> the published name now matches the organisation that owns it. The old name is deprecated
|
|
10
|
+
> on npm and points here. Migration is a rename and nothing else:
|
|
11
|
+
>
|
|
12
|
+
> ```diff
|
|
13
|
+
> - import { serializeCodex } from "@stoachain/ouronet-core/codex";
|
|
14
|
+
> + import { serializeCodex } from "@ouronet/ouronet-core/codex";
|
|
15
|
+
> ```
|
|
16
|
+
|
|
17
|
+
## Status
|
|
18
|
+
|
|
19
|
+
**`4.3.6` on public npmjs** — **PATCH (atomic-triplet alignment with `@stoachain/stoa-core@4.3.6` + `@stoachain/kadena-stoic-legacy@4.3.6`).** 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.**
|
|
20
|
+
|
|
21
|
+
**`4.3.5` on public npmjs** — **ADDITIVE (atomic-triplet with `@stoachain/stoa-core@4.3.5` + `@stoachain/kadena-stoic-legacy@4.3.5` — 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.
|
|
22
|
+
|
|
23
|
+
**`4.3.4` on public npmjs** — **PATCH (atomic-triplet with `@stoachain/stoa-core@4.3.4` + `@stoachain/kadena-stoic-legacy@4.3.4`).** 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.
|
|
24
|
+
|
|
25
|
+
**`4.3.3` on public npmjs** — **Additive (atomic-triplet with `@stoachain/stoa-core@4.3.3` + `@stoachain/kadena-stoic-legacy@4.3.3`).** 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).
|
|
26
|
+
|
|
27
|
+
**`4.3.1` on public npmjs** — **PATCH (atomic-triplet with `@stoachain/stoa-core@4.3.1` + `@stoachain/kadena-stoic-legacy@4.3.1`).** 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('@ouronet/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.
|
|
28
|
+
|
|
29
|
+
**`4.3.0` on public npmjs** — **MINOR (atomic-triplet with `@stoachain/stoa-core@4.3.0` + `@stoachain/kadena-stoic-legacy@4.3.0`).** 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 [`@ouronet/ouronet-codex@0.1.0`](https://www.npmjs.com/package/@ouronet/ouronet-codex)'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.
|
|
30
|
+
|
|
31
|
+
**`4.2.2` on public npmjs** — **PATCH (atomic-triplet with `@stoachain/stoa-core@4.2.2` + `@stoachain/kadena-stoic-legacy@4.2.2`).** 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.
|
|
32
|
+
|
|
33
|
+
**`4.2.1` on public npmjs** — **PATCH (atomic-triplet with `@stoachain/stoa-core@4.2.1` + `@stoachain/kadena-stoic-legacy@4.2.1`).** 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.
|
|
34
|
+
|
|
35
|
+
**`4.2.0` on public npmjs** — **MINOR (atomic with `@stoachain/stoa-core@4.2.0` + `@stoachain/kadena-stoic-legacy@4.2.0`).** 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`](https://github.com/StoaChain/stoa-js/blob/main/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`](https://github.com/StoaChain/stoa-js/blob/main/MIGRATION-v4.2.md) at the monorepo root.
|
|
36
|
+
|
|
37
|
+
**v4.3.6** — atomic-triplet alignment bump (atomic with `@stoachain/stoa-core@4.3.6` + `@stoachain/kadena-stoic-legacy@4.3.6`). 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.**
|
|
38
|
+
|
|
39
|
+
**v4.3.5** — ADDITIVE (atomic-triplet with `@stoachain/stoa-core@4.3.5` + `@stoachain/kadena-stoic-legacy@4.3.5`). 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.**
|
|
40
|
+
|
|
41
|
+
**v4.3.4** — PATCH bugfix (atomic-triplet with `@stoachain/stoa-core@4.3.4` + `@stoachain/kadena-stoic-legacy@4.3.4`). 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.**
|
|
42
|
+
|
|
43
|
+
**v4.3.3** — additive StoicTag + governor-rotation release (atomic-triplet with `@stoachain/stoa-core@4.3.3` + `@stoachain/kadena-stoic-legacy@4.3.3`). 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.**
|
|
44
|
+
|
|
45
|
+
**v4.3.1** — ESM packaging fix (atomic-triplet with `@stoachain/stoa-core@4.3.1` + `@stoachain/kadena-stoic-legacy@4.3.1`). Released 2026-05-27. Fixes extensionless relative imports in emitted `dist/**/*.js` that broke `await import('@ouronet/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**.
|
|
46
|
+
|
|
47
|
+
**v4.3.0** — additive account-rotation release (atomic-triplet with `@stoachain/stoa-core@4.3.0` + `@stoachain/kadena-stoic-legacy@4.3.0`). 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 `@ouronet/ouronet-codex@0.1.0`'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.
|
|
48
|
+
|
|
49
|
+
**v4.2.2** — additive SWP-pair management release (atomic-triplet with `@stoachain/stoa-core@4.2.2` + `@stoachain/kadena-stoic-legacy@4.2.2`). 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).
|
|
50
|
+
|
|
51
|
+
**v4.2.1** — additive strategy-migration release (atomic-triplet with `@stoachain/stoa-core@4.2.1` + `@stoachain/kadena-stoic-legacy@4.2.1`). 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.
|
|
52
|
+
|
|
53
|
+
**v4.2.0** — architectural-closures + INTEGRATION-GUIDE deliverable. **MINOR (atomic with `@stoachain/stoa-core@4.2.0` + `@stoachain/kadena-stoic-legacy@4.2.0`).** 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 `@ouronet/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`](https://github.com/StoaChain/stoa-js/blob/main/MIGRATION-v4.2.md) for the v4.1.x → v4.2.0 transition guide, [`INTEGRATION-GUIDE.md`](https://github.com/StoaChain/stoa-js/blob/main/INTEGRATION-GUIDE.md) for cold-start onboarding.
|
|
54
|
+
|
|
55
|
+
**`4.1.1` on public npmjs** — **PATCH (atomic with `@stoachain/stoa-core@4.1.1` + `@stoachain/kadena-stoic-legacy@4.1.1`).** 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.**
|
|
56
|
+
|
|
57
|
+
**`4.1.0` on public npmjs** — **MIGRATION (atomic with `@stoachain/stoa-core@4.1.0` + `@stoachain/kadena-stoic-legacy@4.1.0`).** Retargets all 12 internal `@kadena/*` imports in `src/interactions/` to the new sibling subpaths under [`@stoachain/kadena-stoic-legacy`](https://www.npmjs.com/package/@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).
|
|
58
|
+
|
|
59
|
+
**`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/stoa-core@4.0.1`) 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.**
|
|
60
|
+
|
|
61
|
+
**`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 `@ouronet/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) + `@ouronet/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`](https://github.com/StoaChain/stoa-js/blob/main/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` + `@ouronet/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).
|
|
62
|
+
|
|
63
|
+
**`v3.3.8`** — **MINOR, additive
|
|
64
|
+
(documentation/deprecation cleanup pass).** Closes 5
|
|
65
|
+
LOW-severity findings from the 2026-05-05 audit's `"v3.x
|
|
66
|
+
deprecation cleanup"` + `"v3.x conventions alignment"` + `"v3.x
|
|
67
|
+
API hygiene"` themes in a single bundled release.
|
|
68
|
+
**F-API-015** rewrote stale `strict`-parameter JSDoc on
|
|
69
|
+
`src/dalos/account.ts:42-45` (the parameter never existed in
|
|
70
|
+
the `CreateAccountOptions` type union; new doc explains the
|
|
71
|
+
actual mode-vs-primitive throw contract).
|
|
72
|
+
**F-API-016** added `export` to the `CoilConfig` interface in
|
|
73
|
+
`src/interactions/coilFunctions.ts:17` — consumers holding a
|
|
74
|
+
`CoilConfig` value (e.g. from `COIL_CONFIGS.ouroToAuryn`)
|
|
75
|
+
could USE it but couldn't TYPE-ANNOTATE a parameter or local
|
|
76
|
+
with `CoilConfig` without re-declaring the shape; now they can.
|
|
77
|
+
**F-SEC-005 / F-ARCH-014** added `@deprecated` JSDoc to
|
|
78
|
+
`KADENA_BASE_URL` redirecting consumers to the failover-aware
|
|
79
|
+
`getActivePactUrl(chainId)` / `getActiveSpvUrl(chainId)` (or
|
|
80
|
+
the same-subpath thin wrappers `getPactUrl(chainId)` /
|
|
81
|
+
`getSpvUrl(chainId)`); removal scheduled for v4.0.0. The
|
|
82
|
+
constant was pinned to `node2.stoachain.com` and bypassed the
|
|
83
|
+
v2.1.0 failover layer.
|
|
84
|
+
**F-ARCH-011** consolidated `normalizeKeysetRef` deep-import
|
|
85
|
+
in `src/interactions/ouroFunctions.ts:10` to the `../guard`
|
|
86
|
+
barrel, matching the project's subpath-import discipline.
|
|
87
|
+
**F-ARCH-012** converted 19 single-quoted string literals to
|
|
88
|
+
double quotes in `src/dalos/account.ts` — the file was the
|
|
89
|
+
only remaining drift after v3.1.1's fix to
|
|
90
|
+
`src/dalos/index.ts`. Pure stylistic; TypeScript treats the
|
|
91
|
+
two forms as identical string literals at the type level.
|
|
92
|
+
**NO breaking change**, **NO observable runtime behavior
|
|
93
|
+
change**, **698/698 tests pass** (was 695 in v3.3.7; +3 from
|
|
94
|
+
the new `tests/v3-3-8-doc-cleanup.test.ts` regression-lock
|
|
95
|
+
file). One new public-API export (`CoilConfig` interface).
|
|
96
|
+
|
|
97
|
+
**`3.3.7`** — **MINOR, additive (security
|
|
98
|
+
pass).** Closes two MEDIUM security findings from the
|
|
99
|
+
2026-05-05 audit in a single bundled release: **F-SEC-003**
|
|
100
|
+
(seam-setter input validation) and **F-SEC-004** (V1-fallback
|
|
101
|
+
security advisory). **F-SEC-003** adds two new typed errors —
|
|
102
|
+
`InvalidPactReaderError` (rejects non-function values passed to
|
|
103
|
+
`setPactReader`) and `InvalidLoggerError` (rejects null /
|
|
104
|
+
undefined / non-object inputs and any object whose `warn` or
|
|
105
|
+
`error` are non-callable, passed to `setLogger`). Both extend
|
|
106
|
+
`TypeError` so existing consumer `instanceof TypeError` catches
|
|
107
|
+
are unchanged. Pre-v3.3.7 the misconfigurations only surfaced
|
|
108
|
+
later as `_reader is not a function` / `_logger.warn is not a
|
|
109
|
+
function` at the first call site, far from the boot wiring;
|
|
110
|
+
v3.3.7 surfaces them at the boot site. **F-SEC-004** wires a
|
|
111
|
+
**one-shot** `getLogger().warn(...)` security advisory into the
|
|
112
|
+
V1-decrypt path (V1 = PBKDF2-SHA256 / 10,000 iterations; OWASP
|
|
113
|
+
2023+ recommends 600,000) — fires on the FIRST V1 envelope
|
|
114
|
+
decoded per process lifetime, stays silent after that so a
|
|
115
|
+
codex with 100 V1 entries logs ONE warning, not 100. Adds two
|
|
116
|
+
new public-API rich variants `decryptStringV2WithDetails` and
|
|
117
|
+
`smartDecryptWithDetails` that return `{plaintext, wasLegacyV1}`
|
|
118
|
+
for the per-call programmatic signal — consumers can react by
|
|
119
|
+
re-encrypting affected entries to V2 in-place. JSDoc CVE-style
|
|
120
|
+
risk documentation added to `EncryptedDataV1`,
|
|
121
|
+
`decryptStringV2`, and `smartDecrypt`. **NO breaking change**,
|
|
122
|
+
**695/695 tests pass** (was 674 in v3.3.6; +21 from
|
|
123
|
+
`tests/v3-3-7-seam-validators.test.ts` (11) +
|
|
124
|
+
`tests/v3-3-7-v1-warning.test.ts` (10)). v3.3.0 contract test
|
|
125
|
+
locking the byte-identical `setLogger requires a non-null
|
|
126
|
+
Logger` message preserved verbatim — the new
|
|
127
|
+
`InvalidLoggerError` extends `TypeError` to keep that contract
|
|
128
|
+
intact.
|
|
129
|
+
|
|
130
|
+
**`3.3.6`** — **MINOR, additive (performance
|
|
131
|
+
pass).** Closes three MEDIUM performance findings from the
|
|
132
|
+
2026-05-05 audit in a single bundled release:
|
|
133
|
+
**F-PERF-008** — added `"sideEffects": false` to `package.json`
|
|
134
|
+
(the audit's "single most impactful tree-shaking fix"; lets
|
|
135
|
+
downstream bundlers prune unused barrel imports from the
|
|
136
|
+
16-subpath exports map; verified safe via top-level-mutation
|
|
137
|
+
grep across `src/`);
|
|
138
|
+
**F-PERF-003** — memoized 8 `RegExp` allocations per call in
|
|
139
|
+
`coilFunctions.getCoilPreviewGeneric` to a per-`targetTokenName`
|
|
140
|
+
`Map<string, CoilPatternSet>` cache (the audit's literal
|
|
141
|
+
suggested fix "hoist to module-level const" doesn't apply
|
|
142
|
+
because patterns interpolate `targetTokenName` from `config`,
|
|
143
|
+
but the cache form achieves the same outcome — steady-state
|
|
144
|
+
allocation cost is 0 RegExp objects per call after warm-up);
|
|
145
|
+
**F-PERF-004** — parallelized `ouroFunctions.getOuronetKdaDetails`
|
|
146
|
+
from sequential `await getKadenaAccountOwner()` →
|
|
147
|
+
`await getKadenaAccountGuard()` to a single
|
|
148
|
+
`Promise.all([owner, guard])` (verified independent: probes
|
|
149
|
+
`DALOS.UR_AccountKadena` vs `DALOS.UR_AccountGuard` with no
|
|
150
|
+
causal dependency; halves happy-path latency from 2 sequential
|
|
151
|
+
RPC roundtrips to 1 parallel roundtrip).
|
|
152
|
+
All three are low-risk, behaviorally identical to v3.3.5.
|
|
153
|
+
Consumer-side impact: smaller OuronetUI bundle sizes (F-PERF-008,
|
|
154
|
+
exact savings bundler-config-dependent); faster
|
|
155
|
+
`getOuronetKdaDetails` (F-PERF-004, ~half wall-clock); no
|
|
156
|
+
observable difference for `getCoilPreviewGeneric` (F-PERF-003,
|
|
157
|
+
internal-only). **NO public API change**, **674/674 tests pass**
|
|
158
|
+
(was 672 in v3.3.5; +2 from the new
|
|
159
|
+
`tests/v3-3-6-perf-pass.test.ts` regression-lock file). Locks
|
|
160
|
+
both F-PERF-008 (`expect(pkg.sideEffects).toBe(false)` strict
|
|
161
|
+
equality) and F-PERF-004 (counting reader proves both
|
|
162
|
+
`UR_AccountKadena` AND `UR_AccountGuard` reads still happen,
|
|
163
|
+
catching a regression that accidentally drops one of the reads).
|
|
164
|
+
|
|
165
|
+
**`3.3.5`** — **MINOR, additive (test-only).**
|
|
166
|
+
Closes audit finding **F-TEST-006** (MEDIUM, testing-auditor) —
|
|
167
|
+
six interaction modules previously had insufficient runtime
|
|
168
|
+
coverage: three with **zero runtime tests at all**
|
|
169
|
+
(`pensionFunctions`, `guardFunctions`, `infoOneFunctions`) and
|
|
170
|
+
three with **compile-only tests** (`coilFunctions`,
|
|
171
|
+
`kpayFunctions`, `activateFunctions` are all type-checked at
|
|
172
|
+
`tests/types.test.ts:44-47` via `expectTypeOf`, but the functions
|
|
173
|
+
never actually execute in the test suite). Compile-only tests
|
|
174
|
+
prove the type signature matches consumer expectations but do
|
|
175
|
+
NOT prove the function executes correctly — a bug that swapped
|
|
176
|
+
two argument-string concatenations, forgot to await a Promise,
|
|
177
|
+
or mis-routed the `pactRead` call would all type-check cleanly
|
|
178
|
+
while producing wrong runtime behaviour. v3.3.5 closes the gap
|
|
179
|
+
with `tests/v3-3-5-smoke.test.ts` — **12 new it-blocks across 6
|
|
180
|
+
describe groups**, one happy-path + one error-path test per
|
|
181
|
+
module, picking the simplest representative read-only function
|
|
182
|
+
from each: `pensionFunctions.getHibernateFee` (the ONLY of the 6
|
|
183
|
+
with a non-null error path — graceful-degradation fallback
|
|
184
|
+
formula `0.12 - 0.000008 * lockDays` clamped non-negative);
|
|
185
|
+
`guardFunctions.getRotateGuardInfo`;
|
|
186
|
+
`infoOneFunctions.getCoilPreviewInfo` (locks the
|
|
187
|
+
`{result: ...}` envelope wrap contract);
|
|
188
|
+
`coilFunctions.getCoilPreviewGeneric` (the ONLY of the 6 that
|
|
189
|
+
rethrows rather than returning `null`/fallback — locks the
|
|
190
|
+
rethrow contract that consumers depend on for try/catch flow);
|
|
191
|
+
`kpayFunctions.getKpayData`;
|
|
192
|
+
`activateFunctions.getDeployStandardAccountInfoOnly`. Strategy
|
|
193
|
+
mirrors v3.3.4: install a stubbed reader via `setPactReader(...)`,
|
|
194
|
+
call SUT, assert. **NO source-code change**, **NO public API
|
|
195
|
+
change**, **672/672 tests pass** (was 660 in v3.3.4; +12 from
|
|
196
|
+
the new test file). With v3.3.5 the **v3.3.x audit-closure track
|
|
197
|
+
is COMPLETE** — all MEDIUM testing findings from the 2026-05-05
|
|
198
|
+
audit are now closed (F-LOGGER-SEAM-001 → v3.3.0; F-TEST-002 →
|
|
199
|
+
v3.3.2; F-TEST-005 → v3.3.4; F-TEST-006 → v3.3.5).
|
|
200
|
+
|
|
201
|
+
**`3.3.4`** — **MINOR, additive (test-only).**
|
|
202
|
+
Closes audit finding **F-TEST-005** (MEDIUM, testing-auditor) —
|
|
203
|
+
the v3.0.0 nullable-widening sweep widened 16 read-side
|
|
204
|
+
interaction functions from `Promise<T>` → `Promise<T | null>`,
|
|
205
|
+
but only **3 of the 16** had a paired success-path test
|
|
206
|
+
(`getStoaPriceUSD` at `tests/interactions-pricing.test.ts:80`,
|
|
207
|
+
`getLPTypeInfo`'s mixed-state lock at
|
|
208
|
+
`interactions-balance-cluster.test.ts:137`, and
|
|
209
|
+
`getUrStoaGuard`'s 3-state contract at the same file:207). The
|
|
210
|
+
other 13 could not distinguish "always returns null" (silent
|
|
211
|
+
regression) from "returns null only on RPC failure" (correct
|
|
212
|
+
contract) — a future bug that returned `null` unconditionally
|
|
213
|
+
would slip past every existing test, surface only at consumer
|
|
214
|
+
runtime, and be caught only by chain-side breakage. v3.3.4
|
|
215
|
+
closes the gap with `tests/v3-3-4-success-paths.test.ts` —
|
|
216
|
+
**13 new it-blocks across 6 describe groups**, one per missing
|
|
217
|
+
function, each installing a `successReader` stub via
|
|
218
|
+
`setPactReader(...)` and asserting the parsed non-null return
|
|
219
|
+
value. The 13 functions: `getTokenDecimals`, `getPoolTotalFee`,
|
|
220
|
+
`getDPTFMinMove` (pricing-quartet missing 3); `getIgnisBalance`,
|
|
221
|
+
`getAccountTokenSupply`, `getOuroDispoCapacity`, `getVirtualOuro`
|
|
222
|
+
(string-balance cluster — none previously covered);
|
|
223
|
+
`getUrStoaBalance` and `checkCoinAccountExists` (urStoa pair);
|
|
224
|
+
`validateLiquidity` (mixed-shape success — locks the
|
|
225
|
+
`valid:true` ↔ `error:undefined` mutual exclusion that
|
|
226
|
+
distinguishes a successful liquidity check from an RPC-failure
|
|
227
|
+
one); `getMaxBuyMovieBooster` (locks `Number.isFinite` guard
|
|
228
|
+
against v2.x fabricated-`0`); `getSWPSpawnLimit` and
|
|
229
|
+
`getSWPInactiveLimit` (magic-string elimination — also asserts
|
|
230
|
+
`expect(out).not.toBe("N/A")` so the v3.0.0 BREAKING swap
|
|
231
|
+
cannot regress unnoticed). **NO source-code change**, **NO
|
|
232
|
+
public API change**, **660/660 tests pass** (was 647 in v3.3.3;
|
|
233
|
+
+13 from the new test file).
|
|
234
|
+
|
|
235
|
+
**`3.3.3`** — **MINOR, additive (NEW PUBLIC
|
|
236
|
+
SURFACE — not a bug fix).** Ships the multi-party
|
|
237
|
+
partial-signature workflow OuronetUI has been blocked on:
|
|
238
|
+
"Person A signs → exports → Person B imports → signs → exports →
|
|
239
|
+
Person C imports → signs → submits", with cross-party tamper
|
|
240
|
+
detection at every handoff. Builds on v3.3.2's locked
|
|
241
|
+
partial-signing primitive (signing with a subset of declared
|
|
242
|
+
signers fills only those slots; pre-existing slots stay intact
|
|
243
|
+
across re-signing passes) by wrapping it in a versioned export
|
|
244
|
+
envelope + slot-status helpers + Ed25519 sig-verification helper.
|
|
245
|
+
New `src/signing/partialSig.ts` module re-exported from
|
|
246
|
+
`@ouronet/ouronet-core/signing`, exposing 7 functions
|
|
247
|
+
(`signPartial`, `serializePartialTransaction`,
|
|
248
|
+
`deserializePartialTransaction`, `getMissingSigners`,
|
|
249
|
+
`getFilledSigners`, `isFullySigned`, `verifyExistingSignatures`)
|
|
250
|
+
+ 2 typed errors (`InvalidEnvelopeError`, `TamperedHashError`) +
|
|
251
|
+
the `PartialSigEnvelope` interface. The envelope embeds both
|
|
252
|
+
`cmd` and `hash` so importers can verify integrity; if the cmd
|
|
253
|
+
was tampered mid-flight, `deserializePartialTransaction` rejects
|
|
254
|
+
with `TamperedHashError` carrying both `expected` and `actual` for
|
|
255
|
+
operator diagnosability. As a second layer,
|
|
256
|
+
`verifyExistingSignatures` runs `nacl.sign.detached.verify` on
|
|
257
|
+
every filled slot — works for both nacl-direct (koala/foreign)
|
|
258
|
+
and BIP32-WASM (chainweaver/eckowallet) sigs since both produce
|
|
259
|
+
standard Ed25519 over the same canonical hash bytes. **NO
|
|
260
|
+
existing API changed**, **NO source-side behaviour change**
|
|
261
|
+
outside the new module, **647/647 tests pass** (was 631 in
|
|
262
|
+
v3.3.2; +16 from the new `tests/partial-sig.test.ts`).
|
|
263
|
+
|
|
264
|
+
**`3.3.2`** — **MINOR, additive (test-only).**
|
|
265
|
+
Closes audit finding **F-TEST-002** (HIGH) — the central signing
|
|
266
|
+
entry point `universalSignTransaction` in
|
|
267
|
+
`src/signing/universalSign.ts` had ZERO direct tests pre-v3.3.2.
|
|
268
|
+
The only mention in `tests/` was a comment in
|
|
269
|
+
`tests/signing.test.ts:5` stating "the full
|
|
270
|
+
universalSignTransaction is not exercised here";
|
|
271
|
+
`tests/strategy.test.ts` exercises a higher-level wrapper but only
|
|
272
|
+
covers `seedType: "koala"`. The chainweaver / eckowallet / foreign
|
|
273
|
+
branches AND the seedType dispatcher itself were never
|
|
274
|
+
runtime-tested — a regression that mis-routed `eckowallet` →
|
|
275
|
+
`koala` (or any other dispatch error) would silently produce
|
|
276
|
+
wrong-shape signatures, surfaced only by chain-side "invalid
|
|
277
|
+
signature" rejection at consumer runtime. v3.3.2 adds
|
|
278
|
+
`tests/universal-sign.test.ts` with **9 new it-blocks** covering
|
|
279
|
+
all three seedType branches with real-keypair round-trips
|
|
280
|
+
(koala via RFC-8032 vector, chainweaver/eckowallet via the
|
|
281
|
+
@kadena/hd-wallet vendor vector through
|
|
282
|
+
`KadenaWalletBuilder.createWalletPairFromMnemonic`), the
|
|
283
|
+
foreign-key `onMissingKey` callback (success and key-mismatch
|
|
284
|
+
error cases), the multi-signer mixed-seedType case, the
|
|
285
|
+
partial-signing primitive (foundation lock for v3.3.3's
|
|
286
|
+
multi-party signing public surface), and the
|
|
287
|
+
silent-skip-when-not-in-signers contract. **NO source-code
|
|
288
|
+
change**, **NO public API change**, **631/631 tests pass** (was
|
|
289
|
+
622 in v3.3.1; +9 from the new test file).
|
|
290
|
+
|
|
291
|
+
**`3.3.1`** — **PATCH, workflow-only.** Closes the
|
|
292
|
+
two carried-forward follow-ups that have appeared in every
|
|
293
|
+
pollinate run's "follow-ups" block since v3.0.0: (1) `npm publish`
|
|
294
|
+
now passes `--provenance` (and the workflow gains `id-token:
|
|
295
|
+
write` permission), so v3.3.1 onwards every release carries a
|
|
296
|
+
verifiable SLSA attestation linking the published tarball to the
|
|
297
|
+
exact GitHub Action run that produced it; (2) the `gh release
|
|
298
|
+
create` calls drop the `--repo` flag, eliminating the
|
|
299
|
+
`gh release create --notes-from-tag --repo X` flag-combination
|
|
300
|
+
incompatibility that the GitHub-hosted runners' gh-CLI image
|
|
301
|
+
rejected starting around 2026-04-30 (every v3.x release pre-v3.3.1
|
|
302
|
+
needed pollinate's REST-API fallback at Step 9c to create the
|
|
303
|
+
GitHub Release manually). Both fixes are workflow-file-only —
|
|
304
|
+
`.github/workflows/publish.yml` is the only file with a behaviour
|
|
305
|
+
change. **NO source-code change**, **NO public API change**,
|
|
306
|
+
**622/622 tests pass unchanged**. Consumers see byte-identical
|
|
307
|
+
package contents to v3.3.0; the difference is the v3.3.1
|
|
308
|
+
attestation badge on npmjs.com and a green-check on the GitHub
|
|
309
|
+
Action run page (vs the recurring red-X for the gh-CLI Release
|
|
310
|
+
step that every v3.x release pre-v3.3.1 produced).
|
|
311
|
+
|
|
312
|
+
**`3.3.0`** — **MINOR, additive (Logger interface
|
|
313
|
+
extension) + behaviour change (call-site routing)** — first release
|
|
314
|
+
in the v3.3.x line. Closes the consolidated **F-LOGGER-SEAM-001**
|
|
315
|
+
finding flagged by all 8 audit agents at 9 distinct source sites
|
|
316
|
+
(highest-redundancy finding in the entire 2026-05-05 audit). Two
|
|
317
|
+
of the nine sites were already removed by v3.2.2's deletion of
|
|
318
|
+
`executeAddLiquidityMultiStepComplete`; v3.3.0 closes the remaining
|
|
319
|
+
seven by extending the `Logger` interface from `{warn, error}` to
|
|
320
|
+
`{warn, error, info}` and routing every surviving raw `console.*`
|
|
321
|
+
call in `src/` through the seam (or deleting debug-leak
|
|
322
|
+
instrumentation that had no operational value). Post-v3.3.0
|
|
323
|
+
invariant: **zero raw `console.*` call sites in `src/`** outside
|
|
324
|
+
the seam's own default-logger implementation, verified by a new
|
|
325
|
+
regression-lock test that scans the entire src/ tree on every run.
|
|
326
|
+
Backwards-compat: v3.2.x consumers wiring
|
|
327
|
+
`setLogger({warn, error})` continue to work — the setter synthesises
|
|
328
|
+
an `info` wrapper that falls through to `console.info` for the new
|
|
329
|
+
channel; consumers that want full control pass
|
|
330
|
+
`setLogger({warn, error, info})`. **622/622 tests pass.**
|
|
331
|
+
|
|
332
|
+
**`3.2.3`** — **MINOR, behaviour change** — fourth
|
|
333
|
+
and final wave of the v3.2.x audit-cycle close-out track. Four
|
|
334
|
+
targeted bug fixes closing the highest-user-impact remaining
|
|
335
|
+
findings: **F-BUG-002** (added `creationTime: safeCreationTime()`
|
|
336
|
+
to `buildCrossChainTransfer` setMeta block — the lone interactions
|
|
337
|
+
builder that omitted the helper after v2.3.0's sweep, causing
|
|
338
|
+
sporadic chain-side rejections under client clock drift); **F-BUG-004**
|
|
339
|
+
(rewrote `fetchSpvProof` to wrap in `withFailover` + add
|
|
340
|
+
`AbortSignal.timeout(30s)` per-attempt deadline — pre-v3.2.3 a
|
|
341
|
+
wedged primary node would hang the function indefinitely with the
|
|
342
|
+
user's KDA committed to `kadena-xchain-gas` escrow and no recovery
|
|
343
|
+
path, identified as the highest-impact bug in the entire audit);
|
|
344
|
+
**F-SEC-002** (added URL parse + `https:` scheme allow-list to
|
|
345
|
+
`setNodeConfig("custom", customUrl)` — pre-v3.2.3 it accepted any
|
|
346
|
+
truthy string and assigned it to `PRIMARY_HOST`, allowing an
|
|
347
|
+
attacker-controlled custom-node setting to redirect every signed
|
|
348
|
+
transaction); and **F-ERR-001** (added `@throws` JSDoc to
|
|
349
|
+
`submitCrossChainTransfer`, `submitContinuation`, and
|
|
350
|
+
`listenForCompletion`, documenting the
|
|
351
|
+
TIMEOUT-as-pending-not-failed contract that prevents user
|
|
352
|
+
double-pay on `listen` timeouts). With these four findings closed,
|
|
353
|
+
the v3.2.x sequence has remediated **15 of the audit's 62
|
|
354
|
+
confirmed findings** across four ship cycles. **618/618 tests pass**
|
|
355
|
+
(was 601 in v3.2.2; +17 new it-blocks). Next: v3.3.x for
|
|
356
|
+
logger-seam completion + test coverage; v4.0.0 for structural
|
|
357
|
+
decomposition + monorepo split + type consolidation.
|
|
358
|
+
|
|
359
|
+
**`3.2.2`** — **MINOR, public API removal** —
|
|
360
|
+
third wave of the v3.2.x audit-cycle close-out track. Removes the
|
|
361
|
+
four `executeAddLiquidityMultiStep*` functions plus the
|
|
362
|
+
`MultiStepAddLiquidityResult` type from
|
|
363
|
+
`src/interactions/addLiquidityFunctions.ts`, along with the
|
|
364
|
+
unused `_strategy` parameter on `executeAddLiquidity`. Closes audit
|
|
365
|
+
findings **F-ERR-005** (`error.message.includes` retry-loop crash on
|
|
366
|
+
non-Error throws), **F-ERR-014** (listen-timeout vs submit-failure
|
|
367
|
+
conflation causing user double-pay risk), **F-PERF-014** (4×
|
|
368
|
+
hardcoded 3-second sleeps adding ~6s wall-clock latency to every
|
|
369
|
+
successful flow), **F-PERF-015** (retry-with-fixed-sleep against
|
|
370
|
+
string-matched `error.message.includes("Cannot find module")`
|
|
371
|
+
patterns), and **F-API-026** (the always-`"auto"` `_strategy`
|
|
372
|
+
parameter on `executeAddLiquidity` was dead public surface). All
|
|
373
|
+
five findings closed **by removal** rather than fix — the
|
|
374
|
+
multi-step pipeline existed because the historical Kadena chainweb
|
|
375
|
+
gas limit (150k per block) couldn't fit a single-block
|
|
376
|
+
add-liquidity transaction; StoaChain's 2M-per-block chainweb fits
|
|
377
|
+
the entire flow in one transaction, so multi-step has been dead
|
|
378
|
+
code in OuronetUI since the gas-limit increase. Net code change:
|
|
379
|
+
**−338 lines** (1031 → 693 lines in `addLiquidityFunctions.ts`).
|
|
380
|
+
**601/601 tests pass** unchanged; no test exercised the removed
|
|
381
|
+
functions, which was itself a v3.2.x audit signal that the surface
|
|
382
|
+
was unused. The Pact-side multi-step contract
|
|
383
|
+
(`TS01-CP.SWP|C_AddStandardLiquidity` defpact) is still on chain
|
|
384
|
+
for historical interoperability — this package just stops exposing
|
|
385
|
+
the TypeScript wrappers around it. Strict-semver-wise this is a
|
|
386
|
+
breaking change requiring a MAJOR bump; classified MINOR for v3.2.2
|
|
387
|
+
because the removed functions had no known consumer (verified via
|
|
388
|
+
repo-wide grep + user confirmation that OuronetUI no longer uses
|
|
389
|
+
multi-step). v3.2.3 will land the targeted bug fixes
|
|
390
|
+
(`creationTime`, `fetchSpvProof` failover, `setNodeConfig` URL
|
|
391
|
+
validation).
|
|
392
|
+
|
|
393
|
+
**`3.2.1`** — **MINOR, behaviour change** —
|
|
394
|
+
second wave of the v3.2.x audit-cycle close-out track. Puts the
|
|
395
|
+
v3.2.0 number-hygiene helpers (`formatDecimalForPact`,
|
|
396
|
+
`formatIntegerForPact`, `ValidatedDecimal` / `ValidatedInteger`
|
|
397
|
+
brand types) to work at the four chain-call sites the 2026-05-05
|
|
398
|
+
audit flagged: `buildCrossChainTransfer` (`crossChainFunctions:92`),
|
|
399
|
+
`executeNativeUrStoaTransfer` (`urStoaFunctions:206`),
|
|
400
|
+
`executeStakeUrStoa` (`urStoaFunctions:441`), and
|
|
401
|
+
`executeUnstakeUrStoa` (`urStoaFunctions:497`). Closes audit
|
|
402
|
+
findings **F-SEC-001** (Pact-code injection via raw `${amount}`
|
|
403
|
+
interpolation in urStoa stake/unstake) and **F-BUG-003**
|
|
404
|
+
(`parseFloat(amount).toFixed(N)` silent precision loss + silent
|
|
405
|
+
rounding). All four sites now route through the validated
|
|
406
|
+
formatter: malformed input throws synchronously before any chain
|
|
407
|
+
interaction begins; arbitrary-precision decimals (e.g., 39-digit
|
|
408
|
+
integer amounts that would overflow float64) round-trip
|
|
409
|
+
byte-identical; EU-locale comma input (`"1,5"`) is normalised to
|
|
410
|
+
period; and the urStoa stake/unstake cap-arg now reuses the
|
|
411
|
+
validated string so pact-code and cap-arg are guaranteed to agree.
|
|
412
|
+
The `numAmount` field on `StakeUrStoaParams` / `UnstakeUrStoaParams`
|
|
413
|
+
is deprecated (still accepted, no longer read; will be removed in
|
|
414
|
+
v4.0.0). **601/601 tests pass.** v3.2.2 will remove the dead
|
|
415
|
+
multi-step add-liquidity surface; v3.2.3 will land the targeted
|
|
416
|
+
bug fixes (`creationTime`, `fetchSpvProof` failover,
|
|
417
|
+
`setNodeConfig` URL validation).
|
|
418
|
+
|
|
419
|
+
**`3.2.0`** — **MINOR, additive** release that opened
|
|
420
|
+
the v3.2.x audit-cycle close-out track with number-hygiene
|
|
421
|
+
infrastructure for Pact-bound integers and decimals.
|
|
422
|
+
`formatDecimalForPact` now accepts a single comma as decimal
|
|
423
|
+
separator (so European-locale UI text fields work without upstream
|
|
424
|
+
normalisation); a new sibling `formatIntegerForPact(amount: string):
|
|
425
|
+
ValidatedInteger` validates integer-typed Pact arguments without ever
|
|
426
|
+
round-tripping through float64 (arbitrary-precision-safe — a
|
|
427
|
+
100-digit integer string passes through byte-identical); two new
|
|
428
|
+
branded TypeScript types (`ValidatedDecimal`, `ValidatedInteger`)
|
|
429
|
+
prove "this string passed the formatter" at the type level so
|
|
430
|
+
downstream call sites get compile-time guarantees that consumer
|
|
431
|
+
input has been validated before it reaches Pact-code interpolation.
|
|
432
|
+
**No consumer-visible behaviour changes** — every previously-valid
|
|
433
|
+
input continues to produce byte-identical output. **593/593 tests
|
|
434
|
+
pass** (was 565 in v3.1.1; +28 covering comma-normalisation,
|
|
435
|
+
arbitrary-precision round-trips with the explicit
|
|
436
|
+
truncation-at-maxDecimals lock, the new integer formatter, and the
|
|
437
|
+
brand-type compile contract). v3.2.1 will apply the new helpers at
|
|
438
|
+
the existing `parseFloat(...).toFixed(N)` call sites to close the
|
|
439
|
+
F-SEC-001 / F-BUG-003 precision-loss vectors; v3.2.2 will remove
|
|
440
|
+
the dead multi-step add-liquidity surface (chainweb's gas bump made
|
|
441
|
+
it obsolete); v3.2.3 will land the targeted bug fixes
|
|
442
|
+
(`creationTime`, `fetchSpvProof` failover, `setNodeConfig` URL
|
|
443
|
+
validation).
|
|
444
|
+
|
|
445
|
+
**`3.1.1`** — **PATCH, additive** release that closed the
|
|
446
|
+
audit-cycle gaps identified by the post-v3.1.0-integration audit
|
|
447
|
+
(see [`CHANGELOG.md`](CHANGELOG.md) v3.1.1 entry for the full
|
|
448
|
+
per-finding trace). Three additive re-exports completed the
|
|
449
|
+
`./dalos` integration surface (`InvalidBitStringError`,
|
|
450
|
+
`InvalidBitmapError`, `InvalidPrivateKeyError` for typed
|
|
451
|
+
validation-failure discrimination + `CoordAffine` companion type
|
|
452
|
+
for `SchnorrSignature`); the `src/dalos/` subdirectory was
|
|
453
|
+
realigned with CONVENTIONS.md (double-quoted imports, no `.js`
|
|
454
|
+
extensions); the v3.1.0 locale-determinism test assertion in
|
|
455
|
+
`tests/gas.test.ts` was tightened to strict equality (was a
|
|
456
|
+
substring regex that wouldn't detect a regression on a US-locale
|
|
457
|
+
CI host); a fresh `tests/dalos-integration.test.ts` block covered
|
|
458
|
+
the v3.1.0 Schnorr re-exports end-to-end. No runtime change for
|
|
459
|
+
any v3.1.0 consumer; v3.1.0 itself was committed locally
|
|
460
|
+
(`bf10dc1`) but never pushed to npm — the npm registry skips from
|
|
461
|
+
`3.0.0` to `3.1.1`.
|
|
462
|
+
|
|
463
|
+
**`3.1.0`** (committed locally `bf10dc1`, never published) — **MINOR,
|
|
464
|
+
additive** release that upgrades `@ouronet/dalos-crypto` from
|
|
465
|
+
`^1.2.0` to `^4.0.3` (covering
|
|
466
|
+
the v2.x/v3.x/v4.x line of the upstream package — Schnorr v2 wire
|
|
467
|
+
format, cofactor subgroup-membership hardening, generator-precompute
|
|
468
|
+
matrix cache, async signing surfaces, the v4.0.0 Elliptic-package
|
|
469
|
+
carve-out on the Go side, and the v4.0.3 LOW-band closures), exposes
|
|
470
|
+
the previously-internal **Schnorr signature surface** through the
|
|
471
|
+
`./dalos` subpath (`schnorrSign` / `schnorrVerify` and the browser-
|
|
472
|
+
friendly `schnorrSignAsync` / `schnorrVerifyAsync` async variants
|
|
473
|
+
that yield to the event loop on a fixed cadence; plus the typed
|
|
474
|
+
`SchnorrSignError` exception and the `SchnorrSignature` shape type),
|
|
475
|
+
and ships a small locale-determinism fix in `formatMaxFee` so the
|
|
476
|
+
ANU thousands separator is `,` on every host (was host-locale-
|
|
477
|
+
dependent — silently passed CI on en-US Linux while failing locally
|
|
478
|
+
on a German-locale host). **558/558 tests pass.** No public surface
|
|
479
|
+
from prior versions changes shape; all additions are opt-in. Per
|
|
480
|
+
the upstream v4.0.0 changelog: TypeScript consumers see no breaking
|
|
481
|
+
surface changes across the dalos-crypto v1.2.0 → v4.0.3 jump (the
|
|
482
|
+
v4.0.0 major bump was driven entirely by a Go-reference
|
|
483
|
+
reorganisation that doesn't affect TS consumers). See
|
|
484
|
+
[`CHANGELOG.md`](CHANGELOG.md) for the full v3.1.0 entry.
|
|
485
|
+
|
|
486
|
+
**`3.0.0`** — **BREAKING** major release closing M3 from the
|
|
487
|
+
2026-04-30 audit cycle (F-CORE-007 fabricated-fallback removal +
|
|
488
|
+
comprehensive HIGH-risk catalog sweep). This was the FIRST major
|
|
489
|
+
bump since **v2.0.0** (2026-05-01) — downstream consumers
|
|
490
|
+
(OuronetUI, AncientHolder HUB) MUST update call sites to handle
|
|
491
|
+
`null` returns. **16 fabricated-fallback widenings** land across 4
|
|
492
|
+
interaction files: 15 functions widen from `Promise<T>` to
|
|
493
|
+
`Promise<T | null>` so that consumers see RPC failures instead of
|
|
494
|
+
fabricated chain values (`1.0` USD prices, `"0"` balances, sentinel
|
|
495
|
+
`"N/A"` strings, fake `false` existence flags), plus 1 mixed-shape
|
|
496
|
+
addition for `validateLiquidity` (preserves `valid: boolean` while
|
|
497
|
+
adding optional `error?: string` to distinguish RPC failure from
|
|
498
|
+
validation rejection). In lockstep, **14 NON-BREAKING logger-routing
|
|
499
|
+
additions** across 5 files complete the silent-catch-elimination
|
|
500
|
+
sweep started in v2.3.0 — every previously-silent diagnostic catch
|
|
501
|
+
in `src/interactions/*` now routes through the
|
|
502
|
+
`@ouronet/ouronet-core/observability` `getLogger().error()` seam.
|
|
503
|
+
NO public-API removals (NFR-03): all 16 modified functions retain
|
|
504
|
+
their names and parameter signatures; only return types widen. See
|
|
505
|
+
[`CHANGELOG.md`](CHANGELOG.md) for the full v3.0.0 entry, and the
|
|
506
|
+
**Migrating to v3.x** H2 section below for per-cluster `Before:` /
|
|
507
|
+
`After:` migration patterns (Option B null-pattern locked decision
|
|
508
|
+
per Q3..Q11 of the requirements). The optional **What's new in
|
|
509
|
+
v3.0.0** section ships a copy-paste example for adapting to nullable
|
|
510
|
+
returns.
|
|
511
|
+
|
|
512
|
+
Every piece of blockchain logic that used to live in OuronetUI has
|
|
513
|
+
landed here: Pact builders, signing pipeline (CodexSigningStrategy +
|
|
514
|
+
universalSignTransaction), encryption (V1 + V2 + smartDecrypt), guard
|
|
515
|
+
analysis, gas calibration, codex codec, seed-type migration. OuronetUI
|
|
516
|
+
is now a pure consumer.
|
|
517
|
+
|
|
518
|
+
As of the current **v3.1.0** shipping line (originally introduced in
|
|
519
|
+
**v1.3.0**, dep range bumped to `^4.0.3` in v3.1.0), OuronetCore
|
|
520
|
+
integrates
|
|
521
|
+
**[`@ouronet/dalos-crypto@^4.0.3`](https://www.npmjs.com/package/@ouronet/dalos-crypto)**
|
|
522
|
+
via the `./dalos` subpath — consumers mint Ouronet accounts locally
|
|
523
|
+
(all six DALOS input modes: random, bitmap, bitstring, base-10,
|
|
524
|
+
base-49, seed words) without touching the retired
|
|
525
|
+
`go.ouronetwork.io/api/generate` endpoint. As of v3.1.0 the `./dalos`
|
|
526
|
+
subpath also re-exports the lower-level **Schnorr signature surface**
|
|
527
|
+
(`schnorrSign`, `schnorrVerify`, plus browser-friendly
|
|
528
|
+
`schnorrSignAsync` / `schnorrVerifyAsync` variants, the typed
|
|
529
|
+
`SchnorrSignError` exception, and the `SchnorrSignature` shape type)
|
|
530
|
+
for advanced consumers who need direct access without going through
|
|
531
|
+
`primitive.sign(...)`.
|
|
532
|
+
|
|
533
|
+
The per-version paragraphs below are compact deltas; for the full
|
|
534
|
+
authoritative per-version detail (Added / Changed / Fixed sections,
|
|
535
|
+
finding closures, file-level citations) see
|
|
536
|
+
[`CHANGELOG.md`](CHANGELOG.md). The README mirrors the headline only
|
|
537
|
+
and points readers at the changelog for the rest.
|
|
538
|
+
|
|
539
|
+
**v1.4.0** — `AccountSelectorData` now includes `public-key`,
|
|
540
|
+
`sovereign`, and `governor` for Smart Ouronet Account display (Σ.
|
|
541
|
+
prefix accounts with sovereign + governor authorisation paths).
|
|
542
|
+
|
|
543
|
+
**v1.5.0** — re-exports `Leto` / `Artemis` / `Apollo` historical-curve
|
|
544
|
+
primitives + `createGen1Primitive` factory through the `./dalos`
|
|
545
|
+
subpath. NOT registered in `createDefaultRegistry()` — Ouronet stays
|
|
546
|
+
Genesis-only; consumers opt in.
|
|
547
|
+
|
|
548
|
+
**v1.6.0** — Smart Ouronet Account auth-path primitives. `/guard`
|
|
549
|
+
gains `classifyGuardKind`, `extractKeysetFromGuard`,
|
|
550
|
+
`analyzeSmartAccountAuthPaths` to discriminate the four guard shapes
|
|
551
|
+
and resolve the `enforce-one` over (account guard / sovereign /
|
|
552
|
+
governor). `buildRotateSovereignPactCode` is the first CFM function
|
|
553
|
+
targeting a Smart account's auth path.
|
|
554
|
+
|
|
555
|
+
**v1.6.1** — every internal `interactions/*` helper now honors the
|
|
556
|
+
active failover node (no more `createClient(PACT_URL)` pinned to
|
|
557
|
+
node2).
|
|
558
|
+
|
|
559
|
+
**v1.7.0** — `IKadenaKeypair` consolidated to a single canonical
|
|
560
|
+
declaration in `src/signing/types.ts`. The duplicate copies that lived
|
|
561
|
+
across `interactions/*` are replaced with `import type` re-exports.
|
|
562
|
+
Closes audit finding F-CORE-001 (CRITICAL).
|
|
563
|
+
|
|
564
|
+
**v2.0.0** — wallet subpath layering restored + `pactRead` injection
|
|
565
|
+
seam fully adopted. Closes F-CORE-005 + F-CORE-006 (HIGH). **Two
|
|
566
|
+
breaking changes** for consumers — see migration guide below.
|
|
567
|
+
|
|
568
|
+
**v2.0.1** — documentation/release-process patch. Adds `CHANGELOG.md`
|
|
569
|
+
to the npm tarball, auto-creates GitHub Releases on tag push, and
|
|
570
|
+
backfills Releases for v1.7.0 and v2.0.0. No runtime change.
|
|
571
|
+
|
|
572
|
+
**v2.0.2 / v2.0.3 / v2.0.4** — release-pipeline hardening patches. No
|
|
573
|
+
runtime change. v2.0.2 added `permissions: contents: write` to
|
|
574
|
+
`publish.yml` for the GitHub Releases step. v2.0.3 introduced a
|
|
575
|
+
`RELEASE_TOKEN` PAT fallback expression to bypass org-locked
|
|
576
|
+
`GITHUB_TOKEN` write permissions. v2.0.4 triggered the workflow with
|
|
577
|
+
the secret installed.
|
|
578
|
+
|
|
579
|
+
**v2.1.0** — reliability hardening release. New `getFailoverClient(chainId, options?)`
|
|
580
|
+
factory composes `withFailover` + per-tier timeout into one reusable
|
|
581
|
+
surface; all 81 legacy `createClient(getPactUrl(chainId))` invocations
|
|
582
|
+
across the 11 interaction files now route through it (primary node
|
|
583
|
+
failure on any chain call now triggers automatic fallback retry).
|
|
584
|
+
Bounded timeouts on every chain-call tier (read 15s, submit 60s,
|
|
585
|
+
listen 180s, pollOne 30s) with `Promise.race` + `AbortController`
|
|
586
|
+
defence-in-depth. New `runWithTimeout(operation, fn, timeoutMs)`
|
|
587
|
+
helper, new `createTimeoutError(...)` factory returning a
|
|
588
|
+
`SigningError { code: "TIMEOUT" }`, new `resetNodeFailover()` export
|
|
589
|
+
for test isolation, new `readTimeoutMs?: number` option on
|
|
590
|
+
`PactReader` and `rawCalibratedDirtyRead`. MINOR, non-breaking —
|
|
591
|
+
existing imports continue to work; the new surface is opt-in.
|
|
592
|
+
|
|
593
|
+
**v2.1.2** — concurrency-race correction in `withFailover`. PATCH, no
|
|
594
|
+
public API change. The retry guard now uses per-invocation captured
|
|
595
|
+
base URLs (`attemptedBaseUrl` AND `attemptedPrimaryBaseUrl` captured
|
|
596
|
+
at fn-entry as local consts) instead of reading the shared
|
|
597
|
+
module-level `currentHost === PRIMARY_HOST` at catch-time. This makes
|
|
598
|
+
the catch-block decision robust to concurrent module-state mutation
|
|
599
|
+
(sibling `withFailover` flip, mid-flight `setNodeConfig`, mid-flight
|
|
600
|
+
`resetNodeFailover`). Closes F-BUG-001. New module-private
|
|
601
|
+
`getPrimaryBaseUrl()` helper added to `src/network/nodeFailover.ts`;
|
|
602
|
+
not exported.
|
|
603
|
+
|
|
604
|
+
**v2.2.0** — crypto error-taxonomy + test-coverage hardening release.
|
|
605
|
+
MINOR, additive. The `./crypto` subpath gains three typed error
|
|
606
|
+
classes — `WrongPasswordError`, `CorruptEnvelopeError`,
|
|
607
|
+
`UnsupportedFormatError` — that discriminate decryption failure modes
|
|
608
|
+
(closes F-CORE-009). `smartDecrypt` switches to single-path dispatch
|
|
609
|
+
via the existing `isEncryptedV2` shape predicate, eliminating the
|
|
610
|
+
~1.5s wall-time differential a wrong-password V1 input previously
|
|
611
|
+
exhibited (timing-leak fix); the V1 catch path no longer logs to
|
|
612
|
+
`console.error` and propagates the original failure via ES2022
|
|
613
|
+
`Error.cause`. Existing `instanceof Error` checks and `error.message`
|
|
614
|
+
access continue to work — the new typed-class discrimination is
|
|
615
|
+
opt-in. Test coverage expands across 4 previously-untested critical
|
|
616
|
+
surfaces (closes F-CORE-011, F-CORE-012): four new test files cover
|
|
617
|
+
the `pactReader` injection seam (`tests/pact-reader.test.ts`),
|
|
618
|
+
`KadenaWalletBuilder` mnemonic dispatch with vendor-vector pinning for
|
|
619
|
+
all three seed types (`tests/wallet-builder.test.ts`), every
|
|
620
|
+
documented branch of `createSigningError` + `createSimulationError`
|
|
621
|
+
(`tests/transaction-errors.test.ts`), and the codex seed-type
|
|
622
|
+
migration round-trip (`tests/seed-type-migration.test.ts`). Five
|
|
623
|
+
existing test files gain extensions: `tests/encryption.test.ts`,
|
|
624
|
+
`tests/encryption-upgrade.test.ts`, `tests/codex-codec.test.ts`,
|
|
625
|
+
`tests/cfm-builders.test.ts`, `tests/pact-format.test.ts`. F-CORE-010
|
|
626
|
+
(a proposed `pactString` charset/blocklist helper) was reviewed and
|
|
627
|
+
explicitly **rejected** — chain-side Pact validation already enforces
|
|
628
|
+
identifier rules, so a client-side blocklist would duplicate
|
|
629
|
+
authoritative server-side checks and risk silent drift if Pact's
|
|
630
|
+
grammar evolves. The decision is logged in `CHANGELOG.md` under a
|
|
631
|
+
`### Rejected (decisions log)` section.
|
|
632
|
+
|
|
633
|
+
**v2.3.0** — medium-and-low audit closures release. MINOR, additive.
|
|
634
|
+
Closes 13 audit findings grouped into two milestones: **M1 — 7
|
|
635
|
+
MEDIUM tier** (F-CORE-013 codex shape validation; F-CORE-014
|
|
636
|
+
foreign-key resolver pre-flight in `CodexSigningStrategy`; F-CORE-015
|
|
637
|
+
`safeCreationTime` DRY refactor — 11 inline copies removed across
|
|
638
|
+
`src/interactions/*Functions.ts`, all routed through the canonical
|
|
639
|
+
declaration in `src/pact/format.ts`; F-CORE-016a tightened
|
|
640
|
+
`classifyGuardKind` requiring full minimal shape per kind; F-CORE-016b
|
|
641
|
+
new `normalizeKeysetRef` helper at the `resolveGuard` boundary;
|
|
642
|
+
F-CORE-016c `SmartAccountAuthPathsAnalysis` JSDoc enumerating 4
|
|
643
|
+
reachable states + optional `firstSignableButUnsatisfied` field;
|
|
644
|
+
F-CORE-017 typed `UnknownPredicateError` class re-exported from
|
|
645
|
+
`./guard` plus `predicateRecognized: false` bit on `analyzeGuard`'s
|
|
646
|
+
returned analysis, replacing the previous silent `console.warn`
|
|
647
|
+
diagnostic) and **M2 — 6 LOW tier** (F-CORE-018a README header
|
|
648
|
+
version table refresh; F-CORE-018b CONTEXT.md interactions section
|
|
649
|
+
refresh covering v1.4 / v1.5 / v1.6 additions; F-CORE-019 catch-block
|
|
650
|
+
consistency in `ouroFunctions.ts` — all 7 affected catch sites now
|
|
651
|
+
route via `getLogger().error(...)` from `../observability`; F-CORE-020
|
|
652
|
+
tier-semantics JSDoc on `pactReader.ts` and `rawCalibratedRead.ts`
|
|
653
|
+
enumerating the canonical T1=balance / T2=preview / T3=metadata /
|
|
654
|
+
T7=very-static mapping; F-CORE-021 dead try/catch wrapping
|
|
655
|
+
`getLPTypeInfo`'s `Promise.all` removed (Option A — the
|
|
656
|
+
"comment as belt-and-braces" alternative was explicitly rejected);
|
|
657
|
+
F-CORE-022 central logger seam at `./observability` with two-file
|
|
658
|
+
source layout `src/observability/{index.ts,logger.ts}`, `Logger` type
|
|
659
|
+
+ `setLogger` (throws `TypeError("setLogger requires a non-null
|
|
660
|
+
Logger")` on null/undefined input) + `getLogger` exports, and a
|
|
661
|
+
sweep that reroutes every `console.warn` / `console.error` in `src/`
|
|
662
|
+
through the seam — verified by `grep -nE "console\.(warn|error)"
|
|
663
|
+
src/` returning ZERO matches outside the seam itself). Two new
|
|
664
|
+
public surfaces ship in lockstep: `UnknownPredicateError` on
|
|
665
|
+
`./guard` and the `./observability` subpath. All changes additive;
|
|
666
|
+
no existing exports change shape.
|
|
667
|
+
|
|
668
|
+
**v3.0.0** — fabricated-fallbacks-removal release. **BREAKING.**
|
|
669
|
+
Closes M3 from the 2026-04-30 audit cycle (lead finding F-CORE-007
|
|
670
|
+
HIGH plus the comprehensive ~24-site catalog sweep). First major
|
|
671
|
+
bump since v2.0.0. **Phase 1 — critical pricing functions (4
|
|
672
|
+
BREAKING widenings):** `getStoaPriceUSD`, `getTokenDecimals`,
|
|
673
|
+
`getPoolTotalFee`, `getDPTFMinMove` all widen from `Promise<number>`
|
|
674
|
+
to `Promise<number | null>`; the previous `1.0` / `0` / `8`
|
|
675
|
+
fabrication sentinels are replaced with `null`, and
|
|
676
|
+
`Number.isFinite()` guards catch `NaN` from malformed chain data
|
|
677
|
+
(e.g. `parseInt("abc", 10)` or `parseFloat(String(undefined))`).
|
|
678
|
+
**Phase 2 — catalog sweep + bonus extras + magic-strings (12
|
|
679
|
+
BREAKING widenings):** the 4-function string-balance cluster
|
|
680
|
+
(`getIgnisBalance`, `getAccountTokenSupply`, `getOuroDispoCapacity`,
|
|
681
|
+
`getVirtualOuro`) widens uniformly to `Promise<string | null>`;
|
|
682
|
+
`LPTypeInfo` field types widen to `boolean | null` per inner flag
|
|
683
|
+
(Approach A — function return type unchanged; chain-failure-status
|
|
684
|
+
returns `false`, catch returns `null`, success returns `true`); the
|
|
685
|
+
urStoa trio (`getUrStoaBalance`, `getUrStoaGuard`,
|
|
686
|
+
`checkCoinAccountExists`) widens to nullable returns and
|
|
687
|
+
`getUrStoaGuard` drops its sentinel `empty` shape; `validateLiquidity`
|
|
688
|
+
gains an optional `error?: string` field on its mixed shape (preserves
|
|
689
|
+
`valid: boolean` — consumers route a populated `error` to the
|
|
690
|
+
network-failure banner and a `valid: false` with no `error` to the
|
|
691
|
+
validation-failure message); `getMaxBuyMovieBooster` widens to
|
|
692
|
+
`Promise<number | null>`; magic-string sentinels disappear from
|
|
693
|
+
`getSWPSpawnLimit` and `getSWPInactiveLimit` (now `Promise<string |
|
|
694
|
+
null>` — consumers swap `=== "N/A"` for `=== null`). **Phase 3 —
|
|
695
|
+
logger parity (14 NON-BREAKING):** `getLogger().error("Error in
|
|
696
|
+
<funcName>:", error)` routing lands in 14 previously-silent catches
|
|
697
|
+
across 5 files (`dexFunctions.ts`, `ouroFunctions.ts`,
|
|
698
|
+
`activateFunctions.ts`, `infoOneFunctions.ts`, and the
|
|
699
|
+
`urStoaFunctions.ts` private helpers `verifyEd25519Sig` +
|
|
700
|
+
`describeKeyset`) — completes the silent-catch elimination sweep
|
|
701
|
+
started in v2.3.0. NO public-API removals (NFR-03): all 16 modified
|
|
702
|
+
functions keep their names + parameter signatures; only return types
|
|
703
|
+
widen. See the new **Migrating to v3.x** H2 section below for
|
|
704
|
+
per-cluster `Before:` / `After:` migration patterns and the locked
|
|
705
|
+
Option B / Approach A / mixed-shape / 3-state-preservation /
|
|
706
|
+
magic-string-removal decisions (Q3..Q11) embedded verbatim.
|
|
707
|
+
|
|
708
|
+
**v3.1.0** — dalos-crypto v4.0.3 integration + Schnorr surface
|
|
709
|
+
re-exports + locale-determinism fix. **MINOR, additive.** Bumps the
|
|
710
|
+
`@ouronet/dalos-crypto` dep from `^1.2.0` to `^4.0.3` (per the
|
|
711
|
+
upstream v4.0.0 changelog: TypeScript consumers see no breaking
|
|
712
|
+
surface changes across the v1.2.0 → v4.0.3 jump — the v4.0.0 major
|
|
713
|
+
bump was driven entirely by a Go-reference reorganisation, not the
|
|
714
|
+
TS port). The `./dalos` subpath gains direct re-exports of the
|
|
715
|
+
**Schnorr signature surface** for advanced consumers:
|
|
716
|
+
`schnorrSign` / `schnorrVerify` for synchronous use; the
|
|
717
|
+
browser-friendly `schnorrSignAsync` / `schnorrVerifyAsync` async
|
|
718
|
+
variants that yield to the event loop on a fixed data-independent
|
|
719
|
+
cadence (the upstream package's REQ-14 yield-count constant-time
|
|
720
|
+
test verifies the cadence is data-independent and constant-time);
|
|
721
|
+
the typed `SchnorrSignError` exception class for `instanceof` catch
|
|
722
|
+
blocks; and the `SchnorrSignature` shape type for parameter typing.
|
|
723
|
+
The high-level `primitive.sign(keyPair, message)` path through the
|
|
724
|
+
registry is unchanged (it has always been Schnorr internally for
|
|
725
|
+
DalosGenesis); the new direct-access surface is opt-in and exists
|
|
726
|
+
mainly so OuronetUI's browser path can use the `*Async` variants to
|
|
727
|
+
keep INP under the 200 ms budget during signing. Also fixes
|
|
728
|
+
`formatMaxFee` in `./gas` to pin its `toLocaleString()` call to
|
|
729
|
+
`'en-US'` so the ANU thousands separator is `,` on every host (was
|
|
730
|
+
host-locale-dependent — silently passed CI on en-US Linux while
|
|
731
|
+
failing locally on a German-locale host); the test suite was already
|
|
732
|
+
pinning the en-US shape, so this restores cross-host parity. NO
|
|
733
|
+
public-API removals or shape changes; all changes additive. See the
|
|
734
|
+
v3.1.0 **CHANGELOG.md** entry for the full per-symbol export list,
|
|
735
|
+
the audit-trail of the 18 dalos-crypto symbols verified
|
|
736
|
+
shape-compatible at upgrade time, and the verification-gate results
|
|
737
|
+
(typecheck + 558/558 tests + build all green).
|
|
738
|
+
|
|
739
|
+
**v3.1.1** — pre-publish audit-cycle close-out for the v3.1.0
|
|
740
|
+
dalos-crypto integration. **PATCH, additive.** Closes 5 audit
|
|
741
|
+
findings the post-v3.1.0-integration audit (2026-05-05) flagged
|
|
742
|
+
against commit `bf10dc1` before that commit reached npm: 3 typed
|
|
743
|
+
validation-error class re-exports added to `./dalos`
|
|
744
|
+
(`InvalidBitStringError`, `InvalidBitmapError`,
|
|
745
|
+
`InvalidPrivateKeyError` — close F-BUG-005 by completing the
|
|
746
|
+
`instanceof`-discrimination surface); 1 type-only re-export added
|
|
747
|
+
(`CoordAffine` — closes F-API-024 by restoring the "single
|
|
748
|
+
integration surface" promise for `SchnorrSignature.r`); 1
|
|
749
|
+
stylistic alignment (`src/dalos/{index,account}.ts` converted
|
|
750
|
+
from single quotes + `.js` extensions to the codebase's standard
|
|
751
|
+
double quotes + bare relative imports — closes F-ARCH-012); 1
|
|
752
|
+
test-strictness fix (`tests/gas.test.ts` `formatMaxFee` assertion
|
|
753
|
+
tightened from `toMatch(/10,000,000/)` substring regex to strict
|
|
754
|
+
`toBe("10,000,000")` — closes F-TEST-001 so the v3.1.0
|
|
755
|
+
locale-determinism contract is actually locked); and 1 fresh
|
|
756
|
+
test block (`tests/dalos-integration.test.ts` gains coverage for
|
|
757
|
+
the v3.1.0 Schnorr re-exports — closes F-TEST-004 with 5
|
|
758
|
+
new it-blocks covering sign/verify round-trip, async variants,
|
|
759
|
+
`SchnorrSignError` class identity, and `SchnorrSignature` /
|
|
760
|
+
`CoordAffine` type-import compile probes). v3.1.0 was committed
|
|
761
|
+
locally (`bf10dc1`) but never pushed to npm, so the npm registry
|
|
762
|
+
goes from `3.0.0` straight to `3.1.1` with v3.1.0 visible only in
|
|
763
|
+
the GitHub commit history. **565/565 tests pass** (was 558 in
|
|
764
|
+
v3.1.0; +7 = 1 new strict locale grouping-style sibling
|
|
765
|
+
assertion + 5 new Schnorr re-export it-blocks + 1 new
|
|
766
|
+
validation-error class probe).
|
|
767
|
+
|
|
768
|
+
**v3.2.0** — number-hygiene infrastructure for the v3.2.x
|
|
769
|
+
audit-cycle close-out track. **MINOR, additive.** First wave of the
|
|
770
|
+
v3.2.x sequence (v3.2.0 = infrastructure / v3.2.1 = apply at call
|
|
771
|
+
sites / v3.2.2 = delete dead multi-step add liquidity / v3.2.3 =
|
|
772
|
+
targeted bug fixes). v3.2.0 lands three additive surfaces in the
|
|
773
|
+
`./pact` subpath: (1) `formatDecimalForPact` now accepts a single
|
|
774
|
+
comma as decimal separator and normalises it to a period before
|
|
775
|
+
validation, so European-locale UI inputs (`"1,5"`, `"0,9"`,
|
|
776
|
+
`"1234,567890"`) work without upstream normalisation; multi-comma
|
|
777
|
+
strings (`"1,234,567"` thousand-separator-style) and mixed
|
|
778
|
+
period+comma strings (`"1,5.6"`, `"1.234,56"`) still throw because
|
|
779
|
+
they are ambiguous. (2) New `formatIntegerForPact(amount: string):
|
|
780
|
+
ValidatedInteger` sibling helper for integer-typed Pact arguments
|
|
781
|
+
— Pact distinguishes integers from decimals at the lexer level
|
|
782
|
+
(`integer` cap-args reject `1.0`, accept `1`); the new helper
|
|
783
|
+
validates `^\d+$` and returns the trimmed input verbatim with no
|
|
784
|
+
float round-trip, so 100-digit integer strings round-trip
|
|
785
|
+
byte-identical (versus `Number(big)` which collapses past
|
|
786
|
+
`Number.MAX_SAFE_INTEGER` ≈ `9.0e15`). (3) Two new branded
|
|
787
|
+
TypeScript types `ValidatedDecimal` and `ValidatedInteger` (zero
|
|
788
|
+
runtime cost — just `unique symbol` brands on `string`) flow out
|
|
789
|
+
of the formatters; functions declared `(amount: ValidatedDecimal)
|
|
790
|
+
=> Transaction` cannot accidentally accept raw user input, and the
|
|
791
|
+
two brands are distinct types so the lexer-level int-vs-decimal
|
|
792
|
+
distinction is enforced at the function-boundary level. The
|
|
793
|
+
file-level JSDoc in `src/pact/format.ts` now spells out the
|
|
794
|
+
three-rule number-hygiene contract: strings in, strings out, never
|
|
795
|
+
round-trip through float64. NO consumer-visible behaviour change
|
|
796
|
+
— every previously-valid input produces byte-identical output;
|
|
797
|
+
the new surface is opt-in. v3.2.1 will adopt the new helpers at
|
|
798
|
+
the existing `parseFloat(...).toFixed(N)` and raw `${amount}`
|
|
799
|
+
interpolation sites to close the F-SEC-001 / F-BUG-003
|
|
800
|
+
precision-loss vectors that the 2026-05-05 audit flagged.
|
|
801
|
+
|
|
802
|
+
**v3.2.1** — applies the v3.2.0 number-hygiene helpers at the four
|
|
803
|
+
chain-call sites flagged by the 2026-05-05 audit. **MINOR,
|
|
804
|
+
behaviour change.** Closes **F-SEC-001** (Pact-code injection vector
|
|
805
|
+
in urStoa stake/unstake's raw `${amount}` interpolation) and
|
|
806
|
+
**F-BUG-003** (`parseFloat(amount).toFixed(N)` silent precision loss
|
|
807
|
+
in `buildCrossChainTransfer:92` and `executeNativeUrStoaTransfer:206`,
|
|
808
|
+
plus silent rounding `1.9999 → 2.000` in the urStoa transfer path).
|
|
809
|
+
All four sites now route through `formatDecimalForPact(amount)`:
|
|
810
|
+
malformed input throws synchronously before any chain interaction
|
|
811
|
+
begins (counting-stub `PactReader` test proves the reader is never
|
|
812
|
+
invoked when the amount is malformed — validation is at the function
|
|
813
|
+
boundary, not deeper); arbitrary-precision decimals round-trip
|
|
814
|
+
byte-identical (39-digit integer amounts and 18-digit-fractional
|
|
815
|
+
decimals that pre-v3.2.1's float-based formatters would have
|
|
816
|
+
truncated or scientific-notation-mangled now reach the chain
|
|
817
|
+
intact); EU-locale comma input is auto-normalised to period (per
|
|
818
|
+
v3.2.0's relaxed input contract); and the urStoa stake/unstake
|
|
819
|
+
cap-args now reuse the **same** validated string as the pact-code
|
|
820
|
+
interpolation, so the `coin.URV|STAKE` / `coin.URV|UNSTAKE` cap-arg
|
|
821
|
+
and the executed `coin.C_URV|Stake` / `coin.C_URV|Unstake` decimal
|
|
822
|
+
literal are guaranteed to agree (was `String(numAmount)` separately
|
|
823
|
+
which had the float-precision drift). The `numAmount: number` field
|
|
824
|
+
on `StakeUrStoaParams` and `UnstakeUrStoaParams` is **deprecated** in
|
|
825
|
+
v3.2.1 (still accepted on the interfaces for v3.x backwards
|
|
826
|
+
compatibility, no longer read by the executors; will be removed in
|
|
827
|
+
v4.0.0). 8 new it-blocks in `tests/interactions-decimal-validation.test.ts`
|
|
828
|
+
pin the contract: synchronous throw on malformed input, pact-code
|
|
829
|
+
contains comma-normalised value, high-precision and 39-digit-int
|
|
830
|
+
amounts preserved past pre-v3.2.1's truncation point, reader-stub
|
|
831
|
+
proves fail-fast at function entry. NO consumer-side migration
|
|
832
|
+
required for callers passing well-formed decimal strings; consumers
|
|
833
|
+
that previously relied on silent `"NaN"` interpolation or
|
|
834
|
+
silent-rounding need to wrap calls in try/catch (the throw is the
|
|
835
|
+
audit-mandated improvement).
|
|
836
|
+
|
|
837
|
+
**v3.2.2** — removes the dead multi-step add-liquidity surface from
|
|
838
|
+
`src/interactions/addLiquidityFunctions.ts`. **MINOR, public API
|
|
839
|
+
removal.** Closes **F-ERR-005**, **F-ERR-014**, **F-PERF-014**,
|
|
840
|
+
**F-PERF-015**, and **F-API-026** — five audit findings
|
|
841
|
+
simultaneously, all by removal rather than fix. The historical
|
|
842
|
+
multi-step pipeline existed because Kadena chainweb's 150k-per-block
|
|
843
|
+
gas limit couldn't fit a single-block add-liquidity transaction;
|
|
844
|
+
StoaChain runs at 2M gas per block (13×), which fits the entire
|
|
845
|
+
flow in one transaction. OuronetUI hasn't called the multi-step
|
|
846
|
+
path since the gas-limit increase, and no test in this package's
|
|
847
|
+
suite exercised it — both signals that the four exported
|
|
848
|
+
`executeAddLiquidityMultiStep*` functions plus their
|
|
849
|
+
`MultiStepAddLiquidityResult` return type plus the unused
|
|
850
|
+
`_strategy` parameter on `executeAddLiquidity` were dead public
|
|
851
|
+
surface carrying real correctness risk (F-ERR-005's
|
|
852
|
+
`.includes(...)` crash on non-Error throws; F-ERR-014's
|
|
853
|
+
listen-timeout-vs-submit-failure conflation that could cause user
|
|
854
|
+
double-pay; F-PERF-014's 4× hardcoded 3-second sleeps adding ~6s
|
|
855
|
+
to every successful flow; F-PERF-015's retry loops against
|
|
856
|
+
string-matched `error.message`). Net code change: **−338 lines**
|
|
857
|
+
(1031 → 693 in `addLiquidityFunctions.ts`). The Pact-side defpact
|
|
858
|
+
contract (`TS01-CP.SWP|C_AddStandardLiquidity` with continuation
|
|
859
|
+
steps) is still on chain for historical interoperability;
|
|
860
|
+
consumers with unusual need can still invoke it via
|
|
861
|
+
`@kadena/client`'s low-level `Pact.builder.continuation()` API.
|
|
862
|
+
Migration: callers of `executeAddLiquidityMultiStep*` should
|
|
863
|
+
switch to `executeAddLiquidity(params)`, same `AddLiquidityParams`
|
|
864
|
+
shape, single-step path. Callers passing `_strategy` to
|
|
865
|
+
`executeAddLiquidity` should drop the second argument (the
|
|
866
|
+
function's behaviour is identical — it always called the
|
|
867
|
+
single-step path anyway). Strict-semver-wise the removal is
|
|
868
|
+
breaking and would justify a MAJOR bump; classified MINOR for
|
|
869
|
+
v3.2.2 because the removed surface had no known consumer
|
|
870
|
+
(verified via repo-wide grep + user confirmation).
|
|
871
|
+
|
|
872
|
+
**v3.2.3** — final wave of the v3.2.x audit-cycle close-out track.
|
|
873
|
+
**MINOR, behaviour change.** Four targeted bug fixes closing the
|
|
874
|
+
highest-user-impact remaining findings: **F-BUG-002** added
|
|
875
|
+
`creationTime: safeCreationTime()` to `buildCrossChainTransfer`
|
|
876
|
+
setMeta (the lone interactions/* builder that omitted the helper
|
|
877
|
+
post v2.3.0's DRY sweep, causing sporadic chain-side rejections
|
|
878
|
+
under client-clock drift); **F-BUG-004** rewrote `fetchSpvProof` to
|
|
879
|
+
wrap in `withFailover` + 30-second `AbortSignal.timeout()` —
|
|
880
|
+
pre-v3.2.3 this was the only chain-RPC function calling raw
|
|
881
|
+
`fetch()` without either guard, with the consequence that a wedged
|
|
882
|
+
primary node hung cross-chain transfers indefinitely with the
|
|
883
|
+
user's KDA committed to `kadena-xchain-gas` escrow on the source
|
|
884
|
+
chain and no recovery path (the highest-impact bug surfaced by the
|
|
885
|
+
2026-05-05 audit); **F-SEC-002** added URL parse + `https:` scheme
|
|
886
|
+
allow-list to `setNodeConfig`'s custom-URL path — pre-v3.2.3 it
|
|
887
|
+
accepted any truthy string and assigned it to `PRIMARY_HOST`,
|
|
888
|
+
allowing an attacker-controlled custom-node setting to redirect
|
|
889
|
+
every signed transaction (now throws `TypeError` on missing,
|
|
890
|
+
unparseable, or non-https customUrl, with the parsed origin only
|
|
891
|
+
stored to discard pathname/query/fragment); **F-ERR-001** added
|
|
892
|
+
`@throws` JSDoc to the three `crossChainFunctions` submit/listen
|
|
893
|
+
helpers — documentation-only, no runtime change, but the
|
|
894
|
+
`listenForCompletion` JSDoc now explicitly calls out that a
|
|
895
|
+
TIMEOUT must be treated as `pending` (poll via
|
|
896
|
+
`pollTransactionStatus`) **not** as `failed` (do NOT retry the
|
|
897
|
+
submit, which would double-pay gas for a transaction that may
|
|
898
|
+
already be confirmed). 17 new it-blocks in
|
|
899
|
+
`tests/v3-2-3-bug-fixes.test.ts` cover all four fixes; 2 existing
|
|
900
|
+
`tests/network.test.ts` tests updated to reflect the new
|
|
901
|
+
`setNodeConfig` throw-on-malformed-input contract.
|
|
902
|
+
|
|
903
|
+
**v3.2.x sequence completed** — 15 audit findings closed across 4
|
|
904
|
+
ship cycles (v3.2.0 infrastructure / v3.2.1 apply-formatters /
|
|
905
|
+
v3.2.2 delete-multi-step / v3.2.3 targeted-bug-fixes). Combined
|
|
906
|
+
with v3.1.1's 5 audit-cycle gaps, the v3.x line has remediated
|
|
907
|
+
**20 audit findings** total. The remaining ~47 confirmed findings
|
|
908
|
+
are scheduled for v3.3.x (logger-seam completion + test coverage
|
|
909
|
+
+ documentation cleanups) and v4.0.0 (structural decomposition +
|
|
910
|
+
monorepo split into `@stoachain/stoa-core` + `@ouronet/ouronet-core`
|
|
911
|
+
+ type consolidation + `readonly` on public types + nullable
|
|
912
|
+
widening for the 10 swap functions).
|
|
913
|
+
|
|
914
|
+
**v3.3.0** — Logger seam completion. **MINOR, additive + behaviour
|
|
915
|
+
change.** First release in the v3.3.x cleanup track. Closes the
|
|
916
|
+
consolidated **F-LOGGER-SEAM-001** finding (9 distinct source sites
|
|
917
|
+
flagged by 8 of 8 audit agents — the highest-redundancy finding in
|
|
918
|
+
the entire 2026-05-05 audit). v3.2.2's `executeAddLiquidityMultiStepComplete`
|
|
919
|
+
deletion already removed 2 of the 9 sites by removal; v3.3.0 closes
|
|
920
|
+
the remaining 7 — `transactionErrors.ts:252-261` (3 calls in
|
|
921
|
+
`logDetailedError`), `nodeFailover.ts:61` (primary-recovery
|
|
922
|
+
announcement), `infoOneFunctions.ts:599-600` (debug-leak in remove-
|
|
923
|
+
liquidity preview), `ouroFunctions.ts:1590,1595` (Coil preview
|
|
924
|
+
failure path + success-path data dump), and `urStoaFunctions.ts:348`
|
|
925
|
+
(signature-pruning announcement). 4 of those 7 are routed through
|
|
926
|
+
the seam (`getLogger().info` for ops events, `getLogger().warn` for
|
|
927
|
+
unusual operational events worth structured-log capture, folded
|
|
928
|
+
into existing `getLogger().error` calls where grouping framing was
|
|
929
|
+
the only thing using `console.group`); 3 are deleted as
|
|
930
|
+
debug-leak (the `console.log` calls flagged by the audit as
|
|
931
|
+
"left-over dev instrumentation" with no operational value beyond
|
|
932
|
+
developer trace). The `Logger` interface gains an `info(msg,
|
|
933
|
+
...args): void` channel — the missing surface that caused 4 of
|
|
934
|
+
the 7 seam violations (the seam previously exposed only `warn` and
|
|
935
|
+
`error`, so `info`-class events fell through to raw `console.info`
|
|
936
|
+
that bypassed consumer-supplied loggers). v3.3.0's `setLogger`
|
|
937
|
+
accepts BOTH the v3.2.x 2-method input shape (`{warn, error}` —
|
|
938
|
+
synthesised wrapper fills in `info` from default `console.info`
|
|
939
|
+
routing) AND the v3.3.0 3-method input shape (`{warn, error, info}`
|
|
940
|
+
— reference identity preserved). Backwards-compat is automatic;
|
|
941
|
+
v3.2.x consumers see no behaviour change unless they were emitting
|
|
942
|
+
to one of the seven raw-console sites that no longer exist. New
|
|
943
|
+
regression-lock test in `tests/v3-3-0-logger-seam-completion.test.ts`
|
|
944
|
+
scans the entire `src/` tree on every run and fails on any future
|
|
945
|
+
commit that re-introduces a raw `console.*` call (filters out
|
|
946
|
+
JSDoc/comments + the seam's own intentional default-logger
|
|
947
|
+
implementation in `observability/logger.ts`). The audit's
|
|
948
|
+
consolidated finding becomes a permanent invariant rather than a
|
|
949
|
+
one-time cleanup. NO breaking changes: every previously-valid
|
|
950
|
+
consumer call shape continues to work; new surface is opt-in.
|
|
951
|
+
|
|
952
|
+
**v3.3.x trajectory ahead:** test coverage completion (F-TEST-002
|
|
953
|
+
adding `tests/universal-sign.test.ts` for the chainweaver/
|
|
954
|
+
eckowallet/foreign branches; F-TEST-005 adding success-path tests
|
|
955
|
+
for the 13 v3.0.0 nullable-widened functions; F-TEST-006 adding
|
|
956
|
+
behavioural tests for `pensionFunctions`/`guardFunctions`/
|
|
957
|
+
`infoOneFunctions`); various documentation cleanups (deprecate
|
|
958
|
+
`KADENA_BASE_URL`, fix `CreateAccountOptions` JSDoc, etc.).
|
|
959
|
+
v4.0.0 is the major structural release (monorepo split into
|
|
960
|
+
`@stoachain/stoa-core` + `@ouronet/ouronet-core`, god-file
|
|
961
|
+
decomposition, type consolidation, `readonly` modifiers across
|
|
962
|
+
the public type surface).
|
|
963
|
+
|
|
964
|
+
**v4.1.1** — audit-closure patch. **PATCH (atomic with `@stoachain/stoa-core@4.1.1` + `@stoachain/kadena-stoic-legacy@4.1.1`).** Closes 7 STILL-OPEN audit findings: F-ERR-022 (fabricated `"0"` fallbacks in `kadenaFunctions.ts` lines 16+27 dropped — `getBalance` and `accountDescription` now throw a typed `KadenaShapeError` (extends Error with ES2022 `cause`) on shape-mismatched RPC envelopes; legitimate fallbacks at lines 28-29 preserved), F-API-005 (`getSublimateInfo` dedup — duplicate body removed from `ouroFunctions.ts:2148` and replaced with a `@deprecated` JSDoc compat shim that adapts the legacy signature; canonical at `infoOneFunctions.ts:179`; shim removed in v4.2.0), F-API-006 (`describeKeyset` dedup with `describeKeysetOrNull` adapter helper that preserves the two behaviors the canonical does NOT have: `pred ?? "keys-all"` coercion + map-keys-not-array-to-null), F-API-007 (byte-identical `EncryptedDataV1` collapsed into a re-export of `EncryptedData` from `crypto/v1` in stoa-core), F-SEC-007 (codex strict-shape — `deserializeCodex` rejects envelopes with unknown top-level fields against KNOWN_TOP_LEVEL_FIELDS = {version, exportedAt, kadenaWallets, ouronetWallets, addressBook, uiSettings} via new `CodexUnknownFieldError`), F-BUG-010 (`migrateSeedType` no longer silently returns `"koala"` for unknown seed types — throws new `UnknownSeedTypeError` instead), F-API-014 (`getSparksBalance` return type narrowed from `Promise<any>` to `Promise<any | null>`). New file: `src/interactions/errors.ts` (`KadenaShapeError`). New codex/errors.ts contains `CodexUnknownFieldError` + `UnknownSeedTypeError`. Test count: ~330 (was 261; +~69 from 11 new v4-1-1-*.test.ts files: kadena-no-fallbacks, codec-strict-shape, seed-type-strict, seed-type-dedup, sparks-balance-narrow, dist-structure, esm-roundtrip, type-preservation, doc-gates, migration-doc-validity, package-metadata, peer-dep-coverage, full-chain-integration, cross-package-version-pin, publish-workflow-simulation, coil-functions-memoization). NO breaking changes — `getSublimateInfo` deprecation shim preserves backward compatibility for one release. See `MIGRATION-v4.1.md` v4.1.1 appendix at the monorepo root for caller-impact details.
|
|
965
|
+
|
|
966
|
+
**v4.1.0** — sovereign supply-chain migration. **MINOR (atomic with `@stoachain/stoa-core@4.1.0` + `@stoachain/kadena-stoic-legacy@4.1.0`).** Retargets all 12 internal `@kadena/*` imports in `src/interactions/` to the new sibling subpaths under [`@stoachain/kadena-stoic-legacy`](https://www.npmjs.com/package/@stoachain/kadena-stoic-legacy) — a sovereign vendoring of `@kadena/{client,cryptography-utils,types,hd-wallet}` under StoaChain stewardship, born at v4.1.0 in response to Kadena LLC's dissolution and the resulting unmaintained-upstream supply-chain risk. The three `@kadena/*` peer-dep declarations (`@kadena/client`, `@kadena/cryptography-utils`, `@kadena/types`) are dropped from `package.json`; the peer-dep on `@stoachain/stoa-core` is bumped `4.0.1 → 4.1.0` (atomic-version invariant — all three packages always release at the same version); a new `@stoachain/kadena-stoic-legacy@4.1.0` peer-dep is added. Every `Pact.builder` call site across the 13 `interactions/*` modules rewires under the hood — the public function signatures (`getOuronetKdaDetails`, `getCoilPreviewGeneric`, every interactions function) keep byte-identical shape. Test count: **261** (was 218; +43 from the new `tests/v4-1-0-no-kadena-imports.test.ts` runtime regression-lock that asserts no `@kadena/*` literal appears in any built or source file). Release is atomic — `vX.Y.Z` git tag publishes all three packages simultaneously via `.github/workflows/publish.yml` in dependency order (kadena-stoic-legacy first, stoa-core second, ouronet-core third), each with its own `--provenance` SLSA attestation. **No consumer migration required** for subpath imports — every `interactions/*` and `pact/cfm` surface is unchanged.
|
|
967
|
+
|
|
968
|
+
**v4.0.1** — cosmetic published-metadata cleanup. **PATCH.** 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) plus `@kadena/*` peer/dev duplicates. The npmjs.com page now shows zero `dependencies`, just the canonical `peerDependencies` (the `@kadena/*` set + `@stoachain/stoa-core@4.0.1` exact-pin). 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.** Regression-lock at `tests/package-version.test.ts` updated to assert `4.0.1`.
|
|
969
|
+
|
|
970
|
+
**v4.0.0** — monorepo split + deprecated-alias removal. **MAJOR,
|
|
971
|
+
breaking.** The structural refactor that v3.3.8 set up. The single
|
|
972
|
+
`@ouronet/ouronet-core` package was split into two atomic-release
|
|
973
|
+
npm packages under the new `StoaChain/stoa-js` GitHub monorepo:
|
|
974
|
+
[`@stoachain/stoa-core`](https://www.npmjs.com/package/@stoachain/stoa-core)
|
|
975
|
+
(chain-generic foundation — signing, wallet, crypto, network
|
|
976
|
+
failover, gas, guard, errors, observability, dalos, reads,
|
|
977
|
+
pact-format) + `@ouronet/ouronet-core` (this package — Ouronet
|
|
978
|
+
protocol business logic: codex codec, interactions/* function
|
|
979
|
+
library, `KADENA_NAMESPACE`, `STOA_AUTONOMIC_*` accounts, cfm Pact
|
|
980
|
+
builders). Both packages release atomically out of the monorepo at
|
|
981
|
+
the same version — a single `vX.Y.Z` git tag publishes both.
|
|
982
|
+
**Breaking removals**: the v3.3.8-deprecated `KADENA_BASE_URL` /
|
|
983
|
+
`PACT_URL` / `GAS_STATION` / `NATIVE_TOKEN_VAULT` aliases plus the
|
|
984
|
+
duplicate `IKadenaKeypair` interface in
|
|
985
|
+
`interactions/ouroFunctions.ts` were removed. Migration: use the
|
|
986
|
+
failover-aware `getPactUrl(chainId)` / `getSpvUrl(chainId)` from
|
|
987
|
+
`@stoachain/stoa-core/constants`; rename references to the canonical
|
|
988
|
+
`STOA_AUTONOMIC_OURONETGASSTATION` / `STOA_AUTONOMIC_LIQUIDPOT` (still
|
|
989
|
+
exported from `@ouronet/ouronet-core/constants`); `import type
|
|
990
|
+
{ IKadenaKeypair } from "@stoachain/stoa-core/signing"`. Consumers
|
|
991
|
+
using only the Ouronet-specific surface (codex, interactions, the
|
|
992
|
+
`ouronet-ns` namespace) can keep this package and bump the version.
|
|
993
|
+
Consumers using chain-generic surfaces must add `@stoachain/stoa-core`
|
|
994
|
+
and update the import paths — see
|
|
995
|
+
[`MIGRATION-v4.md`](https://github.com/StoaChain/stoa-js/blob/main/MIGRATION-v4.md)
|
|
996
|
+
at the monorepo root for the full upgrade map. **Internal moves**
|
|
997
|
+
(transparent if you stayed on subpath imports): chain-generic
|
|
998
|
+
constants moved to `@stoachain/stoa-core/constants` (re-exported
|
|
999
|
+
through `@ouronet/ouronet-core/constants` for source-level
|
|
1000
|
+
back-compat); `pact/cfmBuilders.ts` stays under
|
|
1001
|
+
`@ouronet/ouronet-core/pact` (uses `KADENA_NAMESPACE`); chain-generic
|
|
1002
|
+
`formatDecimalForPact` / `formatIntegerForPact` / `mayComeWithDeimal`
|
|
1003
|
+
/ `filterFreePositionData` / `formatEU` / `safeCreationTime` helpers
|
|
1004
|
+
moved to `@stoachain/stoa-core/pact`. **Dependency hardening**: all
|
|
1005
|
+
`@kadena/*` + `@noble/curves` + `@scure/bip39` +
|
|
1006
|
+
`@ouronet/dalos-crypto` peer/dev deps pinned to exact versions (no
|
|
1007
|
+
`^`) — prep work for v4.1.0's selective vendoring of `@kadena/client`
|
|
1008
|
+
(supply-chain hardening after Kadena LLC's dissolution). **CI
|
|
1009
|
+
workflow** rewritten for dual-package publish: a single `vX.Y.Z`
|
|
1010
|
+
tag now triggers two `npm publish` calls in dependency order
|
|
1011
|
+
(stoa-core first, ouronet-core second), each with its own
|
|
1012
|
+
`--provenance` SLSA attestation; per-package version-parity gates
|
|
1013
|
+
(README + CHANGELOG must reference the publish version on EACH
|
|
1014
|
+
package independently) preserve the v2.1.x staleness lessons.
|
|
1015
|
+
**703/703 tests pass** across the two packages (485 in stoa-core,
|
|
1016
|
+
218 in ouronet-core; up from v3.3.8's 698 because the
|
|
1017
|
+
F-ARCH-011/F-ARCH-012 v3.3.8 regression locks now live alongside
|
|
1018
|
+
their stoa-core SUTs — every prior test preserved).
|
|
1019
|
+
|
|
1020
|
+
**v3.3.8** — documentation/deprecation cleanup pass closing 5
|
|
1021
|
+
LOW-severity findings from the 2026-05-05 audit. **MINOR,
|
|
1022
|
+
additive.** **F-API-015** rewrote a stale JSDoc parameter
|
|
1023
|
+
mention in `src/dalos/account.ts` (the `strict` flag was never
|
|
1024
|
+
implemented; new wording documents the actual contract).
|
|
1025
|
+
**F-API-016** added `export` to the `CoilConfig` interface so
|
|
1026
|
+
consumers can type-annotate `CoilConfig` values directly
|
|
1027
|
+
without re-declaring the shape — one-word change, additive,
|
|
1028
|
+
consumer-facing improvement. **F-SEC-005 / F-ARCH-014** marked
|
|
1029
|
+
`KADENA_BASE_URL` `@deprecated` redirecting to the
|
|
1030
|
+
failover-aware `getActivePactUrl` / `getActiveSpvUrl` (or the
|
|
1031
|
+
same-subpath `getPactUrl` / `getSpvUrl` wrappers); the constant
|
|
1032
|
+
itself remains for backwards-compat, removal scheduled for
|
|
1033
|
+
v4.0.0. **F-ARCH-011** consolidated `normalizeKeysetRef`
|
|
1034
|
+
deep-import in `ouroFunctions.ts` to the `../guard` barrel,
|
|
1035
|
+
matching the project's subpath-import discipline. **F-ARCH-012**
|
|
1036
|
+
converted 19 single-quoted string literals to double quotes in
|
|
1037
|
+
`src/dalos/account.ts` — the only remaining drift after v3.1.1's
|
|
1038
|
+
fix to `src/dalos/index.ts`; TypeScript treats both forms as
|
|
1039
|
+
identical string literals at the type level (pure stylistic).
|
|
1040
|
+
NO breaking change. NO observable runtime behavior change. One
|
|
1041
|
+
new public-API export (`CoilConfig` interface). Locked at
|
|
1042
|
+
`tests/v3-3-8-doc-cleanup.test.ts` with 3 it-blocks across 3
|
|
1043
|
+
describe groups: T1 verifies the `CoilConfig` type export via
|
|
1044
|
+
`expectTypeOf`; T2 verifies `normalizeKeysetRef` is reachable
|
|
1045
|
+
through the `../guard` barrel and round-trips a
|
|
1046
|
+
keysetref-shaped object; T3 reads `src/dalos/account.ts` source
|
|
1047
|
+
verbatim and asserts no single-quoted string literals remain in
|
|
1048
|
+
code (English apostrophes inside JSDoc comments are exempt).
|
|
1049
|
+
F-API-015 (stale JSDoc) and F-SEC-005/F-ARCH-014 (`@deprecated`
|
|
1050
|
+
marker) are pure JSDoc changes that don't surface at runtime;
|
|
1051
|
+
the CHANGELOG entry is the audit trail. **+3 new tests**
|
|
1052
|
+
bringing the suite to **698/698 passing** (was 695 in v3.3.7).
|
|
1053
|
+
|
|
1054
|
+
**v3.3.7** — security pass closing two MEDIUM security findings
|
|
1055
|
+
from the 2026-05-05 audit in one bundled release. **MINOR,
|
|
1056
|
+
additive.** **F-SEC-003** ships `InvalidPactReaderError` and
|
|
1057
|
+
`InvalidLoggerError` (both extend `TypeError`) and tightens
|
|
1058
|
+
`setPactReader` (now rejects non-function inputs with a clear
|
|
1059
|
+
message naming the actual type) and `setLogger` (now rejects
|
|
1060
|
+
null / undefined / non-object inputs AND objects whose `warn`
|
|
1061
|
+
or `error` are non-callable). Pre-v3.3.7 misconfigurations
|
|
1062
|
+
only surfaced later as `_reader is not a function` /
|
|
1063
|
+
`_logger.warn is not a function` at the first call site, far
|
|
1064
|
+
from the boot wiring. **F-SEC-004** wires a one-shot
|
|
1065
|
+
`getLogger().warn(...)` security advisory into the V1-decrypt
|
|
1066
|
+
path — V1 envelopes use PBKDF2-SHA256 / 10,000 iterations,
|
|
1067
|
+
well below OWASP's current 600,000 minimum; the warning fires
|
|
1068
|
+
once per process lifetime (no bulk-decrypt log spam). Adds
|
|
1069
|
+
new rich variants `decryptStringV2WithDetails` and
|
|
1070
|
+
`smartDecryptWithDetails` returning `{plaintext, wasLegacyV1}`
|
|
1071
|
+
for per-call programmatic detection so consumers can re-encrypt
|
|
1072
|
+
affected codex entries to V2 in-place. JSDoc CVE-style risk
|
|
1073
|
+
documentation added to `EncryptedDataV1`, `decryptStringV2`,
|
|
1074
|
+
and `smartDecrypt`. NO breaking change. v3.3.0 contract test
|
|
1075
|
+
locking the byte-identical `setLogger requires a non-null
|
|
1076
|
+
Logger` message preserved verbatim. Locked at
|
|
1077
|
+
`tests/v3-3-7-seam-validators.test.ts` (11 it-blocks across 3
|
|
1078
|
+
describe groups: setPactReader input validation,
|
|
1079
|
+
setLogger input-shape validation, setLogger
|
|
1080
|
+
backwards-compat preservation) and
|
|
1081
|
+
`tests/v3-3-7-v1-warning.test.ts` (10 it-blocks across 3
|
|
1082
|
+
describe groups: decryptStringV2WithDetails,
|
|
1083
|
+
smartDecryptWithDetails, one-shot warning behavior including
|
|
1084
|
+
the load-bearing "second V1 decrypt is silent" assertion that
|
|
1085
|
+
proves the bulk-codex-decrypt UX is non-spammy). **+21 new
|
|
1086
|
+
tests** bringing the suite to **695/695 passing** (was 674 in
|
|
1087
|
+
v3.3.6).
|
|
1088
|
+
|
|
1089
|
+
**v3.3.6** — performance pass closing three MEDIUM perf findings
|
|
1090
|
+
from the 2026-05-05 audit in one release. **MINOR, additive.**
|
|
1091
|
+
**F-PERF-008** added `"sideEffects": false` to `package.json` —
|
|
1092
|
+
the audit's "single most impactful tree-shaking fix"; verified
|
|
1093
|
+
safe via grep showing zero top-level callable statements in
|
|
1094
|
+
`src/` (every seam — `setPactReader`, `setLogger`, `setNodeConfig`
|
|
1095
|
+
— is consumer-invoked at boot, never at module top-level);
|
|
1096
|
+
consumer bundles can now prune unused barrel imports from the
|
|
1097
|
+
16-subpath exports map. **F-PERF-003** memoized 8 `RegExp`
|
|
1098
|
+
allocations per call in `coilFunctions.getCoilPreviewGeneric`
|
|
1099
|
+
to a `Map<string, CoilPatternSet>` cache keyed by
|
|
1100
|
+
`targetTokenName` — patterns are dynamic per token (interpolate
|
|
1101
|
+
`config.targetToken`) so the audit's literal "hoist to
|
|
1102
|
+
module-level const" doesn't apply; the cache form achieves the
|
|
1103
|
+
same outcome with steady-state 0 RegExp allocations per call
|
|
1104
|
+
after warm-up. **F-PERF-004** parallelized
|
|
1105
|
+
`ouroFunctions.getOuronetKdaDetails` via `Promise.all([owner,
|
|
1106
|
+
guard])` — verified independent (probes `DALOS.UR_AccountKadena`
|
|
1107
|
+
vs `DALOS.UR_AccountGuard` with no causal dependency); halves
|
|
1108
|
+
happy-path latency from ~2 sequential RPC roundtrips to ~1
|
|
1109
|
+
parallel roundtrip. NO public API change. NO observable
|
|
1110
|
+
behavior change outside the latency win and the bundler
|
|
1111
|
+
tree-shaking pruning. Locked at
|
|
1112
|
+
`tests/v3-3-6-perf-pass.test.ts` with 2 it-blocks: T1 strict
|
|
1113
|
+
equality `pkg.sideEffects === false` for F-PERF-008, T2
|
|
1114
|
+
counting-reader assertion that both `UR_AccountKadena` AND
|
|
1115
|
+
`UR_AccountGuard` Pact codes appear in the recorded calls for
|
|
1116
|
+
F-PERF-004. F-PERF-003's regex memoization is module-internal;
|
|
1117
|
+
behavioral coverage already lives in v3.3.5's
|
|
1118
|
+
`tests/v3-3-5-smoke.test.ts:117-141` for `getCoilPreviewGeneric`
|
|
1119
|
+
which passes unchanged. **+2 new tests** bringing the suite to
|
|
1120
|
+
**674/674 passing** (was 672 in v3.3.5).
|
|
1121
|
+
|
|
1122
|
+
**v3.3.5** — runtime smoke tests for 6 interaction modules with
|
|
1123
|
+
no runtime test coverage prior to this release. **MINOR,
|
|
1124
|
+
additive (test-only).** Closes audit finding **F-TEST-006**
|
|
1125
|
+
(MEDIUM, testing-auditor). Three modules had **zero runtime
|
|
1126
|
+
tests** (`pensionFunctions`, `guardFunctions`,
|
|
1127
|
+
`infoOneFunctions`); three more had **compile-only tests**
|
|
1128
|
+
(`coilFunctions`, `kpayFunctions`, `activateFunctions`). v3.3.5
|
|
1129
|
+
adds `tests/v3-3-5-smoke.test.ts` — **12 new it-blocks across 6
|
|
1130
|
+
describe groups**, one happy-path + one error-path test per
|
|
1131
|
+
module: `getHibernateFee` parses `{decimal:"0.99"}` → `0.99` and
|
|
1132
|
+
catches into local fallback formula on thrown read;
|
|
1133
|
+
`getRotateGuardInfo` returns success-path data verbatim, `null`
|
|
1134
|
+
on failure-status; `getCoilPreviewInfo` wraps success data in
|
|
1135
|
+
`{result: ...}`, returns `null` on failure-status;
|
|
1136
|
+
`getCoilPreviewGeneric` parses `"generates 5.0 AURYN"` from
|
|
1137
|
+
`pre-text` regex match, **rethrows** on failure-status (the only
|
|
1138
|
+
module of the 6 that rethrows); `getKpayData` returns success
|
|
1139
|
+
data verbatim, `null` on failure-status;
|
|
1140
|
+
`getDeployStandardAccountInfoOnly` returns success data
|
|
1141
|
+
verbatim, `null` + `getLogger().error` on thrown read. Read-only
|
|
1142
|
+
function smoke is sufficient per F-TEST-006's "function actually
|
|
1143
|
+
executes" assertion; transaction-execute coverage requires
|
|
1144
|
+
mocking the full `@kadena/client` signing + submit chain and is
|
|
1145
|
+
queued for v4.0.0's monorepo split. NO source-code change. **+12
|
|
1146
|
+
new tests** bringing the suite to **672/672 passing** (was 660
|
|
1147
|
+
in v3.3.4). Closes the v3.3.x audit-closure track —
|
|
1148
|
+
F-LOGGER-SEAM-001 (v3.3.0), F-TEST-002 (v3.3.2), F-TEST-005
|
|
1149
|
+
(v3.3.4), F-TEST-006 (v3.3.5) all CLOSED; remaining MEDIUM
|
|
1150
|
+
findings are performance/architecture, not test coverage.
|
|
1151
|
+
|
|
1152
|
+
**v3.3.4** — success-path tests for the 13 v3.0.0 nullable-widened
|
|
1153
|
+
functions that previously had only RPC-failure-path coverage.
|
|
1154
|
+
**MINOR, additive (test-only).** Closes audit finding
|
|
1155
|
+
**F-TEST-005** (MEDIUM, testing-auditor). Pre-v3.3.4, only 3 of
|
|
1156
|
+
the 16 v3.0.0 widenings had a paired success-path test —
|
|
1157
|
+
`getStoaPriceUSD`, `getLPTypeInfo` mixed-state, and
|
|
1158
|
+
`getUrStoaGuard` 3-state. The remaining 13 could not distinguish
|
|
1159
|
+
"always returns null" (silent regression) from "returns null
|
|
1160
|
+
only on RPC failure" (correct contract). v3.3.4 adds
|
|
1161
|
+
`tests/v3-3-4-success-paths.test.ts` — **13 new it-blocks
|
|
1162
|
+
across 6 describe groups**: pricing-quartet (3 — int/decimal
|
|
1163
|
+
parse paths for `getTokenDecimals`/`getPoolTotalFee`/`getDPTFMinMove`);
|
|
1164
|
+
string-balance cluster (4 — `getIgnisBalance` /
|
|
1165
|
+
`getAccountTokenSupply` / `getOuroDispoCapacity` /
|
|
1166
|
+
`getVirtualOuro` all unwrap `{decimal:"..."}` to the
|
|
1167
|
+
underlying string via `mayComeWithDeimal`); urStoa pair (2 —
|
|
1168
|
+
`getUrStoaBalance` parses `{decimal:"42.5"}` → `42.5`,
|
|
1169
|
+
`checkCoinAccountExists` (urStoa) returns `true` when chain
|
|
1170
|
+
data is `true`); `validateLiquidity` mixed-shape success (1 —
|
|
1171
|
+
chain returns `[{decimal:"0.05"}, {decimal:"0.10"}]` →
|
|
1172
|
+
function returns `{valid:true, computed:"0.05", max:"0.10"}`
|
|
1173
|
+
AND `error` is `undefined`, locking the v3.0.0 mutual
|
|
1174
|
+
exclusion); `getMaxBuyMovieBooster` (1 — `{int:"5000"}` →
|
|
1175
|
+
`5000`); magic-string elimination (2 — `getSWPSpawnLimit` and
|
|
1176
|
+
`getSWPInactiveLimit` return the decimal string AND
|
|
1177
|
+
`expect(out).not.toBe("N/A")` so the v3.0.0 BREAKING swap
|
|
1178
|
+
cannot regress unnoticed). Strategy mirrors the pre-existing
|
|
1179
|
+
`tests/interactions-pricing.test.ts:80-88` success-path lock:
|
|
1180
|
+
`setPactReader(successReader({...}))` → call SUT → assert. NO
|
|
1181
|
+
source-code change; every interaction function is byte-identical
|
|
1182
|
+
to v3.3.3. **+13 new tests** bringing the suite to **660/660
|
|
1183
|
+
passing** (was 647 in v3.3.3).
|
|
1184
|
+
|
|
1185
|
+
**v3.3.3** — multi-party partial-signature public surface for
|
|
1186
|
+
cross-party signing handoffs. **MINOR, additive (NEW PUBLIC
|
|
1187
|
+
SURFACE — not a bug fix).** Ships the OuronetUI-requested
|
|
1188
|
+
"Person A signs → exports → Person B imports → signs → exports
|
|
1189
|
+
→ Person C imports → signs → submits" workflow as shared core,
|
|
1190
|
+
with cross-party tamper detection at every handoff. Builds on
|
|
1191
|
+
v3.3.2's locked partial-signing primitive (signing with a subset
|
|
1192
|
+
of declared signers fills only those slots; pre-existing slots
|
|
1193
|
+
stay intact across re-signing passes) by wrapping it in a
|
|
1194
|
+
versioned export envelope + slot-status helpers + Ed25519
|
|
1195
|
+
sig-verification helper. New `src/signing/partialSig.ts` module
|
|
1196
|
+
re-exported from `@ouronet/ouronet-core/signing`, exposing
|
|
1197
|
+
**7 functions** (`signPartial`, `serializePartialTransaction`,
|
|
1198
|
+
`deserializePartialTransaction`, `getMissingSigners`,
|
|
1199
|
+
`getFilledSigners`, `isFullySigned`,
|
|
1200
|
+
`verifyExistingSignatures`), **2 typed errors**
|
|
1201
|
+
(`InvalidEnvelopeError`, `TamperedHashError`), and the
|
|
1202
|
+
`PartialSigEnvelope` interface. Two-layer tamper defence: (1)
|
|
1203
|
+
`deserializePartialTransaction` recomputes blake2b-256(cmd) and
|
|
1204
|
+
rejects mismatch with `TamperedHashError` carrying both
|
|
1205
|
+
`expected` and `actual` for operator diagnosability; (2)
|
|
1206
|
+
`verifyExistingSignatures` runs `nacl.sign.detached.verify` on
|
|
1207
|
+
every filled slot — works for both nacl-direct (koala/foreign)
|
|
1208
|
+
and BIP32-WASM (chainweaver/eckowallet) sigs since both produce
|
|
1209
|
+
standard Ed25519 over the same canonical hash bytes; catches
|
|
1210
|
+
the "tampered cmd + tampered hash to match" attack the
|
|
1211
|
+
hash-integrity gate alone misses (any cmd modification
|
|
1212
|
+
invalidates every prior signature against the new hash). NO
|
|
1213
|
+
existing API changed; NO source-side behaviour change outside
|
|
1214
|
+
the new module. **+16 new tests** (`tests/partial-sig.test.ts`
|
|
1215
|
+
— 16 it-blocks across 7 describe groups including end-to-end
|
|
1216
|
+
3-party round-trip via serialize/deserialize handoffs), bringing
|
|
1217
|
+
the suite to **647/647 passing** (was 631 in v3.3.2; +16).
|
|
1218
|
+
|
|
1219
|
+
**v3.3.2** — direct test coverage for `universalSignTransaction`
|
|
1220
|
+
(closes audit finding **F-TEST-002** HIGH). **MINOR, additive
|
|
1221
|
+
(test-only).** Pre-v3.3.2, the central signing entry point in
|
|
1222
|
+
`src/signing/universalSign.ts` had ZERO direct tests — the
|
|
1223
|
+
chainweaver / eckowallet / foreign seedType branches AND the
|
|
1224
|
+
seedType dispatcher itself were never runtime-tested. v3.3.2 adds
|
|
1225
|
+
`tests/universal-sign.test.ts` with 9 new it-blocks across 6
|
|
1226
|
+
describe groups: koala branch round-trip with RFC-8032 vector
|
|
1227
|
+
(2 tests including the `fromKeypair` adapter that normalises
|
|
1228
|
+
consumer-shape `privateKey` field into universal `secretKey`);
|
|
1229
|
+
chainweaver branch round-trip with real WASM `kadenaSign`
|
|
1230
|
+
derived from the @kadena/hd-wallet vendor mnemonic vector
|
|
1231
|
+
(1 test); eckowallet branch round-trip proving the dispatcher
|
|
1232
|
+
routes both labels to the same WASM signing path (1 test);
|
|
1233
|
+
multi-signer mixed-seedType case proving the
|
|
1234
|
+
iterate-and-dispatch-each loop's correctness (1 test);
|
|
1235
|
+
foreign-key `onMissingKey` callback resolution — success path
|
|
1236
|
+
where the callback returns the matching private key (1 test) +
|
|
1237
|
+
failure path where the callback returns a mismatched key →
|
|
1238
|
+
"Key mismatch" error citing both expected and derived pubkeys
|
|
1239
|
+
(1 test); and the partial-signing primitive that v3.3.3's
|
|
1240
|
+
planned multi-party signing public surface will build on —
|
|
1241
|
+
3-signer transaction signed with only 1 keypair fills only
|
|
1242
|
+
that slot, other slots stay empty (1 test); and keypairs whose
|
|
1243
|
+
pubkey is NOT in cmd.signers are silently skipped (1 test).
|
|
1244
|
+
The verification helper uses `nacl.sign.detached.verify` over
|
|
1245
|
+
the base64URL-decoded `signed.hash` bytes — works for BOTH
|
|
1246
|
+
the nacl-direct path (koala/foreign) AND the WASM-Ed25519
|
|
1247
|
+
path (chainweaver/eckowallet) since both produce standard
|
|
1248
|
+
Ed25519 signatures over the same canonical hash. NO
|
|
1249
|
+
source-code change; `universalSign.ts` is byte-identical to
|
|
1250
|
+
v3.3.1.
|
|
1251
|
+
|
|
1252
|
+
**v3.3.1** — workflow-file patch. **PATCH, workflow-only.** Closes
|
|
1253
|
+
the two carried-forward follow-ups that appeared in every
|
|
1254
|
+
pollinate run's final report from v3.0.0 through v3.3.0: (1) `npm
|
|
1255
|
+
publish --provenance` flag added (plus the `id-token: write`
|
|
1256
|
+
workflow permission required to mint the GitHub-Actions-OIDC token
|
|
1257
|
+
that npm exchanges with npmjs.org's attestation endpoint) — every
|
|
1258
|
+
v3.3.1+ release carries a SLSA attestation visible as the
|
|
1259
|
+
"Provenance" badge on npmjs.com and a 200 response on
|
|
1260
|
+
`https://registry.npmjs.org/-/npm/v1/attestations/@ouronet/ouronet-core@{version}`;
|
|
1261
|
+
pre-v3.3.1, every release shipped without provenance because
|
|
1262
|
+
`lifecycle.use_provenance: true` in `.bee/config.json` was
|
|
1263
|
+
truth-claimed by pollinate but the actual workflow's `npm publish
|
|
1264
|
+
--access public` lacked the flag. (2) `gh release create`
|
|
1265
|
+
invocations drop the `--repo` flag — the
|
|
1266
|
+
`gh release create --notes-from-tag --repo X` flag combination
|
|
1267
|
+
started failing on GitHub-hosted runners around 2026-04-30 with
|
|
1268
|
+
the gh-CLI image update; every v3.x release pre-v3.3.1 needed
|
|
1269
|
+
pollinate's REST-API fallback (Step 9c) to create the GitHub
|
|
1270
|
+
Release manually. Dropping `--repo` lets gh auto-detect the repo
|
|
1271
|
+
from the working-directory context (set by `actions/checkout@v4`
|
|
1272
|
+
at the top of the workflow), which is the same repo we want
|
|
1273
|
+
anyway. From v3.3.1 onwards the workflow's gh-Release step
|
|
1274
|
+
succeeds inline; pollinate's REST fallback becomes
|
|
1275
|
+
idempotency-skip code (Step 9b's "release exists?" check passes,
|
|
1276
|
+
Step 9c skips). Workflow-only patch — `.github/workflows/publish.yml`
|
|
1277
|
+
is the sole behaviour-change file; source code is byte-identical
|
|
1278
|
+
to v3.3.0; **622/622 tests pass unchanged** (workflow files
|
|
1279
|
+
aren't in the test scope; verification arrives with the v3.3.1
|
|
1280
|
+
publish run itself).
|
|
1281
|
+
|
|
1282
|
+
**698 tests** pass on every commit (up from 695 in v3.3.7; +3
|
|
1283
|
+
from the new `tests/v3-3-8-doc-cleanup.test.ts` regression-lock
|
|
1284
|
+
file added in v3.3.8 to close 5 LOW-severity findings from the
|
|
1285
|
+
2026-05-05 audit — F-API-015 stale JSDoc, F-API-016 export
|
|
1286
|
+
CoilConfig, F-SEC-005/F-ARCH-014 KADENA_BASE_URL @deprecated
|
|
1287
|
+
marker, F-ARCH-011 normalizeKeysetRef barrel-import
|
|
1288
|
+
consolidation, F-ARCH-012 dalos/account.ts quote-style cleanup.
|
|
1289
|
+
With v3.3.8 the v3.3.x audit-closure track now spans testing
|
|
1290
|
+
AND performance AND security-input-validation AND
|
|
1291
|
+
documentation/deprecation categories; remaining items are
|
|
1292
|
+
either reserved for v4.0.0 (arch + sleep-replacement) or
|
|
1293
|
+
NEEDS CONTEXT findings flagged for human review.
|
|
1294
|
+
Dependency-hygiene release planned for v3.3.9 / v3.4.0. Published to the public npmjs registry via
|
|
1295
|
+
`.github/workflows/publish.yml` on every `v*` tag (which also
|
|
1296
|
+
creates a GitHub Release). Published to the public
|
|
1297
|
+
npmjs registry via `.github/workflows/publish.yml` on every `v*`
|
|
1298
|
+
tag (which also creates a GitHub Release).
|
|
1299
|
+
|
|
1300
|
+
```bash
|
|
1301
|
+
npm install @ouronet/ouronet-core
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
## What's new in v2.1.0
|
|
1305
|
+
|
|
1306
|
+
The chain-RPC surface used to be 81 ad-hoc `createClient(getPactUrl(chainId))`
|
|
1307
|
+
calls scattered across 11 interaction files, each pinned to whatever
|
|
1308
|
+
URL `getPactUrl` returned at the moment of construction and each with
|
|
1309
|
+
no timeout. v2.1.0 collapses that into one reusable factory:
|
|
1310
|
+
|
|
1311
|
+
```ts
|
|
1312
|
+
import { getFailoverClient } from "@ouronet/ouronet-core/network";
|
|
1313
|
+
|
|
1314
|
+
// All four standard chain operations, each wrapped in withFailover +
|
|
1315
|
+
// per-tier timeout. The factory's submit captures the same signed-tx
|
|
1316
|
+
// reference across primary + fallback attempts (REQ-01 dedup contract).
|
|
1317
|
+
const { dirtyRead, submit, listen, pollOne } = getFailoverClient(chainId);
|
|
1318
|
+
|
|
1319
|
+
const txDescriptor = await submit(signedTx); // 60s default, auto-failover
|
|
1320
|
+
const result = await listen(txDescriptor); // 180s default (~6 Kadena blocks), auto-failover
|
|
1321
|
+
```
|
|
1322
|
+
|
|
1323
|
+
### Timeouts
|
|
1324
|
+
|
|
1325
|
+
Per-tier defaults: **read 15s**, **submit 60s**, **listen 180s**
|
|
1326
|
+
(~6 Kadena blocks for inclusion long-polling), **pollOne 30s**.
|
|
1327
|
+
Two-tier override precedence — per-call wins over factory-time wins
|
|
1328
|
+
over locked default:
|
|
1329
|
+
|
|
1330
|
+
```ts
|
|
1331
|
+
// Factory-time override
|
|
1332
|
+
const client = getFailoverClient(chainId, { submitTimeoutMs: 30_000 });
|
|
1333
|
+
|
|
1334
|
+
// Per-call override
|
|
1335
|
+
await client.submit(signedTx, { submitTimeoutMs: 5_000 });
|
|
1336
|
+
```
|
|
1337
|
+
|
|
1338
|
+
A primary-side timeout rejects with `Error.name === "AbortError"`
|
|
1339
|
+
inside `withFailover`, which classifier-matches the existing fallback
|
|
1340
|
+
contract — so a primary timeout transparently triggers the fallback
|
|
1341
|
+
retry. Only if **both** primary and fallback time out does the consumer
|
|
1342
|
+
see a `SigningError { code: "TIMEOUT" }` surfaced via the factory's
|
|
1343
|
+
outer-boundary catch.
|
|
1344
|
+
|
|
1345
|
+
### Lower-level helpers
|
|
1346
|
+
|
|
1347
|
+
For the codex signing strategy seam (where failover is intentionally
|
|
1348
|
+
the consumer's `PactClient` responsibility), v2.1.0 also exports a
|
|
1349
|
+
plain timeout helper:
|
|
1350
|
+
|
|
1351
|
+
```ts
|
|
1352
|
+
import { runWithTimeout } from "@ouronet/ouronet-core/network";
|
|
1353
|
+
|
|
1354
|
+
await runWithTimeout("operation-name", (controller) =>
|
|
1355
|
+
fetch("https://...", { signal: controller.signal }), 15_000);
|
|
1356
|
+
// Rejects with Error.name === "AbortError" on timeout. Caller is
|
|
1357
|
+
// responsible for converting to SigningError { code: "TIMEOUT" }.
|
|
1358
|
+
```
|
|
1359
|
+
|
|
1360
|
+
Plus `createTimeoutError(operation, timeoutMs, originalError?, additionalContext?)`
|
|
1361
|
+
from `@ouronet/ouronet-core/errors` for that conversion, and
|
|
1362
|
+
`resetNodeFailover()` from `@ouronet/ouronet-core/network` for test
|
|
1363
|
+
isolation.
|
|
1364
|
+
|
|
1365
|
+
### Migration
|
|
1366
|
+
|
|
1367
|
+
**No migration required.** All existing imports continue to work
|
|
1368
|
+
unchanged. The new surface is purely opt-in. Internal calls have
|
|
1369
|
+
already been migrated — your existing reads and submits now get
|
|
1370
|
+
failover and timeouts automatically.
|
|
1371
|
+
|
|
1372
|
+
## What's new in v2.2.0
|
|
1373
|
+
|
|
1374
|
+
The `./crypto` subpath previously surfaced every decryption failure as
|
|
1375
|
+
a generic `Error` — wrong password, structurally damaged envelope, and
|
|
1376
|
+
unsupported schema version all collapsed to a string-message check.
|
|
1377
|
+
v2.2.0 adds three typed error classes that discriminate the failure
|
|
1378
|
+
modes, plus a single-path `smartDecrypt` dispatch that closes a
|
|
1379
|
+
wall-time timing differential observed on V1 wrong-password inputs:
|
|
1380
|
+
|
|
1381
|
+
```ts
|
|
1382
|
+
import {
|
|
1383
|
+
smartDecrypt,
|
|
1384
|
+
WrongPasswordError,
|
|
1385
|
+
CorruptEnvelopeError,
|
|
1386
|
+
} from "@ouronet/ouronet-core/crypto";
|
|
1387
|
+
|
|
1388
|
+
try {
|
|
1389
|
+
const plaintext = await smartDecrypt(blob, password);
|
|
1390
|
+
} catch (err) {
|
|
1391
|
+
if (err instanceof WrongPasswordError) {
|
|
1392
|
+
// most common case — show "wrong password" UI
|
|
1393
|
+
} else if (err instanceof CorruptEnvelopeError) {
|
|
1394
|
+
// blob is structurally damaged — recovery / re-import path
|
|
1395
|
+
} else {
|
|
1396
|
+
// unexpected (UnsupportedFormatError, or anything else) — log and
|
|
1397
|
+
// surface to user as a generic decrypt failure
|
|
1398
|
+
throw err;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
```
|
|
1402
|
+
|
|
1403
|
+
Existing consumers that only check `instanceof Error` or read
|
|
1404
|
+
`error.message` continue to work unchanged — the typed classes extend
|
|
1405
|
+
`Error`, so the new discrimination is purely opt-in.
|
|
1406
|
+
|
|
1407
|
+
## What's new in v2.3.0
|
|
1408
|
+
|
|
1409
|
+
The v2.3.0 audit-closure release introduces a central logger seam at
|
|
1410
|
+
`@ouronet/ouronet-core/observability` mirroring the existing
|
|
1411
|
+
`setPactReader` injection-seam pattern. Every diagnostic
|
|
1412
|
+
`console.warn` / `console.error` call inside `src/` now routes through
|
|
1413
|
+
this seam, so consumers can capture, redirect, or suppress library
|
|
1414
|
+
log events without monkey-patching the global `console`:
|
|
1415
|
+
|
|
1416
|
+
```ts
|
|
1417
|
+
import { setLogger, getLogger, type Logger } from "@ouronet/ouronet-core/observability";
|
|
1418
|
+
|
|
1419
|
+
// Option 1: Forward to your existing app logger (Pino, Winston, Sentry, …).
|
|
1420
|
+
const myLogger: Logger = {
|
|
1421
|
+
warn: (msg, ...args) => myApp.warn(msg, args),
|
|
1422
|
+
error: (msg, ...args) => myApp.error(msg, args),
|
|
1423
|
+
};
|
|
1424
|
+
setLogger(myLogger);
|
|
1425
|
+
|
|
1426
|
+
// Option 2: Capture for telemetry without losing console output.
|
|
1427
|
+
const original = getLogger();
|
|
1428
|
+
setLogger({
|
|
1429
|
+
warn: (msg, ...args) => { telemetry.warn(msg, args); original.warn(msg, ...args); },
|
|
1430
|
+
error: (msg, ...args) => { telemetry.error(msg, args); original.error(msg, ...args); },
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
// Or do nothing — the default routes to console.warn / console.error so
|
|
1434
|
+
// existing v2.2.x behavior is preserved exactly.
|
|
1435
|
+
```
|
|
1436
|
+
|
|
1437
|
+
The mutator rejects null/undefined input with a clear `TypeError`:
|
|
1438
|
+
|
|
1439
|
+
```ts
|
|
1440
|
+
setLogger(null);
|
|
1441
|
+
// throws TypeError: setLogger requires a non-null Logger
|
|
1442
|
+
```
|
|
1443
|
+
|
|
1444
|
+
The companion addition is a typed `UnknownPredicateError` class
|
|
1445
|
+
re-exported from the `./guard` subpath. `computeThreshold` throws it
|
|
1446
|
+
when it encounters an unrecognized predicate; the general-purpose
|
|
1447
|
+
`analyzeGuard` catches it and folds it into a structured
|
|
1448
|
+
`predicateRecognized: false` bit on the returned analysis. Consumers
|
|
1449
|
+
that want to discriminate this failure mode can branch on the typed
|
|
1450
|
+
class:
|
|
1451
|
+
|
|
1452
|
+
```ts
|
|
1453
|
+
import { computeThreshold, UnknownPredicateError } from "@ouronet/ouronet-core/guard";
|
|
1454
|
+
|
|
1455
|
+
try {
|
|
1456
|
+
const threshold = computeThreshold(guard);
|
|
1457
|
+
} catch (err) {
|
|
1458
|
+
if (err instanceof UnknownPredicateError) {
|
|
1459
|
+
// Surface a recognizable "unknown predicate" diagnostic to the user.
|
|
1460
|
+
} else {
|
|
1461
|
+
throw err;
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
```
|
|
1465
|
+
|
|
1466
|
+
Existing `instanceof Error` checks and existing analysis-flag access
|
|
1467
|
+
continue to work unchanged — the typed-class discrimination from
|
|
1468
|
+
`./guard` and the logger-seam injection from `./observability` are
|
|
1469
|
+
both purely opt-in.
|
|
1470
|
+
|
|
1471
|
+
## What's new in v3.0.0
|
|
1472
|
+
|
|
1473
|
+
The v3.0.0 fabricated-fallbacks-removal release closes M3 from the
|
|
1474
|
+
2026-04-30 audit cycle (lead finding F-CORE-007 HIGH plus the
|
|
1475
|
+
~24-site catalog sweep). The headline change is uniform: every
|
|
1476
|
+
`src/interactions/*` read helper that previously fabricated a chain
|
|
1477
|
+
value on RPC failure (`1.0` USD prices, `"0"` balances, sentinel
|
|
1478
|
+
`"N/A"` strings, fake `false` existence flags) now returns `null`
|
|
1479
|
+
on failure so consumers can distinguish "RPC failed" from "chain
|
|
1480
|
+
returned this real value." Sixteen functions widen their return
|
|
1481
|
+
types in lockstep; consumers add `if (result === null) { ... }`
|
|
1482
|
+
branches at call sites:
|
|
1483
|
+
|
|
1484
|
+
```ts
|
|
1485
|
+
import { getStoaPriceUSD } from "@ouronet/ouronet-core/interactions/ouroFunctions";
|
|
1486
|
+
|
|
1487
|
+
// v3.0.0 — null on RPC failure / chain failure / non-finite parse,
|
|
1488
|
+
// real number on success.
|
|
1489
|
+
const price = await getStoaPriceUSD();
|
|
1490
|
+
|
|
1491
|
+
if (price === null) {
|
|
1492
|
+
// RPC failed or chain returned malformed data — show an error
|
|
1493
|
+
// banner instead of computing positions against a fabricated 1.0.
|
|
1494
|
+
showRPCErrorBanner("Could not fetch STOA/USD price");
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
// price is a real Number.isFinite(...) value — safe to use.
|
|
1499
|
+
renderPriceLabel(`$${price.toFixed(4)}`);
|
|
1500
|
+
```
|
|
1501
|
+
|
|
1502
|
+
`getLPTypeInfo` keeps its function-level return type but widens its
|
|
1503
|
+
inner field types so consumers can render mixed UI per flag (Frozen
|
|
1504
|
+
LP succeeded, Sleeping LP RPC-failed):
|
|
1505
|
+
|
|
1506
|
+
```ts
|
|
1507
|
+
import { getLPTypeInfo } from "@ouronet/ouronet-core/interactions/addLiquidityFunctions";
|
|
1508
|
+
|
|
1509
|
+
const info = await getLPTypeInfo(swpair); // { hasFrozenLP, hasSleepingLP }
|
|
1510
|
+
|
|
1511
|
+
// Three states per flag now: true (chain confirmed exists),
|
|
1512
|
+
// false (chain confirmed absent OR chain failure-status), null (catch).
|
|
1513
|
+
if (info.hasFrozenLP === null) {
|
|
1514
|
+
renderFrozenSection({ status: "rpc-error" });
|
|
1515
|
+
} else {
|
|
1516
|
+
renderFrozenSection({ status: info.hasFrozenLP ? "present" : "absent" });
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
if (info.hasSleepingLP === null) {
|
|
1520
|
+
renderSleepingSection({ status: "rpc-error" });
|
|
1521
|
+
} else {
|
|
1522
|
+
renderSleepingSection({ status: info.hasSleepingLP ? "present" : "absent" });
|
|
1523
|
+
}
|
|
1524
|
+
```
|
|
1525
|
+
|
|
1526
|
+
In lockstep, **14 NON-BREAKING logger-routing additions** across 5
|
|
1527
|
+
files complete the silent-catch-elimination sweep started in v2.3.0
|
|
1528
|
+
— previously-silent diagnostic catches in `dexFunctions.ts`,
|
|
1529
|
+
`ouroFunctions.ts`, `activateFunctions.ts`, `infoOneFunctions.ts`,
|
|
1530
|
+
and `urStoaFunctions.ts` private helpers now route via
|
|
1531
|
+
`getLogger().error("Error in <funcName>:", error)`. Consumers who
|
|
1532
|
+
called `setLogger(...)` (introduced in v2.3.0) automatically capture
|
|
1533
|
+
these new error events with no additional wiring.
|
|
1534
|
+
|
|
1535
|
+
## Migrating to v3.x
|
|
1536
|
+
|
|
1537
|
+
v3.0.0 is the first major bump since v2.0.0 and the deliberate
|
|
1538
|
+
forcing function for **Option B null-pattern** (locked Q3..Q11):
|
|
1539
|
+
sixteen `src/interactions/*` read helpers that previously fabricated
|
|
1540
|
+
chain values on RPC failure now widen their return types so consumers
|
|
1541
|
+
see RPC failures instead of silently fabricated sentinels (`1.0` USD
|
|
1542
|
+
prices, `"0"` balances, sentinel `"N/A"` strings, fake `false`
|
|
1543
|
+
existence flags). Fifteen functions widen from `Promise<T>` to
|
|
1544
|
+
`Promise<T | null>`; one (`validateLiquidity`) adds an optional
|
|
1545
|
+
`error?: string` field on its mixed shape to distinguish "RPC failed"
|
|
1546
|
+
from "validation rejected" without dropping the existing `valid:
|
|
1547
|
+
boolean` contract.
|
|
1548
|
+
|
|
1549
|
+
Every breaking change below stems from the **Option B null-pattern**
|
|
1550
|
+
locked decision per the 2026-04-30 audit cycle: callers add `if
|
|
1551
|
+
(result === null) { showRPCErrorBanner(); return; }` branches before
|
|
1552
|
+
reading the previously-fabricated value. The 14 NON-BREAKING
|
|
1553
|
+
logger-routing additions across 5 files (Phase 3) require **NO
|
|
1554
|
+
consumer migration** — they are pure observability and existing call
|
|
1555
|
+
sites continue to work unchanged.
|
|
1556
|
+
|
|
1557
|
+
### 1. Pricing-quartet — `Promise<number>` → `Promise<number | null>`
|
|
1558
|
+
|
|
1559
|
+
`getStoaPriceUSD`, `getTokenDecimals`, `getPoolTotalFee`, and
|
|
1560
|
+
`getDPTFMinMove` (REQ-01..REQ-04) all widen to `Promise<number |
|
|
1561
|
+
null>`. The previous `1.0` / `0` / `8` fabrication sentinels are
|
|
1562
|
+
replaced with `null`, and `Number.isFinite()` guards catch `NaN`
|
|
1563
|
+
from malformed chain data (e.g. `parseInt("abc", 10)` or
|
|
1564
|
+
`parseFloat(String(undefined))`). All three failure paths — outer
|
|
1565
|
+
catch (network failure), `status !== "success"` branch (chain
|
|
1566
|
+
failure), and success-but-not-finite branch — now return `null`.
|
|
1567
|
+
|
|
1568
|
+
These are transaction-relevant amounts: silently fabricating `1.0`
|
|
1569
|
+
for a missing USD price would have produced wildly wrong position
|
|
1570
|
+
values; silently returning `8` for missing token decimals would have
|
|
1571
|
+
produced off-by-many-orders-of-magnitude amounts. The **Option B
|
|
1572
|
+
null-pattern** locked decision makes this failure mode explicit at
|
|
1573
|
+
the call site.
|
|
1574
|
+
|
|
1575
|
+
```ts
|
|
1576
|
+
// Before (v2.x):
|
|
1577
|
+
const price = await getStoaPriceUSD(); // number — could be fabricated 1.0
|
|
1578
|
+
const decimals = await getTokenDecimals(token); // number — could be fabricated 8
|
|
1579
|
+
renderPosition(price * amount, decimals);
|
|
1580
|
+
|
|
1581
|
+
// After (v3.x):
|
|
1582
|
+
const price = await getStoaPriceUSD();
|
|
1583
|
+
const decimals = await getTokenDecimals(token);
|
|
1584
|
+
if (price === null || decimals === null) {
|
|
1585
|
+
showRPCErrorBanner("Could not fetch pricing data");
|
|
1586
|
+
return;
|
|
1587
|
+
}
|
|
1588
|
+
renderPosition(price * amount, decimals);
|
|
1589
|
+
```
|
|
1590
|
+
|
|
1591
|
+
### 2. String-balance cluster — `Promise<string>` → `Promise<string | null>`
|
|
1592
|
+
|
|
1593
|
+
`getIgnisBalance`, `getAccountTokenSupply`, `getOuroDispoCapacity`,
|
|
1594
|
+
and `getVirtualOuro` (REQ-05) all widen to `Promise<string | null>`
|
|
1595
|
+
as a tightly-coupled cluster — both `return "0"` sentinels in each
|
|
1596
|
+
function become `return null`. Per the locked decision, "changing
|
|
1597
|
+
only some risks a UI where some buttons silently misbehave on RPC
|
|
1598
|
+
failure while others now correctly disable" — these four functions
|
|
1599
|
+
move together so consumer-side balance-display UI can branch
|
|
1600
|
+
uniformly on `null`.
|
|
1601
|
+
|
|
1602
|
+
Existing v2.3.0 logger routing is preserved; only the type and
|
|
1603
|
+
sentinel change. Catch paths still route via `getLogger().error()`.
|
|
1604
|
+
|
|
1605
|
+
```ts
|
|
1606
|
+
// Before (v2.x):
|
|
1607
|
+
const balance = await getIgnisBalance(account); // string — could be fabricated "0"
|
|
1608
|
+
showBalance(formatToken(balance));
|
|
1609
|
+
|
|
1610
|
+
// After (v3.x):
|
|
1611
|
+
const balance = await getIgnisBalance(account);
|
|
1612
|
+
if (balance === null) {
|
|
1613
|
+
showBalanceUnknown(); // Distinguish RPC failure from a real "0" balance
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1616
|
+
showBalance(formatToken(balance));
|
|
1617
|
+
```
|
|
1618
|
+
|
|
1619
|
+
### 3. `getLPTypeInfo` field widening (Approach A — function return type unchanged)
|
|
1620
|
+
|
|
1621
|
+
`getLPTypeInfo` (REQ-06) widens its inner field types from `{
|
|
1622
|
+
hasFrozenLP: boolean; hasSleepingLP: boolean }` to `{ hasFrozenLP:
|
|
1623
|
+
boolean | null; hasSleepingLP: boolean | null }`. Per the locked
|
|
1624
|
+
**Approach A** decision, the **function-level return type is
|
|
1625
|
+
UNCHANGED** — only the inner field types widen. Consumers can render
|
|
1626
|
+
granular per-flag mixed UI (e.g. Frozen LP succeeded but Sleeping LP
|
|
1627
|
+
RPC-failed). Approach B (function-level null) was rejected because
|
|
1628
|
+
it loses granularity; Approach C (separate error channel) was
|
|
1629
|
+
rejected because it is non-breaking and defeats the audit purpose.
|
|
1630
|
+
|
|
1631
|
+
Per the Phase 2 P-001 fix, **3-state preservation** is the locked
|
|
1632
|
+
contract for each flag: chain-failure-status (`response.result.status
|
|
1633
|
+
!== "success"`) returns `false`, the inner IIFE catch returns `null`,
|
|
1634
|
+
and a successful chain read returns `true`. Both inner catches route
|
|
1635
|
+
via `getLogger().error("Error checking Frozen LP:", error)` and
|
|
1636
|
+
`("Error checking Sleeping LP:", error)`.
|
|
1637
|
+
|
|
1638
|
+
```ts
|
|
1639
|
+
// Before (v2.x):
|
|
1640
|
+
const info = await getLPTypeInfo(swpair);
|
|
1641
|
+
// { hasFrozenLP: boolean; hasSleepingLP: boolean }
|
|
1642
|
+
if (info.hasFrozenLP) renderFrozen();
|
|
1643
|
+
if (info.hasSleepingLP) renderSleeping();
|
|
1644
|
+
|
|
1645
|
+
// After (v3.x):
|
|
1646
|
+
const info = await getLPTypeInfo(swpair);
|
|
1647
|
+
// { hasFrozenLP: boolean | null; hasSleepingLP: boolean | null }
|
|
1648
|
+
if (info.hasFrozenLP === null) renderFrozenRpcError();
|
|
1649
|
+
else if (info.hasFrozenLP) renderFrozen();
|
|
1650
|
+
else renderFrozenAbsent();
|
|
1651
|
+
|
|
1652
|
+
if (info.hasSleepingLP === null) renderSleepingRpcError();
|
|
1653
|
+
else if (info.hasSleepingLP) renderSleeping();
|
|
1654
|
+
else renderSleepingAbsent();
|
|
1655
|
+
```
|
|
1656
|
+
|
|
1657
|
+
### 4. urStoa trio — `Promise<T>` → `Promise<T | null>`
|
|
1658
|
+
|
|
1659
|
+
`getUrStoaBalance`, `getUrStoaGuard`, and `checkCoinAccountExists`
|
|
1660
|
+
(urStoa) (REQ-07) all widen to nullable returns as a tightly-coupled
|
|
1661
|
+
trio. `getUrStoaBalance` widens `Promise<number>` → `Promise<number
|
|
1662
|
+
| null>` (both `return 0` sites become `return null`).
|
|
1663
|
+
`getUrStoaGuard` widens `Promise<UrStoaGuardResult>` →
|
|
1664
|
+
`Promise<UrStoaGuardResult | null>` and **drops the sentinel** `empty
|
|
1665
|
+
= { exists: false, isKeyset: false, keys: [], pred: "" }` value;
|
|
1666
|
+
`null` now means RPC failed, while a real `UrStoaGuardResult` means
|
|
1667
|
+
the chain answered. **3-state preservation** in `getUrStoaGuard` is
|
|
1668
|
+
the locked contract: `null` (RPC failed), `{ exists: false, ... }`
|
|
1669
|
+
(chain confirmed no guard), `{ exists: true, ... }` (chain returned a
|
|
1670
|
+
real guard). `checkCoinAccountExists` widens `Promise<boolean>` →
|
|
1671
|
+
`Promise<boolean | null>` and gains `getLogger().error("Error in
|
|
1672
|
+
checkCoinAccountExists (urStoa):", error)` routing (was silent); JSDoc
|
|
1673
|
+
gains a cross-reference to the `ouroFunctions.ts:2088` sibling that
|
|
1674
|
+
already has the same nullable-boolean shape.
|
|
1675
|
+
|
|
1676
|
+
```ts
|
|
1677
|
+
// Before (v2.x):
|
|
1678
|
+
const guard = await getUrStoaGuard(account);
|
|
1679
|
+
// guard is always present; "empty" sentinel masks RPC failure
|
|
1680
|
+
if (!guard.exists) renderCreateGuardForm();
|
|
1681
|
+
else renderEditGuardForm(guard);
|
|
1682
|
+
|
|
1683
|
+
// After (v3.x):
|
|
1684
|
+
const guard = await getUrStoaGuard(account);
|
|
1685
|
+
if (guard === null) showRPCError(); // RPC failed
|
|
1686
|
+
else if (!guard.exists) renderCreateGuardForm(); // chain confirmed no guard
|
|
1687
|
+
else renderEditGuardForm(guard); // chain returned a real guard
|
|
1688
|
+
```
|
|
1689
|
+
|
|
1690
|
+
### 5. `validateLiquidity` mixed-shape addition
|
|
1691
|
+
|
|
1692
|
+
`validateLiquidity` (REQ-08) **preserves** its existing `valid:
|
|
1693
|
+
boolean` field but adds an optional `error?: string` field on RPC
|
|
1694
|
+
failure. This is the **mixed-shape** locked decision: distinguishing
|
|
1695
|
+
"validation rejected" from "RPC failed" without collapsing both into
|
|
1696
|
+
`valid: false`. Consumers route a populated `error` to the
|
|
1697
|
+
network-failure banner and a `valid: false` with no `error` to the
|
|
1698
|
+
validation-failure message.
|
|
1699
|
+
|
|
1700
|
+
The catch path now routes via `getLogger().error("Error in
|
|
1701
|
+
validateLiquidity:", error)` (preserved from v2.3.0) and sets the
|
|
1702
|
+
`error` field on the returned object.
|
|
1703
|
+
|
|
1704
|
+
```ts
|
|
1705
|
+
// Before (v2.x):
|
|
1706
|
+
const result = await validateLiquidity(...); // { valid: boolean; ... }
|
|
1707
|
+
if (!result.valid) showValidationFail("Liquidity rejected");
|
|
1708
|
+
|
|
1709
|
+
// After (v3.x):
|
|
1710
|
+
const result = await validateLiquidity(...); // { valid: boolean; error?: string; ... }
|
|
1711
|
+
if (result.error) {
|
|
1712
|
+
showRPCErrorBanner(result.error); // RPC failure
|
|
1713
|
+
} else if (!result.valid) {
|
|
1714
|
+
showValidationFail("Liquidity rejected"); // real validation rejection
|
|
1715
|
+
}
|
|
1716
|
+
```
|
|
1717
|
+
|
|
1718
|
+
### 6. `getMaxBuyMovieBooster` — `Promise<number>` → `Promise<number | null>`
|
|
1719
|
+
|
|
1720
|
+
`getMaxBuyMovieBooster` (REQ-08) widens to `Promise<number | null>`,
|
|
1721
|
+
matching the Phase 1 `getPoolTotalFee` pattern exactly. Both `return
|
|
1722
|
+
0` sites become `return null`; the success-path falsy-collapse (`||
|
|
1723
|
+
0`) becomes a `Number.isFinite()` guard. A `0` max-buy is a plausible
|
|
1724
|
+
chain return (e.g. when a booster is sold out) — collapsing the
|
|
1725
|
+
fabricated-failure case onto the same `0` made the two states
|
|
1726
|
+
indistinguishable. Existing v2.3.0 logger routing is preserved.
|
|
1727
|
+
|
|
1728
|
+
```ts
|
|
1729
|
+
// Before (v2.x):
|
|
1730
|
+
const max = await getMaxBuyMovieBooster(); // number — 0 could mean sold-out OR RPC fail
|
|
1731
|
+
if (max === 0) showSoldOut(); // ambiguous
|
|
1732
|
+
|
|
1733
|
+
// After (v3.x):
|
|
1734
|
+
const max = await getMaxBuyMovieBooster();
|
|
1735
|
+
if (max === null) showRPCErrorBanner(); // RPC failed
|
|
1736
|
+
else if (max === 0) showSoldOut(); // chain confirmed sold-out
|
|
1737
|
+
else showAvailable(max); // chain returned real positive max
|
|
1738
|
+
```
|
|
1739
|
+
|
|
1740
|
+
### 7. Magic-string elimination — `getSWPSpawnLimit` + `getSWPInactiveLimit`
|
|
1741
|
+
|
|
1742
|
+
`getSWPSpawnLimit` and `getSWPInactiveLimit` (REQ-09) widen from
|
|
1743
|
+
`Promise<string>` (sentinel `"N/A"`) to `Promise<string | null>` per
|
|
1744
|
+
the **magic-string elimination** locked decision. Both `return
|
|
1745
|
+
"N/A"` sites in each function become `return null`; consumers swap
|
|
1746
|
+
`=== "N/A"` checks for `=== null` checks. Both functions also gain
|
|
1747
|
+
`getLogger().error("Error in <funcName>:", error)` routing in their
|
|
1748
|
+
catch paths (was silent).
|
|
1749
|
+
|
|
1750
|
+
```ts
|
|
1751
|
+
// Before (v2.x):
|
|
1752
|
+
const spawnLimit = await getSWPSpawnLimit(swpair);
|
|
1753
|
+
if (spawnLimit === "N/A") showRPCError();
|
|
1754
|
+
else renderLimit(spawnLimit);
|
|
1755
|
+
|
|
1756
|
+
// After (v3.x):
|
|
1757
|
+
const spawnLimit = await getSWPSpawnLimit(swpair);
|
|
1758
|
+
if (spawnLimit === null) showRPCError();
|
|
1759
|
+
else renderLimit(spawnLimit);
|
|
1760
|
+
```
|
|
1761
|
+
|
|
1762
|
+
### Phase 3 logger-routing additions — no consumer migration required
|
|
1763
|
+
|
|
1764
|
+
The 14 NON-BREAKING logger-routing additions across 5 files
|
|
1765
|
+
(`dexFunctions.ts`, `ouroFunctions.ts`, `activateFunctions.ts`,
|
|
1766
|
+
`infoOneFunctions.ts`, and the `urStoaFunctions.ts` private helpers
|
|
1767
|
+
`verifyEd25519Sig` + `describeKeyset`) are pure observability —
|
|
1768
|
+
return types and parameter signatures are unchanged. Consumers who
|
|
1769
|
+
called `setLogger(...)` (introduced in v2.3.0) automatically capture
|
|
1770
|
+
the new error events with no additional wiring; consumers who did
|
|
1771
|
+
not configure a logger continue to see the default `console.error`
|
|
1772
|
+
output that the seam falls back to. No migration is required for
|
|
1773
|
+
this set of changes.
|
|
1774
|
+
|
|
1775
|
+
## Migrating to v2.x
|
|
1776
|
+
|
|
1777
|
+
Two breaking changes shipped in v2.0.0 — both consumer-side, no
|
|
1778
|
+
internal call sites in `src/` are affected.
|
|
1779
|
+
|
|
1780
|
+
### 1. `KadenaWallet` requires a `balanceResolver` to fetch balances
|
|
1781
|
+
|
|
1782
|
+
The `wallet/` subpath no longer imports from `interactions/*` (closes
|
|
1783
|
+
F-CORE-005). The `KadenaWallet` class now exposes a publicly mutable
|
|
1784
|
+
`balanceResolver: BalanceResolver` instance property. The default is a
|
|
1785
|
+
lazy throwing stub — it fires only when `wallet.getBalance()` is
|
|
1786
|
+
actually called, so wallets used purely for address derivation stay
|
|
1787
|
+
zero-config.
|
|
1788
|
+
|
|
1789
|
+
```ts
|
|
1790
|
+
import KadenaWallet from "@ouronet/ouronet-core/wallet";
|
|
1791
|
+
import { getBalance } from "@ouronet/ouronet-core/interactions/kadenaFunctions";
|
|
1792
|
+
|
|
1793
|
+
const wallet = new KadenaWallet({
|
|
1794
|
+
parentId: 0, index: 0,
|
|
1795
|
+
secret: ..., publicKey: ..., derivationPath: "m/44'/...",
|
|
1796
|
+
// Wrap interactions.getBalance to match the
|
|
1797
|
+
// (address) => Promise<string> contract:
|
|
1798
|
+
balanceResolver: (addr) => getBalance(addr).then((r) => r.balance ?? "0"),
|
|
1799
|
+
});
|
|
1800
|
+
|
|
1801
|
+
// Or assign post-construction:
|
|
1802
|
+
wallet.balanceResolver = (addr) => myIndexer.balanceOf(addr);
|
|
1803
|
+
```
|
|
1804
|
+
|
|
1805
|
+
`wallet.getBalance()` now **propagates errors** — the previous
|
|
1806
|
+
`?? "0"` silent fallback is gone (mildly breaking behavioural shift).
|
|
1807
|
+
Wrap the call in `try/catch`, or have your resolver default-on-error
|
|
1808
|
+
return `"0"`.
|
|
1809
|
+
|
|
1810
|
+
### 2. `simulateTransaction(pactCode, chainId)` signature change
|
|
1811
|
+
|
|
1812
|
+
`interactions/crossChainFunctions.simulateTransaction` previously
|
|
1813
|
+
accepted a pre-built `IUnsignedCommand` transaction object. It now
|
|
1814
|
+
accepts the Pact code string directly:
|
|
1815
|
+
|
|
1816
|
+
```ts
|
|
1817
|
+
// Before (v1.x):
|
|
1818
|
+
const tx = Pact.builder.execution(code).setMeta(...).createTransaction();
|
|
1819
|
+
const result = await simulateTransaction(tx, chainId);
|
|
1820
|
+
|
|
1821
|
+
// After (v2.x):
|
|
1822
|
+
const result = await simulateTransaction(code, chainId);
|
|
1823
|
+
```
|
|
1824
|
+
|
|
1825
|
+
The return shape `{ success, result?, error?, gas? }` is unchanged.
|
|
1826
|
+
|
|
1827
|
+
## Design docs
|
|
1828
|
+
|
|
1829
|
+
The architectural plan, per-phase migration history, HUB handoff, and
|
|
1830
|
+
decision log live in the **OuronetUI repo** under `docs/`:
|
|
1831
|
+
|
|
1832
|
+
- [`EXTRACT_OURONET_CORE_PLAN.md`](https://github.com/DemiourgosHoldings/OuronetUI/blob/dev/docs/EXTRACT_OURONET_CORE_PLAN.md) — the 8-phase migration plan (now complete)
|
|
1833
|
+
- [`ANCIENTHOLDER_HUB_HANDOFF.md`](https://github.com/DemiourgosHoldings/OuronetUI/blob/dev/docs/ANCIENTHOLDER_HUB_HANDOFF.md) — what the HUB agent needs to know to integrate
|
|
1834
|
+
- [`TESTING_STRATEGY.md`](https://github.com/DemiourgosHoldings/OuronetUI/blob/dev/docs/TESTING_STRATEGY.md) — 3-tier testing approach + current state + roadmap
|
|
1835
|
+
- [`CFM_BUILD_GUIDE.md`](https://github.com/DemiourgosHoldings/OuronetUI/blob/dev/docs/CFM_BUILD_GUIDE.md) — how a CFM modal uses this package
|
|
1836
|
+
|
|
1837
|
+
Don't fork logic — add to core, version-bump, publish, and consumers
|
|
1838
|
+
upgrade deliberately.
|
|
1839
|
+
|
|
1840
|
+
## Submodules
|
|
1841
|
+
|
|
1842
|
+
Each is a subpath export of the package: `import { ... } from "@ouronet/ouronet-core/<submodule>"`.
|
|
1843
|
+
|
|
1844
|
+
| Path | Contains |
|
|
1845
|
+
|---|---|
|
|
1846
|
+
| `@ouronet/ouronet-core/constants` | `KADENA_NAMESPACE`, `KADENA_CHAIN_ID`, `KADENA_NETWORK`, `PACT_URL`, gas-station + liquidpot addresses, every `TOKEN_ID_*` |
|
|
1847
|
+
| `@ouronet/ouronet-core/network` | Node failover (node2 → node1), URL construction; **(v2.1.0+)** `getFailoverClient(chainId, options?)` factory returning `{ dirtyRead, submit, listen, pollOne }` with `withFailover` + per-tier timeout baked in, `runWithTimeout(operation, fn, timeoutMs)` helper, `FailoverClientOptions` type, `resetNodeFailover()` for test isolation |
|
|
1848
|
+
| `@ouronet/ouronet-core/gas` | `calculateAutoGasLimit`, ANU/STOA math |
|
|
1849
|
+
| `@ouronet/ouronet-core/guard` | `analyzeGuard`, `buildCodexPubSet`, `selectCapsSigningKey`, `computeThreshold` (all predicates including `stoa-ns.stoic-predicates.*`); **(v1.6.0+)** `classifyGuardKind`, `extractKeysetFromGuard`, `analyzeSmartAccountAuthPaths` for the Smart Ouronet Account three-branch auth-path resolution (`enforce-one` over account-guard / sovereign-guard / governor) |
|
|
1850
|
+
| `@ouronet/ouronet-core/crypto` | V1 + V2 AES-GCM-256 encryption, `smartDecrypt`, pure `smartEncrypt(pt, pw, schemaVersion)`; **(v2.2.0+)** typed error classes `WrongPasswordError`, `CorruptEnvelopeError`, `UnsupportedFormatError` discriminate decryption failure modes; `smartDecrypt` single-path dispatch eliminates v1-then-v2 timing-leak |
|
|
1851
|
+
| `@ouronet/ouronet-core/signing` | `KeyResolver` / `SigningStrategy` interfaces, `CodexSigningStrategy`, `universalSignTransaction`, signing primitives (`publicKeyFromPrivateKey`, etc.) |
|
|
1852
|
+
| `@ouronet/ouronet-core/codex` | `PlaintextCodex` generic type, `serializeCodex` / `deserializeCodex` (backup format `"1.2"`), `migrateSeedType` |
|
|
1853
|
+
| `@ouronet/ouronet-core/reads` | `rawCalibratedDirtyRead` (pure Pact read with node failover + 15s timeout; no cache); **(v2.1.0+)** accepts a `readTimeoutMs?: number` option for per-call timeout override; **(v2.3.0+)** JSDoc enumerates the canonical tier mapping (T1=balance, T2=preview, T3=metadata, T7=very-static) and documents that the default reader accepts and ignores the `tier` argument — see `setPactReader` for cache-aware consumers |
|
|
1854
|
+
| `@ouronet/ouronet-core/observability` | **(v2.3.0+)** central logger seam mirroring `setPactReader`. Exports `Logger` type (`{ warn(msg, ...args), error(msg, ...args) }`), `setLogger(logger)` mutator (throws `TypeError("setLogger requires a non-null Logger")` on null/undefined), `getLogger()` accessor. Default routes `warn` to `console.warn` and `error` to `console.error` — consumers who do nothing observe identical behavior to direct `console.*` calls. |
|
|
1855
|
+
| `@ouronet/ouronet-core/guard` | **(v2.3.0+)** `UnknownPredicateError` typed class — thrown by `computeThreshold` on unrecognized predicates; `analyzeGuard` catches it and folds it into a `predicateRecognized: false` bit on the returned analysis. Also adds optional `firstSignableButUnsatisfied: number` field on `SmartAccountAuthPathsAnalysis`. |
|
|
1856
|
+
| `@ouronet/ouronet-core/pact` | `formatDecimalForPact`, `safeCreationTime`, `filterFreePositionData`, EU locale formatters, and **14 `buildXxxPactCode` builders** for every CFM function the ecosystem ships |
|
|
1857
|
+
| `@ouronet/ouronet-core/interactions` | Read helpers (`getXxxInfo`, `getXxxBalance`, `getHibernatedNonces…`) + non-CFM execute helpers (`executeWrapStoa`, `executeWrapUrStoa`, `executeNativeUrStoaTransfer`); **(v2.0.0+)** `simulateTransaction(pactCode, chainId)` (signature change — see Migrating to v2.x); **(v3.0.0+)** 16 fabricated-fallback fabrications widened to `Promise<T \| null>` (BREAKING — see Migrating to v3.x); 14 logger-routing additions across 5 files complete the silent-catch elimination (NON-BREAKING) |
|
|
1858
|
+
| `@ouronet/ouronet-core/dalos` | **(v1.3.0+)** thin re-export of `@ouronet/dalos-crypto/registry` + `createOuronetAccount(registry, options)` convenience helper covering all 6 DALOS input modes. One-stop shop for browser-side key-gen; no need to install `dalos-crypto` as a separate dep. **(v3.1.0+)** dep range bumped to `@ouronet/dalos-crypto@^4.0.3`; re-exports the lower-level Schnorr signature surface (`schnorrSign`, `schnorrVerify`, `schnorrSignAsync`, `schnorrVerifyAsync`, `SchnorrSignError`, `SchnorrSignature`) for advanced consumers — the `*Async` variants yield to the event loop on a fixed data-independent cadence so browser signing keeps INP < 200ms. |
|
|
1859
|
+
|
|
1860
|
+
## Quick start — `/dalos` subpath
|
|
1861
|
+
|
|
1862
|
+
Mint a new Ouronet account locally in one call:
|
|
1863
|
+
|
|
1864
|
+
```ts
|
|
1865
|
+
import {
|
|
1866
|
+
createDefaultRegistry,
|
|
1867
|
+
createOuronetAccount,
|
|
1868
|
+
} from "@ouronet/ouronet-core/dalos";
|
|
1869
|
+
|
|
1870
|
+
const registry = createDefaultRegistry();
|
|
1871
|
+
|
|
1872
|
+
// Random account (simplest — OS randomness)
|
|
1873
|
+
const a = createOuronetAccount(registry, { mode: "random" });
|
|
1874
|
+
|
|
1875
|
+
// From a seed phrase (any array of UTF-8 words, 4–256 entries)
|
|
1876
|
+
const b = createOuronetAccount(registry, {
|
|
1877
|
+
mode: "seedWords",
|
|
1878
|
+
data: ["mountain", "whisper", "aurora", "eternal"],
|
|
1879
|
+
});
|
|
1880
|
+
|
|
1881
|
+
// From a 40×40 bitmap (1 = black, 0 = white; row-major TTB-LTR)
|
|
1882
|
+
import type { Bitmap } from "@ouronet/ouronet-core/dalos";
|
|
1883
|
+
const bitmap: Bitmap = /* 40 rows × 40 cols */;
|
|
1884
|
+
const c = createOuronetAccount(registry, { mode: "bitmap", data: bitmap });
|
|
1885
|
+
|
|
1886
|
+
console.log(b.standardAddress); // Ѻ.xxxxx…
|
|
1887
|
+
console.log(b.keyPair.priv); // base-49 private key
|
|
1888
|
+
console.log(b.privateKey.int49); // same, via `privateKey` object
|
|
1889
|
+
console.log(b.privateKey.int10); // base-10 representation
|
|
1890
|
+
console.log(b.privateKey.bitString); // 1600-bit binary
|
|
1891
|
+
```
|
|
1892
|
+
|
|
1893
|
+
Same API shape as `@ouronet/dalos-crypto/registry` — OuronetCore just
|
|
1894
|
+
re-exports the types and adds `createOuronetAccount` as a convenience.
|
|
1895
|
+
See [`@ouronet/dalos-crypto`](https://www.npmjs.com/package/@ouronet/dalos-crypto)
|
|
1896
|
+
for deeper documentation on the cryptographic primitive itself.
|
|
1897
|
+
|
|
1898
|
+
## Local development
|
|
1899
|
+
|
|
1900
|
+
```bash
|
|
1901
|
+
npm install
|
|
1902
|
+
npm run build # tsc -p tsconfig.build.json → dist/
|
|
1903
|
+
npm run typecheck # tsc --noEmit
|
|
1904
|
+
npm test # vitest run — 558 tests across crypto, guard, gas, pact format, signing, strategy, codex, cfmBuilders, dalos integration, wallet, interactions-read-seam, network, failover-client, timeouts, failover-submit, pact-reader, wallet-builder, transaction-errors, seed-type-migration, crypto-errors, crypto-v2-classification, package-version, observability-logger, phase5-catch-routing, interactions-pricing, interactions-balance-cluster, interactions-logger-parity
|
|
1905
|
+
```
|
|
1906
|
+
|
|
1907
|
+
To hot-reload changes into OuronetUI (which now depends on the published
|
|
1908
|
+
registry version), use `npm link`:
|
|
1909
|
+
|
|
1910
|
+
```bash
|
|
1911
|
+
cd stoa-js && npm link
|
|
1912
|
+
cd OuronetUI && npm link @ouronet/ouronet-core
|
|
1913
|
+
# Edit core, run `npm run build` in stoa-js, UI picks up the change.
|
|
1914
|
+
# npm unlink @ouronet/ouronet-core # restores registry resolution
|
|
1915
|
+
```
|
|
1916
|
+
|
|
1917
|
+
## Publishing
|
|
1918
|
+
|
|
1919
|
+
Push a `v*`-prefixed tag and `.github/workflows/publish.yml` handles the
|
|
1920
|
+
rest — typecheck + build + test + `npm publish` to **public npmjs.org**
|
|
1921
|
+
under the `@stoachain` scope. Version parity check bakes in protection
|
|
1922
|
+
against mismatched tag / package.json versions.
|
|
1923
|
+
|
|
1924
|
+
```bash
|
|
1925
|
+
# After bumping package.json + CHANGELOG.md and committing:
|
|
1926
|
+
git tag v1.3.1 -m "v1.3.1 — ..."
|
|
1927
|
+
git push origin v1.3.1
|
|
1928
|
+
# Workflow publishes within ~2 minutes. Consumers run `npm install` to pick up.
|
|
1929
|
+
```
|
|
1930
|
+
|
|
1931
|
+
## Versioning
|
|
1932
|
+
|
|
1933
|
+
Strict semver. Breaking changes → major version bump → consumers upgrade
|
|
1934
|
+
deliberately. Changelog in `CHANGELOG.md`.
|
|
1935
|
+
|
|
1936
|
+
## License
|
|
1937
|
+
|
|
1938
|
+
UNLICENSED (org-owned package). Public on
|
|
1939
|
+
[npmjs.com/package/@ouronet/ouronet-core](https://www.npmjs.com/package/@ouronet/ouronet-core);
|
|
1940
|
+
authoring rights retained by AncientHoldings GmbH.
|