wative-core 2.4.2 → 2.4.4
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 +21 -29
- package/README.md +21 -32
- package/dist/artifacts/evm/index.cjs +1 -1
- package/dist/artifacts/evm/index.d.cts +2 -2
- package/dist/artifacts/evm/index.d.ts +2 -2
- package/dist/artifacts/evm/index.js +1 -1
- package/dist/artifacts/svm/index.cjs +1 -1
- package/dist/artifacts/svm/index.d.cts +3 -3
- package/dist/artifacts/svm/index.d.ts +3 -3
- package/dist/artifacts/svm/index.js +1 -1
- package/dist/{container-provider-YxyMpkhG.d.cts → container-provider-BHHQ3D_6.d.cts} +3 -1
- package/dist/{container-provider-B8M0ylrK.d.ts → container-provider-BlCZxRdL.d.ts} +3 -1
- package/dist/{evm-DA6Sh6jv.d.cts → evm-Budo2tT1.d.cts} +1 -1
- package/dist/{evm-Bo3Dy492.d.ts → evm-aNe3xFxN.d.ts} +1 -1
- package/dist/{file-sink-KCCpKHRj.d.cts → file-sink-GGSUbddN.d.cts} +4 -2
- package/dist/{file-sink-Be5iLbuT.d.ts → file-sink-mJ2y6o7H.d.ts} +4 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1 -1
- package/dist/index.node.cjs +1 -1
- package/dist/index.node.d.cts +5 -5
- package/dist/index.node.d.ts +5 -5
- package/dist/index.node.js +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +3 -3
- package/dist/node/index.d.ts +3 -3
- package/dist/node/index.js +1 -1
- package/dist/{svm-DswX6XRv.d.cts → svm-CXjYOYxt.d.cts} +1 -1
- package/dist/{svm-B51NevS8.d.ts → svm-Cndg5tXR.d.ts} +1 -1
- package/dist/{workspace-CBxKR80D.d.cts → workspace-bxOhg4wh.d.cts} +6 -43
- package/dist/{workspace-CBxKR80D.d.ts → workspace-bxOhg4wh.d.ts} +6 -43
- package/examples/01-quick-start.test.cjs +1 -2
- package/examples/02-hd-account.test.cjs +1 -2
- package/examples/03-pk-account.test.cjs +1 -28
- package/examples/04-network-management.test.cjs +1 -2
- package/examples/05-asset-management.test.cjs +1 -2
- package/examples/06-address-signing.test.cjs +1 -2
- package/examples/07-custom-provider.test.cjs +2 -8
- package/examples/08-persistence.test.cjs +1 -2
- package/examples/09-workspace-filter.test.cjs +1 -2
- package/examples/10-default-network.test.cjs +1 -3
- package/examples/11-subpath-imports.test.cjs +2 -6
- package/examples/12-logger.test.cjs +1 -3
- package/examples/13-workspace-config.test.cjs +1 -5
- package/examples/14-esm-runtime.test.mjs +0 -9
- package/examples/15-package-resolution.test.cjs +5 -83
- package/examples/16-known-answer-vectors.test.cjs +4 -22
- package/examples/17-locked-state.test.cjs +2 -23
- package/examples/18-envelope-v3.test.cjs +2 -21
- package/examples/19-simple-provider.test.cjs +1 -19
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,44 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `wative-core` are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
4
|
|
|
5
|
-
## [2.4.
|
|
5
|
+
## [2.4.4] — 2026-08-12
|
|
6
|
+
|
|
7
|
+
Correctness fixes across signing, storage and the network layer.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- Signing twice, or signing after sending, no longer double-signs a transaction or erases its recorded on-chain outcome.
|
|
11
|
+
- A Solana transaction reports the id the network knows it by, not the wallet's own signature — including after a failed broadcast.
|
|
12
|
+
- Requests to a node now have a deadline, so an unresponsive endpoint no longer leaves a transaction hanging indefinitely.
|
|
13
|
+
- A failed unlock leaves no open session and no stray directories behind, and a workspace root that is a symlink is refused.
|
|
14
|
+
- `signTransaction(tx)` returns the type it was given. Type-only: a non-generic value assigned to it now needs the same shape.
|
|
6
15
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
16
|
+
## [2.4.3] — 2026-08-11
|
|
17
|
+
|
|
18
|
+
Documentation only. No API or behaviour changes from 2.4.2.
|
|
10
19
|
|
|
11
20
|
### Changed
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`addresses[0]`, so code reading that position is unaffected — but
|
|
16
|
-
`addresses.length` is now 2, and totals derived from it will differ.
|
|
21
|
+
- The README now leads with what a `Record` is and where records can live, and states plainly that one imported key controls both addresses in a PK wallet.
|
|
22
|
+
|
|
23
|
+
## [2.4.2] — 2026-08-11
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
so both addresses come from it, and whoever learns that key holds both
|
|
20
|
-
chains. This is not how an HD account behaves: there a slot's two addresses
|
|
21
|
-
come from two derivation paths and are independent keys. Use an HD account,
|
|
22
|
-
or import a separate key per chain, if you need that separation.
|
|
25
|
+
Importing a private key is easier, and one import now reaches both chains.
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
### Changed
|
|
28
|
+
- **BREAKING.** A PK wallet now holds two addresses — the chain you imported for, plus one on the other chain derived from the same secret, so one key controls both. `addresses[0]` is unchanged; `addresses.length` is now 2. Existing stored wallets keep their single address.
|
|
26
29
|
|
|
27
30
|
### Added
|
|
28
|
-
-
|
|
29
|
-
overlap — 64 hex characters for EVM, 80–96 base58 for Solana — so the chain is
|
|
30
|
-
read off the key. Passing `vm` explicitly still works and still wins.
|
|
31
|
-
- **`solana-keygen` JSON byte arrays are accepted.** The contents of
|
|
32
|
-
`~/.config/solana/id.json` can be handed to `importPrivateKey` as-is, instead
|
|
33
|
-
of being converted to base58 by hand first.
|
|
31
|
+
- `importPrivateKey(pk)` no longer needs a `vm` — the chain is read from the key — and accepts the JSON byte array `solana-keygen` writes.
|
|
34
32
|
|
|
35
33
|
### Fixed
|
|
36
|
-
-
|
|
37
|
-
hex is not necessarily a key: zero, and anything at or above the secp256k1
|
|
38
|
-
group order, previously reached the curve library and surfaced as a bare
|
|
39
|
-
`Error` with no `code`, thrown from inside a queued mutation. It is refused at
|
|
40
|
-
the boundary now, like every other malformed key.
|
|
41
|
-
- Corrected the README's account diagrams, which described a PK wallet as
|
|
42
|
-
carrying exactly one address as though it were a structural rule.
|
|
34
|
+
- An EVM private key outside the valid range is refused as `INVALID_PRIVATE_KEY` instead of surfacing as an untyped error.
|
|
43
35
|
|
|
44
36
|
## [2.4.1] — 2026-08-11
|
|
45
37
|
|
package/README.md
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
Hyperscale crypto wallet management library — multi-workspace, multi-chain, originally designed for on-chain market makers.
|
|
9
9
|
|
|
10
|
-
Runs in Node and in the browser.
|
|
11
|
-
|
|
10
|
+
Runs in Node and in the browser environments. Everything a workspace persists — wallets, accounts, networks, assets — is encrypted `Record` layer, sealed by the library exclusively seen by creators.
|
|
11
|
+
|
|
12
|
+
Where those records live is yours to choose: files, IndexedDB, Docker, NSA, databases, CDN, RAM, etc. Any encryption algorithm, any format, any storage media.
|
|
12
13
|
|
|
13
14
|
## How it fits together
|
|
14
15
|
|
|
@@ -65,15 +66,6 @@ Account "Cold Storage" (PK) no mnemonic
|
|
|
65
66
|
A PK account can hold as many keys as you like, on any mix of chains — but it
|
|
66
67
|
refuses the same identity twice, on either chain.
|
|
67
68
|
|
|
68
|
-
> ⚠️ **One secret controls both addresses in a PK wallet.** There is only one
|
|
69
|
-
> key to import, so both addresses come from it. Whoever learns that key holds
|
|
70
|
-
> both chains.
|
|
71
|
-
>
|
|
72
|
-
> This is not how an HD account works. There, a slot's two addresses come from
|
|
73
|
-
> two different derivation paths — the mnemonic is shared, the private keys are
|
|
74
|
-
> independent. If you want independent keys per chain, use an HD account, or
|
|
75
|
-
> import a separate key for each and read `addresses[0]` of each wallet.
|
|
76
|
-
|
|
77
69
|
> **`wallet.addresses` is a list.** It holds one address per `(vm, network)`
|
|
78
70
|
> pair and is free to carry several. Read it rather than assuming a position:
|
|
79
71
|
>
|
|
@@ -113,10 +105,10 @@ await hd.deriveWallets(5); // slots 1..5, alongside slot 0
|
|
|
113
105
|
hd.wallets[0].addresses.find((a) => a.vm === "evm");
|
|
114
106
|
hd.wallets[0].addresses.find((a) => a.vm === "svm");
|
|
115
107
|
|
|
116
|
-
// PK — each import is its own wallet, on
|
|
108
|
+
// PK — each import is its own wallet, with an address on both chains
|
|
117
109
|
const pk = await ws.accounts.create("Cold Storage", password, privateKey);
|
|
118
|
-
await pk.importPrivateKey(anotherEvmKey
|
|
119
|
-
await pk.importPrivateKey(aSolanaKey
|
|
110
|
+
await pk.importPrivateKey(anotherEvmKey); // -> a new Wallet, vm inferred
|
|
111
|
+
await pk.importPrivateKey(aSolanaKey); // -> another new Wallet
|
|
120
112
|
```
|
|
121
113
|
|
|
122
114
|
## Install
|
|
@@ -292,9 +284,7 @@ to be sure you get it rather than the fallback.
|
|
|
292
284
|
import { argon2BackendInfo } from "wative-core";
|
|
293
285
|
|
|
294
286
|
argon2BackendInfo();
|
|
295
|
-
// { backend: "wasm", wasm
|
|
296
|
-
// { backend: "noble", wasm: false, reason: "...", overrides: [] } ← degraded
|
|
297
|
-
// { backend: "unresolved", wasm: false, ..., overrides: ["node-rs"] }
|
|
287
|
+
// -> { backend: "wasm" | "noble" | "unresolved", wasm, reason?, overrides }
|
|
298
288
|
```
|
|
299
289
|
|
|
300
290
|
`backend` is the process-wide default. A provider may carry its own — a
|
|
@@ -403,13 +393,10 @@ So a typical lifecycle looks like:
|
|
|
403
393
|
// First run on a fresh machine — env unset, no <cwd>/.wative2 → creates ~/.wative2
|
|
404
394
|
await Workspace.open({ password: "wsp-pwd" });
|
|
405
395
|
|
|
406
|
-
//
|
|
407
|
-
// $ mkdir .wative2
|
|
408
|
-
// Now <cwd>/.wative2 exists → tier 2 wins
|
|
396
|
+
// After `mkdir .wative2`, <cwd>/.wative2 exists and tier 2 wins
|
|
409
397
|
await Workspace.open({ password: "wsp-pwd" });
|
|
410
398
|
|
|
411
|
-
// Or
|
|
412
|
-
// $ WATIVE_WORKSPACE_PATH=/srv/wative-staging node app.js
|
|
399
|
+
// Or set WATIVE_WORKSPACE_PATH=/srv/wative-staging to override
|
|
413
400
|
await Workspace.open({ password: "wsp-pwd" });
|
|
414
401
|
```
|
|
415
402
|
|
|
@@ -469,6 +456,15 @@ await hd.wallets.drop(hd.wallets[10]);
|
|
|
469
456
|
|
|
470
457
|
### Address — sign messages, build transactions
|
|
471
458
|
|
|
459
|
+
> ⚠️ **One secret controls both addresses in a PK wallet.** There is only one
|
|
460
|
+
> key to import, so both addresses come from it. Whoever learns that key holds
|
|
461
|
+
> both chains.
|
|
462
|
+
>
|
|
463
|
+
> This is not how an HD account works. There, a slot's two addresses come from
|
|
464
|
+
> two different derivation paths — the mnemonic is shared, the private keys are
|
|
465
|
+
> independent. If you want independent keys per chain, use an HD account, or
|
|
466
|
+
> import a separate key for each and read `addresses[0]` of each wallet.
|
|
467
|
+
|
|
472
468
|
```ts
|
|
473
469
|
const evmAddr = hd.wallets[0].addresses.find((a) => a.vm === "evm")!;
|
|
474
470
|
const svmAddr = hd.wallets[0].addresses.find((a) => a.vm === "svm")!;
|
|
@@ -562,11 +558,7 @@ const evmTx = new EvmTransaction({
|
|
|
562
558
|
from: evmAddr.publicKey as EvmAddress,
|
|
563
559
|
to: "0x1234567890123456789012345678901234567890" as EvmAddress,
|
|
564
560
|
value: 10_000_000n,
|
|
565
|
-
|
|
566
|
-
// and there is no `network` field on a transaction — both are refused
|
|
567
|
-
// rather than guessed, because a signed transaction for the wrong chain is
|
|
568
|
-
// still a valid transaction on that chain.
|
|
569
|
-
chainId: 8453 as ChainId, // Base
|
|
561
|
+
chainId: 8453 as ChainId, // required, no default; there is no `network` field
|
|
570
562
|
gasLimit: 21000n,
|
|
571
563
|
maxFeePerGas: 50_000_000_000n,
|
|
572
564
|
maxPriorityFeePerGas: 1_000_000_000n,
|
|
@@ -591,8 +583,7 @@ const evmTx = evmAddr.buildTransaction({
|
|
|
591
583
|
gasLimit: 21000n,
|
|
592
584
|
});
|
|
593
585
|
const rawEvm = evmTx.toRawTx();
|
|
594
|
-
// { from, to, value, data, type, chainId, gasLimit, ... }
|
|
595
|
-
// pass `rawEvm` to web3.eth.sendTransaction, ethers Signer, viem walletClient, etc.
|
|
586
|
+
// { from, to, value, data, type, chainId, gasLimit, ... } — hand to web3/ethers/viem
|
|
596
587
|
```
|
|
597
588
|
|
|
598
589
|
```ts
|
|
@@ -602,9 +593,7 @@ const svmTx = svmAddr.buildTransaction({
|
|
|
602
593
|
amount: 1_000_000n,
|
|
603
594
|
});
|
|
604
595
|
const rawSvm = await svmTx.toRawTx();
|
|
605
|
-
// rawSvm.add(
|
|
606
|
-
// rawSvm.sign(theirKeypair);
|
|
607
|
-
// connection.sendRawTransaction(rawSvm.serialize());
|
|
596
|
+
// then rawSvm.add(...) / .sign(...) / connection.sendRawTransaction(rawSvm.serialize())
|
|
608
597
|
```
|
|
609
598
|
|
|
610
599
|
For SVM, if you supply `recentBlockhash` at construction time, `toRawTx()` builds entirely offline — no Address binding required.
|