|
1 | 1 | # Antelope ECC Changelog |
2 | 2 |
|
| 3 | +## 6.0.0 - 2026-08-07 |
| 4 | + |
| 5 | +### Breaking Changes |
| 6 | + |
| 7 | +- Updated the minimum supported Node.js version to **Node.js 22**. |
| 8 | +- Migrated `ripemd160-js` from v3 to **v4** and adopted its synchronous `Uint8Array -> Uint8Array` API. |
| 9 | +- Updated `isomorphic-secp256k1-js` to **v6**. |
| 10 | +- Standardized the package as **native ESM**. |
| 11 | +- Removed legacy/default package export behavior. Consumers should use named imports or documented deep imports. |
| 12 | +- Package build artifacts are now generated under `dist/` rather than alongside TypeScript source files. |
| 13 | +- Renamed the `sign_packed_txn()` `extension` argument to `context_free_data_hash` to correctly describe its role in the Antelope transaction signing preimage. |
| 14 | +- `new_keys()` is now synchronous and returns the generated key pair directly instead of `Promise<{ public_key, private_key }>`. |
| 15 | +- `recover_public_key()` is now synchronous and returns the recovered `PUB_K1_` key directly instead of `Promise<string>`. |
| 16 | +- Public-key derivation and RIPEMD-backed key conversion and validation operations no longer introduce unnecessary Promise wrappers. |
| 17 | +- `mnemonic_recover()` is now asynchronous because BIP39 recovery verifies the mnemonic checksum using SHA-256. |
| 18 | +- Key decoding and validation are stricter and may now reject malformed, checksum-valid, or structurally invalid key material that older versions accepted. |
| 19 | +- Signing now requires an exact 32-byte digest. Malformed, partial, or incorrectly sized hexadecimal input is rejected. |
| 20 | +- Existing callers using `await` with newly synchronous APIs remain compatible because JavaScript permits awaiting non-Promise values, but callers using `.then()`, `.catch()`, `Promise.all()`, or explicit `Promise<T>` typings must update their code. |
| 21 | + |
| 22 | +### Added |
| 23 | + |
| 24 | +- Added a side-effect-free root ESM entry point exposing the supported API through named exports. |
| 25 | +- Added explicit supported deep-import paths. |
| 26 | +- Added TypeScript declaration generation for the complete published API. |
| 27 | +- Added npm package smoke testing against the actual tarball produced by `npm pack`. |
| 28 | +- Added a committed npm lockfile for reproducible installations and CI. |
| 29 | +- Added modern ESLint flat configuration. |
| 30 | +- Added automated lint-fix and formatting scripts. |
| 31 | +- Added CI coverage across Node.js **22, 24, and 26** on Linux and macOS. |
| 32 | +- Added strict secp256k1 scalar validation for `PVT_K1_` private keys. |
| 33 | +- Added strict compressed SEC 1 point validation for `PUB_K1_` public keys. |
| 34 | +- Added checksum validation when decoding K1 private and public keys. |
| 35 | +- Added checksum validation when decoding and recovering `SIG_K1_` signatures. |
| 36 | +- Added strict 32-byte digest validation for signing and public-key recovery. |
| 37 | +- Added strict hexadecimal validation for packed transaction signing inputs. |
| 38 | +- Added validation that `chain_id` and `context_free_data_hash` are exactly 32 bytes. |
| 39 | +- Added bounded rejection sampling when generating random secp256k1 private keys. |
| 40 | +- Added BIP39 checksum validation during mnemonic recovery. |
| 41 | +- Added validation for standard BIP39 entropy sizes of 128, 160, 192, 224, and 256 bits. |
| 42 | +- Added validation for standard BIP39 mnemonic lengths of 12, 15, 18, 21, and 24 words. |
| 43 | +- Added BIP39 known-vector and invalid-checksum tests. |
| 44 | +- Added tests for checksum-valid but cryptographically invalid secp256k1 keys. |
| 45 | +- Added smoke-test assertions ensuring synchronous public APIs do not accidentally regress back to returning Promises. |
| 46 | + |
| 47 | +### Changed |
| 48 | + |
| 49 | +- RIPEMD-160 imports now use the v4 package API: |
| 50 | + |
| 51 | + ```js |
| 52 | + import { ripemd160 } from "ripemd160-js"; |
| 53 | + ``` |
| 54 | + |
| 55 | +- Updated Antelope private-key, public-key, and signature checksum operations to use synchronous RIPEMD-160. |
| 56 | + |
| 57 | +- Removed unnecessary asynchronous RIPEMD-160 checksum handling. |
| 58 | + |
| 59 | +- Updated K1 key encoding and decoding so cryptographic validity is checked in addition to Antelope Base58 checksum validity. |
| 60 | + |
| 61 | +- `private_key_from_wif()` now validates the `PVT_K1_` checksum and secp256k1 scalar before returning the raw private key. |
| 62 | + |
| 63 | +- `public_key_from_wif()` now validates the `PUB_K1_` checksum and compressed secp256k1 point before returning the raw public key. |
| 64 | + |
| 65 | +- `private_key_to_wif()` now rejects invalid secp256k1 private scalars before encoding them. |
| 66 | + |
| 67 | +- `public_key_to_wif()` now requires a valid compressed 33-byte secp256k1 public key before encoding it. |
| 68 | + |
| 69 | +- `public_key_from_private_wif()` now uses the validated private-key decoding path before deriving the public key. |
| 70 | + |
| 71 | +- `sign()` now validates the supplied `PVT_K1_` private key before signing. |
| 72 | + |
| 73 | +- `sign()` now accepts only: |
| 74 | + |
| 75 | + - a 32-byte `Uint8Array`; or |
| 76 | + - a hexadecimal string containing exactly 64 hexadecimal characters. |
| 77 | + |
| 78 | +- `recover_public_key()` now validates the full `SIG_K1_` checksum before attempting secp256k1 public-key recovery. |
| 79 | + |
| 80 | +- `recover_public_key()` now requires an exact 32-byte digest. |
| 81 | + |
| 82 | +- `sign_packed_txn()` now validates the complete signing preimage rather than extracting hexadecimal byte pairs from partially valid input. |
| 83 | + |
| 84 | +- `transaction_header` and `transaction_body` must now contain complete, even-length hexadecimal byte strings. |
| 85 | + |
| 86 | +- `chain_id` must contain exactly 32 bytes of hexadecimal data. |
| 87 | + |
| 88 | +- `context_free_data_hash` must contain exactly 32 bytes of hexadecimal data. |
| 89 | + |
| 90 | +- `context_free_data_hash` defaults to 32 zero bytes when no context-free data is present. |
| 91 | + |
| 92 | +- Clarified that `context_free_data_hash` is unrelated to Antelope `transaction_extensions`, which are serialized as part of the transaction itself. |
| 93 | + |
| 94 | +- Replaced environment-specific Node.js random-byte handling with the standard Web Crypto API: |
| 95 | + |
| 96 | + ```js |
| 97 | + globalThis.crypto.getRandomValues(...) |
| 98 | + ``` |
| 99 | + |
| 100 | +- Removed the previous `require("crypto")` and dynamic `import("crypto")` random-byte fallback logic. |
| 101 | + |
| 102 | +- Random-byte generation now uses the same standards-based API in Node.js and modern browsers. |
| 103 | + |
| 104 | +- Random-byte generation supports requests larger than the Web Crypto 65,536-byte per-call limit by filling the result in chunks. |
| 105 | + |
| 106 | +- `new_keys()` now retries random candidates that are outside the valid secp256k1 private-scalar range. |
| 107 | + |
| 108 | +- BIP39 mnemonic creation now validates supported entropy sizes. |
| 109 | + |
| 110 | +- BIP39 mnemonic recovery now verifies checksum bits before returning entropy. |
| 111 | + |
| 112 | +- Retained the historical Antelope/Graphene compact-canonical signature compatibility policy inside `antelope-ecc`. |
| 113 | + |
| 114 | +- Kept generic standards-focused secp256k1 behavior isolated inside `isomorphic-secp256k1-js`. |
| 115 | + |
| 116 | +- Updated TypeScript compilation to use `NodeNext` module and module-resolution semantics. |
| 117 | + |
| 118 | +- TypeScript source now lives exclusively under `src/`. |
| 119 | + |
| 120 | +- Compiled JavaScript and `.d.ts` files are generated exclusively under `dist/`. |
| 121 | + |
| 122 | +- npm now publishes only the compiled `dist/` distribution. |
| 123 | + |
| 124 | +- Updated README documentation for the v6 API, synchronous and asynchronous API boundaries, ESM usage, deep imports, Node.js requirements, Web Crypto support, package structure, signing semantics, and security considerations. |
| 125 | + |
| 126 | +### Async API Boundary |
| 127 | + |
| 128 | +The following APIs remain asynchronous because they perform operations that genuinely require asynchronous Web Crypto primitives: |
| 129 | + |
| 130 | +- `sign()` — RFC 6979 signing uses asynchronous HMAC-SHA-256. |
| 131 | +- `sign_packed_txn()` — computes SHA-256 and then signs the resulting digest. |
| 132 | +- `legacy_from_private_key()` — performs SHA-256 checksum operations. |
| 133 | +- `mnemonic_create()` — computes the BIP39 SHA-256 checksum. |
| 134 | +- `mnemonic_recover()` — verifies the BIP39 SHA-256 checksum. |
| 135 | + |
| 136 | +Pure key encoding, decoding, validation, public-key derivation, secure random-byte generation, and public-key recovery operations are synchronous. |
| 137 | + |
| 138 | +### Tooling |
| 139 | + |
| 140 | +- Updated TypeScript to v6. |
| 141 | +- Migrated from legacy `.eslintrc` configuration to ESLint flat config. |
| 142 | +- Updated ESLint to v10. |
| 143 | +- Updated Prettier to v3. |
| 144 | +- Updated `typescript-eslint`. |
| 145 | +- Updated `eslint-plugin-simple-import-sort`. |
| 146 | +- Updated test and development dependencies. |
| 147 | +- CI now uses `npm ci`. |
| 148 | +- CI now runs the complete npm package smoke test. |
| 149 | +- Simplified build cleanup so only generated `dist/` output is removed. |
| 150 | + |
| 151 | +### Package Structure |
| 152 | + |
| 153 | +Source files are maintained under: |
| 154 | + |
| 155 | +```text |
| 156 | +src/ |
| 157 | +├── index.ts |
| 158 | +├── sign.ts |
| 159 | +├── sign_packed_txn.ts |
| 160 | +├── recover_public_key.ts |
| 161 | +├── new_keys.ts |
| 162 | +├── mnemonic_create.ts |
| 163 | +├── mnemonic_recover.ts |
| 164 | +├── keys/ |
| 165 | +└── internal/ |
| 166 | +``` |
| 167 | + |
| 168 | +TypeScript generates the npm distribution under: |
| 169 | + |
| 170 | +```text |
| 171 | +dist/ |
| 172 | +├── index.js |
| 173 | +├── index.d.ts |
| 174 | +├── sign.js |
| 175 | +├── sign.d.ts |
| 176 | +├── sign_packed_txn.js |
| 177 | +├── sign_packed_txn.d.ts |
| 178 | +├── recover_public_key.js |
| 179 | +├── recover_public_key.d.ts |
| 180 | +├── new_keys.js |
| 181 | +├── new_keys.d.ts |
| 182 | +├── mnemonic_create.js |
| 183 | +├── mnemonic_create.d.ts |
| 184 | +├── mnemonic_recover.js |
| 185 | +├── mnemonic_recover.d.ts |
| 186 | +├── keys/ |
| 187 | +└── internal/ |
| 188 | +``` |
| 189 | + |
| 190 | +Generated JavaScript is no longer stored alongside TypeScript source files. |
| 191 | + |
| 192 | +### Dependencies |
| 193 | + |
| 194 | +Runtime dependencies are now: |
| 195 | + |
| 196 | +- `base58-js` v3 |
| 197 | +- `isomorphic-secp256k1-js` v6 |
| 198 | +- `ripemd160-js` v4 |
| 199 | + |
| 200 | +### Removed |
| 201 | + |
| 202 | +- Removed support for Node.js versions below 22. |
| 203 | +- Removed support for `ripemd160-js` v3. |
| 204 | +- Removed the legacy `ripemd160-js/ripemd160.js` deep import. |
| 205 | +- Removed the unused `eosio-wasm-js` runtime dependency. |
| 206 | +- Removed Node-specific `require("crypto")` random-byte handling. |
| 207 | +- Removed dynamic Node `crypto` import fallback logic. |
| 208 | +- Removed legacy ESLint `.eslintrc` configuration. |
| 209 | +- Removed generated JavaScript from the TypeScript source tree. |
| 210 | +- Removed obsolete root-level compiler output and cleanup behavior. |
| 211 | +- Removed stale CommonJS and default-import documentation. |
| 212 | +- Removed unnecessary Promise wrappers from synchronous key and recovery operations. |
| 213 | + |
| 214 | +### Migration Notes |
| 215 | + |
| 216 | +Applications upgrading from v5 should: |
| 217 | + |
| 218 | +- run on Node.js 22 or later; |
| 219 | +- update default package imports to named imports; |
| 220 | +- use documented package exports for deep imports; |
| 221 | +- update `sign_packed_txn()` calls from `extension` to `context_free_data_hash`; |
| 222 | +- treat `new_keys()` as synchronous; |
| 223 | +- treat `recover_public_key()` as synchronous; |
| 224 | +- update `.then()` or explicit Promise typings for APIs that now return values directly; |
| 225 | +- provide exactly 32-byte digests to `sign()` and `recover_public_key()`; |
| 226 | +- expect malformed or cryptographically invalid K1 keys to be rejected more strictly; |
| 227 | +- `await mnemonic_recover()` because mnemonic recovery now performs BIP39 checksum verification. |
| 228 | + |
| 229 | +Typical root imports are: |
| 230 | + |
| 231 | +```js |
| 232 | +import { |
| 233 | + new_keys, |
| 234 | + recover_public_key, |
| 235 | + sign, |
| 236 | + sign_packed_txn, |
| 237 | + validate_private_key, |
| 238 | + validate_public_key, |
| 239 | +} from "antelope-ecc"; |
| 240 | +``` |
| 241 | + |
| 242 | +Individual modules may also be imported through documented package subpaths: |
| 243 | + |
| 244 | +```js |
| 245 | +import sign from "antelope-ecc/sign.js"; |
| 246 | +import new_keys from "antelope-ecc/new_keys.js"; |
| 247 | +``` |
| 248 | + |
3 | 249 | ## 5.0.1 - 2026-08-03 |
4 | 250 |
|
5 | 251 | ### Major |
|
0 commit comments