wative-core 2.5.6 → 2.5.7

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +5 -6
  3. package/dist/artifacts/evm/index.cjs +1 -1
  4. package/dist/artifacts/evm/index.d.cts +2 -2
  5. package/dist/artifacts/evm/index.d.ts +2 -2
  6. package/dist/artifacts/evm/index.js +1 -1
  7. package/dist/artifacts/svm/index.cjs +1 -1
  8. package/dist/artifacts/svm/index.d.cts +3 -3
  9. package/dist/artifacts/svm/index.d.ts +3 -3
  10. package/dist/artifacts/svm/index.js +1 -1
  11. package/dist/{container-provider-BOFF5wqv.d.ts → container-provider-CqpIaus8.d.ts} +1 -1
  12. package/dist/{container-provider-QvO3JYFb.d.cts → container-provider-sRxvigzk.d.cts} +1 -1
  13. package/dist/{evm-BWORcsia.d.ts → evm-KpZ3cLDe.d.ts} +1 -1
  14. package/dist/{evm-DaLCh_ce.d.cts → evm-hYUvjm9n.d.cts} +1 -1
  15. package/dist/{file-sink-DJEWW4yu.d.cts → file-sink-B94nIe1u.d.cts} +2 -2
  16. package/dist/{file-sink-bJzTrooq.d.ts → file-sink-Di2hJA5x.d.ts} +2 -2
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.d.cts +6 -6
  19. package/dist/index.d.ts +6 -6
  20. package/dist/index.js +1 -1
  21. package/dist/index.node.cjs +1 -1
  22. package/dist/index.node.d.cts +5 -5
  23. package/dist/index.node.d.ts +5 -5
  24. package/dist/index.node.js +1 -1
  25. package/dist/node/index.cjs +1 -1
  26. package/dist/node/index.d.cts +3 -3
  27. package/dist/node/index.d.ts +3 -3
  28. package/dist/node/index.js +1 -1
  29. package/dist/{svm-BYbTqW4J.d.cts → svm-B88JqNxb.d.cts} +1 -1
  30. package/dist/{svm-5rQU53_9.d.ts → svm-DYpcdzPR.d.ts} +1 -1
  31. package/dist/{workspace-D7nb3-cO.d.cts → workspace-g-1DGOHJ.d.cts} +37 -2
  32. package/dist/{workspace-D7nb3-cO.d.ts → workspace-g-1DGOHJ.d.ts} +37 -2
  33. package/examples/05-asset-management.test.cjs +135 -36
  34. package/examples/08-persistence.test.cjs +6 -6
  35. package/examples/README.md +1 -1
  36. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { c as Address, a5 as SvmTxBuildParams, a4 as SvmTransaction, N as Network, a2 as SvmAddressLookupTable } from './workspace-D7nb3-cO.cjs';
1
+ import { c as Address, a8 as SvmTxBuildParams, a7 as SvmTransaction, N as Network, a5 as SvmAddressLookupTable } from './workspace-g-1DGOHJ.cjs';
2
2
 
3
3
  declare function svmResolveAddressLookupTables(network: Network, addresses: readonly string[]): Promise<SvmAddressLookupTable[]>;
4
4
  interface SvmInstruction {
@@ -1,4 +1,4 @@
1
- import { c as Address, a5 as SvmTxBuildParams, a4 as SvmTransaction, N as Network, a2 as SvmAddressLookupTable } from './workspace-D7nb3-cO.js';
1
+ import { c as Address, a8 as SvmTxBuildParams, a7 as SvmTransaction, N as Network, a5 as SvmAddressLookupTable } from './workspace-g-1DGOHJ.js';
2
2
 
3
3
  declare function svmResolveAddressLookupTables(network: Network, addresses: readonly string[]): Promise<SvmAddressLookupTable[]>;
4
4
  interface SvmInstruction {
@@ -8,6 +8,24 @@ interface AssetInitObject {
8
8
  displayDecimals?: number;
9
9
  displayStatus?: boolean;
10
10
  }
11
+
12
+ interface AssetUpdate {
13
+ symbol?: string;
14
+ name?: string;
15
+ decimals?: number;
16
+ displayDecimals?: number;
17
+ displayStatus?: boolean;
18
+ }
19
+
20
+ interface AssetAddInit {
21
+ network: NetworkLike;
22
+ symbol: string;
23
+ name: string;
24
+ decimals: number;
25
+ contractAddress?: string | null;
26
+ displayDecimals?: number;
27
+ displayStatus?: boolean;
28
+ }
11
29
  declare class Asset {
12
30
  readonly id: AssetId;
13
31
  readonly contractAddress: string | null;
@@ -20,6 +38,8 @@ declare class Asset {
20
38
  readonly network: Network;
21
39
  constructor(init: AssetInitObject);
22
40
  constructor(id: AssetId, symbol: string, name: string, decimals: number, network: Network, contractAddress?: string | null);
41
+
42
+ save(): Promise<Asset>;
23
43
  }
24
44
  interface AssetBalance {
25
45
  readonly assetId: AssetId;
@@ -34,6 +54,13 @@ interface AssetCollection extends ReadonlyArray<Asset> {
34
54
  byId(id: AssetId): Asset | null;
35
55
  }
36
56
 
57
+ interface NetworkAssetCollection extends AssetCollection {
58
+ add(init: Omit<AssetAddInit, "network">): Promise<Asset>;
59
+ update(id: AssetId, patch: AssetUpdate): Promise<Asset>;
60
+ drop(id: AssetId): Promise<void>;
61
+ move(id: AssetId, toIndex: number): Promise<void>;
62
+ }
63
+
37
64
  interface NetworkRoutes {
38
65
 
39
66
  staked?: {
@@ -94,7 +121,7 @@ declare class Network {
94
121
 
95
122
  get symbol(): string;
96
123
 
97
- readonly assets: readonly Asset[];
124
+ get assets(): NetworkAssetCollection;
98
125
 
99
126
  save(): Promise<void>;
100
127
 
@@ -1071,8 +1098,16 @@ declare class Workspace {
1071
1098
 
1072
1099
  assets(network: NetworkLike): Promise<readonly Asset[]>;
1073
1100
 
1101
+ _networkAssets(network: Network): NetworkAssetCollection;
1102
+
1074
1103
  addAsset(asset: Asset): Promise<Asset>;
1075
1104
 
1105
+ addAsset(init: AssetAddInit): Promise<Asset>;
1106
+
1107
+ updateAsset(id: AssetId, patch: AssetUpdate): Promise<Asset>;
1108
+
1109
+ _saveAsset(asset: Asset): Promise<Asset>;
1110
+
1076
1111
  dropAsset(id: AssetId): Promise<void>;
1077
1112
 
1078
1113
  moveAsset(network: NetworkLike, id: AssetId, toIndex: number): Promise<void>;
@@ -1088,4 +1123,4 @@ declare class Workspace {
1088
1123
  }>;
1089
1124
  }
1090
1125
 
1091
- export { type SinkConfig as $, Account as A, type LogSink as B, type ChainId as C, type DecodedTx as D, type EvmAddress as E, Logger as F, type LoggerConfig as G, type NetworkCollection as H, type NetworkInit as I, type NetworkLike as J, type NetworkRoutes as K, type LogLevel as L, type NormalizedTx as M, Network as N, type OpenOptions as O, Provider as P, Record$1 as Q, type RawTx as R, type RecordInit as S, type RecordType as T, type SendOptions as U, type SendRoute as V, type Settling as W, type SignInParams as X, type SignInResult as Y, type SignRawOptions as Z, type SimulationResult as _, type AccountCollection as a, type Slug as a0, type SvmAddress as a1, type SvmAddressLookupTable as a2, SvmSigner as a3, SvmTransaction as a4, type SvmTxBuildParams as a5, type Transaction as a6, type TransactionReceipt as a7, type TransactionStateChange as a8, type TransactionStatus as a9, type TransactionTracker as aa, type TransferPayload as ab, type TransferRequest as ac, type VmToken as ad, Wallet as ae, type WalletCollection as af, WativeError as ag, type WativeErrorCode as ah, type WativeErrorOpts as ai, Workspace as aj, type WorkspaceConfig as ak, deserializeEvmTx as al, deserializeSvmTx as am, deserializeTx as an, isRawTx as ao, newMnemonic as ap, normalizeTxInput as aq, type SuiAddress as ar, type AccountOrgType as b, Address as c, Asset as d, type AssetBalance as e, type AssetCollection as f, type AssetId as g, type AssetInitObject as h, type AssetRef as i, type ChainVM as j, type Commitment as k, ConsoleSink as l, type ContainerState as m, type DestinationCode as n, type DestinationGuardOptions as o, type DestinationReport as p, type DestinationScreenResult as q, type DestinationScreener as r, type DestinationSeverity as s, type DestinationWarning as t, type EvmRawTx as u, EvmSigner as v, EvmTransaction as w, type EvmTxBuildParams as x, EvmTxType as y, type LogRecord as z };
1126
+ export { type SignInResult as $, Account as A, EvmTxType as B, type ChainId as C, type DecodedTx as D, type EvmAddress as E, type LogRecord as F, type LogSink as G, Logger as H, type LoggerConfig as I, type NetworkAssetCollection as J, type NetworkCollection as K, type LogLevel as L, type NetworkInit as M, Network as N, type NetworkLike as O, type NetworkRoutes as P, type NormalizedTx as Q, type OpenOptions as R, Provider as S, type RawTx as T, Record$1 as U, type RecordInit as V, type RecordType as W, type SendOptions as X, type SendRoute as Y, type Settling as Z, type SignInParams as _, type AccountCollection as a, type SignRawOptions as a0, type SimulationResult as a1, type SinkConfig as a2, type Slug as a3, type SvmAddress as a4, type SvmAddressLookupTable as a5, SvmSigner as a6, SvmTransaction as a7, type SvmTxBuildParams as a8, type Transaction as a9, type TransactionReceipt as aa, type TransactionStateChange as ab, type TransactionStatus as ac, type TransactionTracker as ad, type TransferPayload as ae, type TransferRequest as af, type VmToken as ag, Wallet as ah, type WalletCollection as ai, WativeError as aj, type WativeErrorCode as ak, type WativeErrorOpts as al, Workspace as am, type WorkspaceConfig as an, deserializeEvmTx as ao, deserializeSvmTx as ap, deserializeTx as aq, isRawTx as ar, newMnemonic as as, normalizeTxInput as at, type SuiAddress as au, type AccountOrgType as b, Address as c, Asset as d, type AssetAddInit as e, type AssetBalance as f, type AssetCollection as g, type AssetId as h, type AssetInitObject as i, type AssetRef as j, type AssetUpdate as k, type ChainVM as l, type Commitment as m, ConsoleSink as n, type ContainerState as o, type DestinationCode as p, type DestinationGuardOptions as q, type DestinationReport as r, type DestinationScreenResult as s, type DestinationScreener as t, type DestinationSeverity as u, type DestinationWarning as v, type EvmRawTx as w, EvmSigner as x, EvmTransaction as y, type EvmTxBuildParams as z };
@@ -8,6 +8,24 @@ interface AssetInitObject {
8
8
  displayDecimals?: number;
9
9
  displayStatus?: boolean;
10
10
  }
11
+
12
+ interface AssetUpdate {
13
+ symbol?: string;
14
+ name?: string;
15
+ decimals?: number;
16
+ displayDecimals?: number;
17
+ displayStatus?: boolean;
18
+ }
19
+
20
+ interface AssetAddInit {
21
+ network: NetworkLike;
22
+ symbol: string;
23
+ name: string;
24
+ decimals: number;
25
+ contractAddress?: string | null;
26
+ displayDecimals?: number;
27
+ displayStatus?: boolean;
28
+ }
11
29
  declare class Asset {
12
30
  readonly id: AssetId;
13
31
  readonly contractAddress: string | null;
@@ -20,6 +38,8 @@ declare class Asset {
20
38
  readonly network: Network;
21
39
  constructor(init: AssetInitObject);
22
40
  constructor(id: AssetId, symbol: string, name: string, decimals: number, network: Network, contractAddress?: string | null);
41
+
42
+ save(): Promise<Asset>;
23
43
  }
24
44
  interface AssetBalance {
25
45
  readonly assetId: AssetId;
@@ -34,6 +54,13 @@ interface AssetCollection extends ReadonlyArray<Asset> {
34
54
  byId(id: AssetId): Asset | null;
35
55
  }
36
56
 
57
+ interface NetworkAssetCollection extends AssetCollection {
58
+ add(init: Omit<AssetAddInit, "network">): Promise<Asset>;
59
+ update(id: AssetId, patch: AssetUpdate): Promise<Asset>;
60
+ drop(id: AssetId): Promise<void>;
61
+ move(id: AssetId, toIndex: number): Promise<void>;
62
+ }
63
+
37
64
  interface NetworkRoutes {
38
65
 
39
66
  staked?: {
@@ -94,7 +121,7 @@ declare class Network {
94
121
 
95
122
  get symbol(): string;
96
123
 
97
- readonly assets: readonly Asset[];
124
+ get assets(): NetworkAssetCollection;
98
125
 
99
126
  save(): Promise<void>;
100
127
 
@@ -1071,8 +1098,16 @@ declare class Workspace {
1071
1098
 
1072
1099
  assets(network: NetworkLike): Promise<readonly Asset[]>;
1073
1100
 
1101
+ _networkAssets(network: Network): NetworkAssetCollection;
1102
+
1074
1103
  addAsset(asset: Asset): Promise<Asset>;
1075
1104
 
1105
+ addAsset(init: AssetAddInit): Promise<Asset>;
1106
+
1107
+ updateAsset(id: AssetId, patch: AssetUpdate): Promise<Asset>;
1108
+
1109
+ _saveAsset(asset: Asset): Promise<Asset>;
1110
+
1076
1111
  dropAsset(id: AssetId): Promise<void>;
1077
1112
 
1078
1113
  moveAsset(network: NetworkLike, id: AssetId, toIndex: number): Promise<void>;
@@ -1088,4 +1123,4 @@ declare class Workspace {
1088
1123
  }>;
1089
1124
  }
1090
1125
 
1091
- export { type SinkConfig as $, Account as A, type LogSink as B, type ChainId as C, type DecodedTx as D, type EvmAddress as E, Logger as F, type LoggerConfig as G, type NetworkCollection as H, type NetworkInit as I, type NetworkLike as J, type NetworkRoutes as K, type LogLevel as L, type NormalizedTx as M, Network as N, type OpenOptions as O, Provider as P, Record$1 as Q, type RawTx as R, type RecordInit as S, type RecordType as T, type SendOptions as U, type SendRoute as V, type Settling as W, type SignInParams as X, type SignInResult as Y, type SignRawOptions as Z, type SimulationResult as _, type AccountCollection as a, type Slug as a0, type SvmAddress as a1, type SvmAddressLookupTable as a2, SvmSigner as a3, SvmTransaction as a4, type SvmTxBuildParams as a5, type Transaction as a6, type TransactionReceipt as a7, type TransactionStateChange as a8, type TransactionStatus as a9, type TransactionTracker as aa, type TransferPayload as ab, type TransferRequest as ac, type VmToken as ad, Wallet as ae, type WalletCollection as af, WativeError as ag, type WativeErrorCode as ah, type WativeErrorOpts as ai, Workspace as aj, type WorkspaceConfig as ak, deserializeEvmTx as al, deserializeSvmTx as am, deserializeTx as an, isRawTx as ao, newMnemonic as ap, normalizeTxInput as aq, type SuiAddress as ar, type AccountOrgType as b, Address as c, Asset as d, type AssetBalance as e, type AssetCollection as f, type AssetId as g, type AssetInitObject as h, type AssetRef as i, type ChainVM as j, type Commitment as k, ConsoleSink as l, type ContainerState as m, type DestinationCode as n, type DestinationGuardOptions as o, type DestinationReport as p, type DestinationScreenResult as q, type DestinationScreener as r, type DestinationSeverity as s, type DestinationWarning as t, type EvmRawTx as u, EvmSigner as v, EvmTransaction as w, type EvmTxBuildParams as x, EvmTxType as y, type LogRecord as z };
1126
+ export { type SignInResult as $, Account as A, EvmTxType as B, type ChainId as C, type DecodedTx as D, type EvmAddress as E, type LogRecord as F, type LogSink as G, Logger as H, type LoggerConfig as I, type NetworkAssetCollection as J, type NetworkCollection as K, type LogLevel as L, type NetworkInit as M, Network as N, type NetworkLike as O, type NetworkRoutes as P, type NormalizedTx as Q, type OpenOptions as R, Provider as S, type RawTx as T, Record$1 as U, type RecordInit as V, type RecordType as W, type SendOptions as X, type SendRoute as Y, type Settling as Z, type SignInParams as _, type AccountCollection as a, type SignRawOptions as a0, type SimulationResult as a1, type SinkConfig as a2, type Slug as a3, type SvmAddress as a4, type SvmAddressLookupTable as a5, SvmSigner as a6, SvmTransaction as a7, type SvmTxBuildParams as a8, type Transaction as a9, type TransactionReceipt as aa, type TransactionStateChange as ab, type TransactionStatus as ac, type TransactionTracker as ad, type TransferPayload as ae, type TransferRequest as af, type VmToken as ag, Wallet as ah, type WalletCollection as ai, WativeError as aj, type WativeErrorCode as ak, type WativeErrorOpts as al, Workspace as am, type WorkspaceConfig as an, deserializeEvmTx as ao, deserializeSvmTx as ap, deserializeTx as aq, isRawTx as ar, newMnemonic as as, normalizeTxInput as at, type SuiAddress as au, type AccountOrgType as b, Address as c, Asset as d, type AssetAddInit as e, type AssetBalance as f, type AssetCollection as g, type AssetId as h, type AssetInitObject as i, type AssetRef as j, type AssetUpdate as k, type ChainVM as l, type Commitment as m, ConsoleSink as n, type ContainerState as o, type DestinationCode as p, type DestinationGuardOptions as q, type DestinationReport as r, type DestinationScreenResult as s, type DestinationScreener as t, type DestinationSeverity as u, type DestinationWarning as v, type EvmRawTx as w, EvmSigner as x, EvmTransaction as y, type EvmTxBuildParams as z };
@@ -1,4 +1,4 @@
1
- // 05 — Assets: the pre-loaded tokens, adding, dropping, and searching via filter.
1
+ // 05 — Assets: pre-loaded tokens, the live network.assets collection, adding, editing, persisting and dropping tokens, two-tier edits, and filter search.
2
2
 
3
3
  const test = require("node:test");
4
4
  const assert = require("node:assert");
@@ -8,6 +8,10 @@ const { join } = require("node:path");
8
8
 
9
9
  const { Workspace, Network, Asset } = require("wative-core");
10
10
 
11
+ const PEPE_ADDR = "0x6982508145454Ce325dDbE47a25d4ec3d2311933";
12
+ const SHIB_ADDR = "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE";
13
+ const USDC_ADDR = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
14
+
11
15
  test("asset — pre-loaded tokens per network", async () => {
12
16
  const root = mkdtempSync(join(tmpdir(), "wative-asset-builtin-"));
13
17
  const ws = await Workspace.open({ path: root, password: "wsp-pwd" });
@@ -31,73 +35,168 @@ test("asset — pre-loaded tokens per network", async () => {
31
35
  await ws.lock();
32
36
  });
33
37
 
34
- test("asset — add a custom user token", async () => {
38
+ test("asset — add a custom token with addAsset(init); the library allocates the id", async () => {
35
39
  const root = mkdtempSync(join(tmpdir(), "wative-asset-add-"));
36
40
  const ws = await Workspace.open({ path: root, password: "wsp-pwd" });
37
41
 
38
- const pepe = new Asset({
39
- id: 200,
42
+ const pepe = await ws.addAsset({
43
+ network: Network.Ethereum,
40
44
  symbol: "PEPE",
41
45
  name: "Pepe",
42
46
  decimals: 18,
43
- contractAddress: "0x6982508145454Ce325dDbE47a25d4ec3d2311933",
44
- network: Network.Ethereum,
47
+ contractAddress: PEPE_ADDR,
45
48
  });
46
- await ws.addAsset(pepe);
49
+ assert.ok(pepe.id >= 1000);
47
50
 
48
51
  const ethAssets = await ws.assets(Network.Ethereum);
49
52
  assert.strictEqual(ethAssets.length, 5);
50
- assert.ok(ethAssets.some((a) => a.id === 200 && a.symbol === "PEPE"));
53
+ assert.ok(ethAssets.some((a) => a.id === pepe.id && a.symbol === "PEPE"));
51
54
 
52
55
  await ws.lock();
53
56
  });
54
57
 
55
- test("asset — id and address collisions are rejected", async () => {
56
- const root = mkdtempSync(join(tmpdir(), "wative-asset-collide-"));
58
+ test("asset — network.assets is a live collection (add, byId, update, move, drop)", async () => {
59
+ const root = mkdtempSync(join(tmpdir(), "wative-asset-collection-"));
57
60
  const ws = await Workspace.open({ path: root, password: "wsp-pwd" });
58
61
 
59
- const dupId = new Asset({
60
- id: 1,
61
- symbol: "FAKE",
62
- name: "Fake",
62
+ const eth = ws.networks.bySlug("ethereum");
63
+ assert.ok(Array.isArray(eth.assets));
64
+ const before = eth.assets.length;
65
+
66
+ const added = await eth.assets.add({
67
+ symbol: "PEPE",
68
+ name: "Pepe",
63
69
  decimals: 18,
64
- contractAddress: "0x1234567890123456789012345678901234567890",
65
- network: Network.Ethereum,
70
+ contractAddress: PEPE_ADDR,
66
71
  });
67
- await assert.rejects(ws.addAsset(dupId), (err) => err.code === "DUPLICATE_IDENTITY");
68
-
69
- const dupAddr = new Asset({
70
- id: 201,
71
- symbol: "USDC2",
72
- name: "Other USDC",
73
- decimals: 6,
74
- contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
72
+ assert.ok(added.id >= 1000);
73
+ assert.strictEqual(eth.assets.length, before + 1);
74
+ assert.strictEqual(eth.assets.byId(added.id).symbol, "PEPE");
75
+
76
+ await eth.assets.update(added.id, { displayStatus: false });
77
+ assert.strictEqual(eth.assets.byId(added.id).displayStatus, false);
78
+
79
+ await eth.assets.move(added.id, 0);
80
+ assert.strictEqual(eth.assets[0].id, added.id);
81
+
82
+ await eth.assets.drop(added.id);
83
+ assert.strictEqual(eth.assets.byId(added.id), null);
84
+
85
+ await ws.lock();
86
+ });
87
+
88
+ test("asset — asset.save() persists an edit across reopen; a detached asset cannot save", async () => {
89
+ const root = mkdtempSync(join(tmpdir(), "wative-asset-save-"));
90
+ let ws = await Workspace.open({ path: root, password: "wsp-pwd" });
91
+
92
+ const eth = ws.networks.bySlug("ethereum");
93
+ const added = await eth.assets.add({
94
+ symbol: "PEPE",
95
+ name: "Pepe",
96
+ decimals: 18,
97
+ contractAddress: PEPE_ADDR,
98
+ });
99
+
100
+ const held = eth.assets.byId(added.id);
101
+ held.displayStatus = false;
102
+ held.name = "Pepe Token";
103
+ await held.save();
104
+
105
+ await ws.lock();
106
+ ws = await Workspace.open({ path: root, password: "wsp-pwd" });
107
+ const reopened = ws.networks.bySlug("ethereum").assets.byId(added.id);
108
+ assert.strictEqual(reopened.displayStatus, false);
109
+ assert.strictEqual(reopened.name, "Pepe Token");
110
+
111
+ const detached = new Asset({
112
+ id: 5000,
113
+ symbol: "DET",
114
+ name: "Detached",
115
+ decimals: 18,
116
+ contractAddress: SHIB_ADDR,
75
117
  network: Network.Ethereum,
76
118
  });
77
- await assert.rejects(ws.addAsset(dupAddr), (err) => err.code === "DUPLICATE_IDENTITY");
119
+ await assert.rejects(detached.save(), (err) => err.code === "UNSUPPORTED_OP");
78
120
 
79
121
  await ws.lock();
80
122
  });
81
123
 
82
- test("asset — drop user token; pre-loaded tokens reject drop", async () => {
83
- const root = mkdtempSync(join(tmpdir(), "wative-asset-drop-"));
124
+ test("asset — two-tier edits: a user token edits all metadata, a built-in only its display fields", async () => {
125
+ const root = mkdtempSync(join(tmpdir(), "wative-asset-tier-"));
84
126
  const ws = await Workspace.open({ path: root, password: "wsp-pwd" });
85
127
 
86
- const my = new Asset({
87
- id: 300,
128
+ const eth = ws.networks.bySlug("ethereum");
129
+ const mine = await eth.assets.add({
88
130
  symbol: "MINE",
89
131
  name: "Mine",
90
132
  decimals: 18,
91
- contractAddress: "0x1111111111111111111111111111111111111111",
92
- network: Network.Ethereum,
133
+ contractAddress: PEPE_ADDR,
93
134
  });
94
- await ws.addAsset(my);
95
- await ws.dropAsset(300);
96
135
 
97
- const ethAssets = await ws.assets(Network.Ethereum);
98
- assert.ok(!ethAssets.some((a) => a.id === 300));
136
+ const updated = await ws.updateAsset(mine.id, {
137
+ symbol: "MINE2",
138
+ name: "My Token",
139
+ decimals: 8,
140
+ displayDecimals: 8,
141
+ displayStatus: false,
142
+ });
143
+ assert.strictEqual(updated.symbol, "MINE2");
144
+ assert.strictEqual(updated.decimals, 8);
145
+ assert.strictEqual(updated.displayStatus, false);
146
+
147
+ const usdc = eth.assets.find((a) => a.symbol === "USDC");
148
+ const builtinEdited = await ws.updateAsset(usdc.id, { displayStatus: false });
149
+ assert.strictEqual(builtinEdited.displayStatus, false);
150
+ await assert.rejects(ws.updateAsset(usdc.id, { symbol: "USDX" }), (err) => err.code === "PARAMETER_ERROR");
151
+
152
+ await ws.lock();
153
+ });
154
+
155
+ test("asset — a standalone network's assets are a read-only template", async () => {
156
+ const builtins = Network.Ethereum.assets;
157
+ assert.ok(builtins.length >= 4);
158
+ assert.ok(builtins.every((a) => a instanceof Asset));
159
+ assert.ok(builtins.find((a) => a.symbol === "ETH"));
160
+ await assert.rejects(
161
+ Network.Ethereum.assets.add({ symbol: "X", name: "X", decimals: 18, contractAddress: PEPE_ADDR }),
162
+ (err) => err.code === "UNSUPPORTED_OP",
163
+ );
164
+ });
165
+
166
+ test("asset — a duplicate contract address is rejected", async () => {
167
+ const root = mkdtempSync(join(tmpdir(), "wative-asset-collide-"));
168
+ const ws = await Workspace.open({ path: root, password: "wsp-pwd" });
169
+
170
+ await assert.rejects(
171
+ ws.addAsset({
172
+ network: Network.Ethereum,
173
+ symbol: "USDC2",
174
+ name: "Other USDC",
175
+ decimals: 6,
176
+ contractAddress: USDC_ADDR,
177
+ }),
178
+ (err) => err.code === "DUPLICATE_IDENTITY",
179
+ );
180
+
181
+ await ws.lock();
182
+ });
183
+
184
+ test("asset — drop a user token via network.assets; built-in tokens reject drop", async () => {
185
+ const root = mkdtempSync(join(tmpdir(), "wative-asset-drop-"));
186
+ const ws = await Workspace.open({ path: root, password: "wsp-pwd" });
187
+
188
+ const eth = ws.networks.bySlug("ethereum");
189
+ const my = await eth.assets.add({
190
+ symbol: "MINE",
191
+ name: "Mine",
192
+ decimals: 18,
193
+ contractAddress: PEPE_ADDR,
194
+ });
195
+ await eth.assets.drop(my.id);
196
+ assert.strictEqual(eth.assets.byId(my.id), null);
99
197
 
100
- await assert.rejects(ws.dropAsset(1), (err) => err.code === "UNSUPPORTED_OP");
198
+ const ethId = eth.assets.find((a) => a.symbol === "ETH").id;
199
+ await assert.rejects(eth.assets.drop(ethId), (err) => err.code === "UNSUPPORTED_OP");
101
200
 
102
201
  await ws.lock();
103
202
  });
@@ -6,7 +6,7 @@ const { mkdtempSync } = require("node:fs");
6
6
  const { tmpdir } = require("node:os");
7
7
  const { join } = require("node:path");
8
8
 
9
- const { Workspace, Network, Asset } = require("wative-core");
9
+ const { Workspace, Network } = require("wative-core");
10
10
 
11
11
  const MNEMONIC =
12
12
  "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
@@ -70,19 +70,19 @@ test("persistence — custom user asset round-trips", async () => {
70
70
  const root = mkdtempSync(join(tmpdir(), "wative-persist-asset-"));
71
71
  let ws = await Workspace.open({ path: root, password: "wsp-pwd" });
72
72
 
73
- await ws.addAsset(new Asset({
74
- id: 250,
73
+ const added = await ws.addAsset({
74
+ network: Network.Ethereum,
75
75
  symbol: "PEPE",
76
76
  name: "Pepe",
77
77
  decimals: 18,
78
78
  contractAddress: "0x6982508145454Ce325dDbE47a25d4ec3d2311933",
79
- network: Network.Ethereum,
80
- }));
79
+ });
80
+ const id = added.id;
81
81
 
82
82
  await ws.lock();
83
83
  ws = await Workspace.open({ path: root, password: "wsp-pwd" });
84
84
  const ethAssets = await ws.assets(Network.Ethereum);
85
- const pepe = ethAssets.find((a) => a.id === 250);
85
+ const pepe = ethAssets.find((a) => a.id === id);
86
86
  assert.ok(pepe);
87
87
  assert.strictEqual(pepe.symbol, "PEPE");
88
88
  assert.strictEqual(pepe.decimals, 18);
@@ -35,7 +35,7 @@ All tests work fully offline — no RPC calls, no real networks. Each test creat
35
35
  | [02-hd-account.test.cjs](02-hd-account.test.cjs) | HD-specific flows — deriving / slicing wallets, dumping the mnemonic, account-level passwords with `resetPassword`, round-trip across lock + reopen. |
36
36
  | [03-pk-account.test.cjs](03-pk-account.test.cjs) | PK accounts — creating from a private key, importing more keys, and the three key formats accepted (EVM hex, Solana base58, `solana-keygen` JSON) with the chain inferred from the key. Also shows each import producing an address on both chains, duplicate-import rejection, and dropping wallets. |
37
37
  | [04-network-management.test.cjs](04-network-management.test.cjs) | The 15 pre-loaded networks, adding a brand-new network, overriding a pre-loaded RPC URL via `update()`, dropping user networks, the built-in protection guard. |
38
- | [05-asset-management.test.cjs](05-asset-management.test.cjs) | The 32 pre-loaded tokens, adding a custom user token, id collision rejection, contract-address collision rejection, dropping user tokens, `workspace.filter(q, "Asset")` search. |
38
+ | [05-asset-management.test.cjs](05-asset-management.test.cjs) | The 32 pre-loaded tokens, the live `network.assets` collection (add / byId / update / move / drop), adding a token with `addAsset(init)` (library-allocated id), editing and persisting with `asset.save()` and `workspace.updateAsset`, the built-in vs user two-tier edit rule, a standalone network's read-only assets, contract-address collision rejection, and `workspace.filter(q, "Asset")` search. |
39
39
  | [06-address-signing.test.cjs](06-address-signing.test.cjs) | Personal-message signing on EVM and Solana, building a transaction fully offline (no RPC). |
40
40
  | [07-custom-provider.test.cjs](07-custom-provider.test.cjs) | Taking over the record layer as well, by extending `Provider` rather than `ContainerProvider` — for storage that has its own encryption or its own idea of a record. Longer than [19](19-simple-provider.test.cjs); start there unless you need this. |
41
41
  | [08-persistence.test.cjs](08-persistence.test.cjs) | Round-trip across `lock()` + reopen — multiple accounts, user networks, custom assets, and logger configuration. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wative-core",
3
- "version": "2.5.6",
3
+ "version": "2.5.7",
4
4
  "description": "Hyperscale crypto wallet management library — multi-workspace, multi-chain, originally designed for on-chain market makers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.node.cjs",