@kynesyslabs/demosdk 4.0.13 → 4.0.15

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 (71) hide show
  1. package/build/abstraction/Identities.d.ts +65 -21
  2. package/build/abstraction/Identities.js +51 -50
  3. package/build/abstraction/Identities.js.map +1 -1
  4. package/build/bridge/nativeBridge.d.ts +3 -1
  5. package/build/bridge/nativeBridge.js +4 -3
  6. package/build/bridge/nativeBridge.js.map +1 -1
  7. package/build/contracts/ContractDeployer.js +5 -2
  8. package/build/contracts/ContractDeployer.js.map +1 -1
  9. package/build/contracts/ContractInteractor.js +4 -1
  10. package/build/contracts/ContractInteractor.js.map +1 -1
  11. package/build/d402/client/D402Client.d.ts +3 -1
  12. package/build/d402/client/D402Client.js +4 -3
  13. package/build/d402/client/D402Client.js.map +1 -1
  14. package/build/escrow/EscrowTransaction.d.ts +7 -2
  15. package/build/escrow/EscrowTransaction.js +9 -8
  16. package/build/escrow/EscrowTransaction.js.map +1 -1
  17. package/build/l2ps/anchor/anchor.d.ts +1 -0
  18. package/build/l2ps/anchor/anchor.js +4 -3
  19. package/build/l2ps/anchor/anchor.js.map +1 -1
  20. package/build/l2ps/binding/binding.d.ts +3 -1
  21. package/build/l2ps/binding/binding.js +3 -2
  22. package/build/l2ps/binding/binding.js.map +1 -1
  23. package/build/tlsnotary/TLSNotaryService.d.ts +2 -0
  24. package/build/tlsnotary/TLSNotaryService.js +11 -10
  25. package/build/tlsnotary/TLSNotaryService.js.map +1 -1
  26. package/build/types/blockchain/GCREdit.d.ts +0 -30
  27. package/build/types/blockchain/Transaction.d.ts +7 -0
  28. package/build/types/blockchain/Transaction.js.map +1 -1
  29. package/build/types/blockchain/rawTransaction.d.ts +2 -7
  30. package/build/types/web2/index.d.ts +1 -0
  31. package/build/utils/index.d.ts +2 -0
  32. package/build/utils/index.js +18 -0
  33. package/build/utils/index.js.map +1 -1
  34. package/build/websdk/DemosTokens.d.ts +42 -14
  35. package/build/websdk/DemosTokens.js +35 -30
  36. package/build/websdk/DemosTokens.js.map +1 -1
  37. package/build/websdk/DemosTransactions.d.ts +27 -9
  38. package/build/websdk/DemosTransactions.js +27 -26
  39. package/build/websdk/DemosTransactions.js.map +1 -1
  40. package/build/websdk/NonceManager.d.ts +56 -0
  41. package/build/websdk/NonceManager.js +87 -0
  42. package/build/websdk/NonceManager.js.map +1 -0
  43. package/build/websdk/Web2Calls.js +4 -2
  44. package/build/websdk/Web2Calls.js.map +1 -1
  45. package/build/websdk/demosclass.d.ts +145 -32
  46. package/build/websdk/demosclass.js +83 -10
  47. package/build/websdk/demosclass.js.map +1 -1
  48. package/build/websdk/programmatic/attest.js +40 -20
  49. package/build/websdk/programmatic/attest.js.map +1 -1
  50. package/build/websdk/programmatic/bridge.js +1 -1
  51. package/build/websdk/programmatic/bridge.js.map +1 -1
  52. package/build/websdk/programmatic/d402.js +1 -1
  53. package/build/websdk/programmatic/d402.js.map +1 -1
  54. package/build/websdk/programmatic/escrow.js +3 -3
  55. package/build/websdk/programmatic/escrow.js.map +1 -1
  56. package/build/websdk/programmatic/governance.js +6 -2
  57. package/build/websdk/programmatic/governance.js.map +1 -1
  58. package/build/websdk/programmatic/ipfs.js +10 -7
  59. package/build/websdk/programmatic/ipfs.js.map +1 -1
  60. package/build/websdk/programmatic/pay.js +2 -2
  61. package/build/websdk/programmatic/pay.js.map +1 -1
  62. package/build/websdk/programmatic/runner.js +5 -3
  63. package/build/websdk/programmatic/runner.js.map +1 -1
  64. package/build/websdk/programmatic/storage.js +4 -2
  65. package/build/websdk/programmatic/storage.js.map +1 -1
  66. package/build/websdk/programmatic/tokens.js +27 -13
  67. package/build/websdk/programmatic/tokens.js.map +1 -1
  68. package/build/websdk/programmatic/types.d.ts +1 -0
  69. package/build/websdk/programmatic/validator.js +7 -3
  70. package/build/websdk/programmatic/validator.js.map +1 -1
  71. package/package.json +2 -1
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Per-address nonce sequencer for a single Demos client.
3
+ *
4
+ * The node reports an address's nonce lagging inclusion: `getAddressNonce()`
5
+ * returns the last confirmed nonce, not counting transactions already
6
+ * broadcast but not yet included. So two sends fired back-to-back both read
7
+ * the same on-chain value, compute the same nonce, and collide — the node
8
+ * rejects the second one. That is the batch-failure mode apps hit when
9
+ * sending several transactions from the same address at once.
10
+ *
11
+ * NonceManager fixes this on the client: it keeps a local "next nonce" per
12
+ * address, seeded once from the node, then hands out strictly increasing
13
+ * nonces without re-reading the lagging chain value between sends.
14
+ * Reservations are serialized per address so concurrent callers never share
15
+ * a nonce.
16
+ *
17
+ * Boundary: this only sequences sends from THIS client. If the same key
18
+ * signs from another client/device concurrently, the local counter drifts
19
+ * from the chain — call {@link reset} to reseed from the node. Likewise, a
20
+ * reserved nonce is consumed at build time; if that transaction never lands
21
+ * the counter runs ahead of the chain, so callers should {@link reset} the
22
+ * address after a nonce-rejection so the next reservation reseeds.
23
+ */
24
+ export declare class NonceManager {
25
+ /** Next nonce to hand out per address (absent = not yet seeded). */
26
+ private readonly next;
27
+ /** Per-address serialization tail so concurrent reservations don't race. */
28
+ private readonly tail;
29
+ /**
30
+ * Reserve the next nonce for `address`, serialized against other
31
+ * reservations for the same address. Seeds from `fetchNext` on first use
32
+ * (or after {@link reset}); `fetchNext` must resolve the first usable nonce
33
+ * for the address — the confirmed on-chain nonce plus one
34
+ * (`Demos.getAddressNonce(address) + 1`). Subsequent reservations increment
35
+ * locally, which is what keeps concurrent sends from colliding.
36
+ */
37
+ reserve(address: string, fetchNext: () => Promise<number>): Promise<number>;
38
+ /**
39
+ * Drop local state for `address` so the next {@link reserve} reseeds from
40
+ * the node. Call after a broadcast fails with a nonce error, or when
41
+ * another client may have sent from the same address.
42
+ */
43
+ reset(address: string): void;
44
+ /** Drop local state for every address. */
45
+ resetAll(): void;
46
+ /**
47
+ * Force the next nonce for `address` (advanced use / recovery). The next
48
+ * {@link reserve} returns exactly `nextNonce`.
49
+ */
50
+ seed(address: string, nextNonce: number): void;
51
+ /**
52
+ * The nonce the next {@link reserve} would hand out for `address`, or
53
+ * `undefined` if the address has not been seeded yet.
54
+ */
55
+ peek(address: string): number | undefined;
56
+ }
@@ -0,0 +1,87 @@
1
+ import { assertValidNonce } from "../utils/index.js";
2
+ /**
3
+ * Per-address nonce sequencer for a single Demos client.
4
+ *
5
+ * The node reports an address's nonce lagging inclusion: `getAddressNonce()`
6
+ * returns the last confirmed nonce, not counting transactions already
7
+ * broadcast but not yet included. So two sends fired back-to-back both read
8
+ * the same on-chain value, compute the same nonce, and collide — the node
9
+ * rejects the second one. That is the batch-failure mode apps hit when
10
+ * sending several transactions from the same address at once.
11
+ *
12
+ * NonceManager fixes this on the client: it keeps a local "next nonce" per
13
+ * address, seeded once from the node, then hands out strictly increasing
14
+ * nonces without re-reading the lagging chain value between sends.
15
+ * Reservations are serialized per address so concurrent callers never share
16
+ * a nonce.
17
+ *
18
+ * Boundary: this only sequences sends from THIS client. If the same key
19
+ * signs from another client/device concurrently, the local counter drifts
20
+ * from the chain — call {@link reset} to reseed from the node. Likewise, a
21
+ * reserved nonce is consumed at build time; if that transaction never lands
22
+ * the counter runs ahead of the chain, so callers should {@link reset} the
23
+ * address after a nonce-rejection so the next reservation reseeds.
24
+ */
25
+ export class NonceManager {
26
+ constructor() {
27
+ /** Next nonce to hand out per address (absent = not yet seeded). */
28
+ this.next = new Map();
29
+ /** Per-address serialization tail so concurrent reservations don't race. */
30
+ this.tail = new Map();
31
+ }
32
+ /**
33
+ * Reserve the next nonce for `address`, serialized against other
34
+ * reservations for the same address. Seeds from `fetchNext` on first use
35
+ * (or after {@link reset}); `fetchNext` must resolve the first usable nonce
36
+ * for the address — the confirmed on-chain nonce plus one
37
+ * (`Demos.getAddressNonce(address) + 1`). Subsequent reservations increment
38
+ * locally, which is what keeps concurrent sends from colliding.
39
+ */
40
+ async reserve(address, fetchNext) {
41
+ const prior = this.tail.get(address) ?? Promise.resolve();
42
+ const run = prior.then(async () => {
43
+ let n = this.next.get(address);
44
+ if (n === undefined) {
45
+ // Seed once. `fetchNext` already returns the next nonce to
46
+ // use; subsequent reservations increment locally so rapid
47
+ // sends don't re-read the lagging confirmed nonce.
48
+ n = await fetchNext();
49
+ }
50
+ this.next.set(address, n + 1);
51
+ return n;
52
+ });
53
+ // Swallow the tail's outcome so one rejected reservation (e.g. a
54
+ // transient getAddressNonce failure during seeding) does not poison
55
+ // every later reservation for this address. The real error still
56
+ // surfaces to this caller via `run`.
57
+ this.tail.set(address, run.then(() => undefined, () => undefined));
58
+ return run;
59
+ }
60
+ /**
61
+ * Drop local state for `address` so the next {@link reserve} reseeds from
62
+ * the node. Call after a broadcast fails with a nonce error, or when
63
+ * another client may have sent from the same address.
64
+ */
65
+ reset(address) {
66
+ this.next.delete(address);
67
+ }
68
+ /** Drop local state for every address. */
69
+ resetAll() {
70
+ this.next.clear();
71
+ }
72
+ /**
73
+ * Force the next nonce for `address` (advanced use / recovery). The next
74
+ * {@link reserve} returns exactly `nextNonce`.
75
+ */
76
+ seed(address, nextNonce) {
77
+ this.next.set(address, assertValidNonce(nextNonce));
78
+ }
79
+ /**
80
+ * The nonce the next {@link reserve} would hand out for `address`, or
81
+ * `undefined` if the address has not been seeded yet.
82
+ */
83
+ peek(address) {
84
+ return this.next.get(address);
85
+ }
86
+ }
87
+ //# sourceMappingURL=NonceManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NonceManager.js","sourceRoot":"","sources":["../../../src/websdk/NonceManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE1C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,YAAY;IAAzB;QACI,oEAAoE;QACnD,SAAI,GAAG,IAAI,GAAG,EAAkB,CAAA;QACjD,4EAA4E;QAC3D,SAAI,GAAG,IAAI,GAAG,EAA4B,CAAA;IAqE/D,CAAC;IAnEG;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,CACT,OAAe,EACf,SAAgC;QAEhC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;QACzD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAC9B,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC9B,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBAClB,2DAA2D;gBAC3D,0DAA0D;gBAC1D,mDAAmD;gBACnD,CAAC,GAAG,MAAM,SAAS,EAAE,CAAA;YACzB,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7B,OAAO,CAAC,CAAA;QACZ,CAAC,CAAC,CAAA;QACF,iEAAiE;QACjE,oEAAoE;QACpE,iEAAiE;QACjE,qCAAqC;QACrC,IAAI,CAAC,IAAI,CAAC,GAAG,CACT,OAAO,EACP,GAAG,CAAC,IAAI,CACJ,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAClB,CACJ,CAAA;QACD,OAAO,GAAG,CAAA;IACd,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAe;QACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC7B,CAAC;IAED,0CAA0C;IAC1C,QAAQ;QACJ,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,OAAe,EAAE,SAAiB;QACnC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAA;IACvD,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,OAAe;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC;CACJ"}
@@ -2,6 +2,7 @@ import { EnumWeb2Actions } from "../types/index.js";
2
2
  import { web2_request } from "./utils/skeletons.js";
3
3
  import { DemosTransactions } from "./DemosTransactions.js";
4
4
  import { canonicalJSONStringify, validatePureJson, looksLikeJsonString, } from "./utils/canonicalJson.js";
5
+ import { resolveNonce } from "../utils/index.js";
5
6
  class Web2InvalidUrlError extends Error {
6
7
  constructor(message, code) {
7
8
  super(message);
@@ -134,8 +135,9 @@ export class Web2Proxy {
134
135
  web2Tx.content.type = "web2Request";
135
136
  web2Tx.content.data = ["web2Request", web2Payload];
136
137
  web2Tx.content.timestamp = Date.now();
137
- const nonce = await this._demos.getAddressNonce(await this._demos.getEd25519Address());
138
- web2Tx.content.nonce = nonce + 1;
138
+ const fromAddress = await this._demos.getEd25519Address();
139
+ const nonce = await resolveNonce(options?.nonce, () => this._demos.getAddressNonce(fromAddress), this._demos._nonceReserver(fromAddress));
140
+ web2Tx.content.nonce = nonce;
139
141
  const signedWeb2Tx = await this._demos.sign(web2Tx);
140
142
  const validityData = await this._demos.confirm(signedWeb2Tx);
141
143
  const txHash = validityData.response.data.transaction.hash;
@@ -1 +1 @@
1
- {"version":3,"file":"Web2Calls.js","sourceRoot":"","sources":["../../../src/websdk/Web2Calls.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Web2Calls.js","sourceRoot":"","sources":["../../../src/websdk/Web2Calls.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,14 @@ export declare class Demos {
42
42
  * still see the warning exactly once per instance lifetime.
43
43
  */
44
44
  private static readonly _NETWORK_INFO_FAILURE_TTL_MS;
45
+ /**
46
+ * Client-side nonce sequencer. Opt-in via {@link enableAutoNonce}. When
47
+ * enabled, transaction builders reserve nonces from this manager instead
48
+ * of re-reading the lagging chain nonce, so batched sends from the same
49
+ * address don't collide. See {@link NonceManager}.
50
+ */
51
+ private readonly _nonceManager;
52
+ private _autoNonce;
45
53
  /** Connection status of the RPC URL */
46
54
  connected: boolean;
47
55
  dual_sign: boolean;
@@ -178,7 +186,9 @@ export declare class Demos {
178
186
  * @param amount - DEM `number` (legacy) or OS `bigint` (preferred).
179
187
  * @returns The signed transaction.
180
188
  */
181
- pay(to: string, amount: number | bigint): Promise<Transaction>;
189
+ pay(to: string, amount: number | bigint, options?: {
190
+ nonce?: number;
191
+ }): Promise<Transaction>;
182
192
  /**
183
193
  * Create a signed DEMOS transaction to send native tokens to a given address.
184
194
  *
@@ -196,7 +206,9 @@ export declare class Demos {
196
206
  * @param amount - DEM `number` (legacy) or OS `bigint` (preferred).
197
207
  * @returns The signed transaction.
198
208
  */
199
- transfer(to: string, amount: number | bigint): Promise<Transaction>;
209
+ transfer(to: string, amount: number | bigint, options?: {
210
+ nonce?: number;
211
+ }): Promise<Transaction>;
200
212
  /**
201
213
  * Create a signed DEMOS transaction to store binary data on the blockchain.
202
214
  * Data is stored in the sender's account.
@@ -205,7 +217,9 @@ export declare class Demos {
205
217
  *
206
218
  * @returns The signed storage transaction.
207
219
  */
208
- store(bytes: Uint8Array): Promise<Transaction>;
220
+ store(bytes: Uint8Array, options?: {
221
+ nonce?: number;
222
+ }): Promise<Transaction>;
209
223
  storagePrograms: {
210
224
  /**
211
225
  * Creates and signs a storage program transaction given a payload.
@@ -214,7 +228,9 @@ export declare class Demos {
214
228
  * @returns The signed transaction
215
229
  *
216
230
  */
217
- sign: (payload: StorageProgramPayload) => Promise<Transaction>;
231
+ sign: (payload: StorageProgramPayload, options?: {
232
+ nonce?: number;
233
+ }) => Promise<Transaction>;
218
234
  /**
219
235
  * Reads a storage program by address.
220
236
  *
@@ -267,7 +283,9 @@ export declare class Demos {
267
283
  * @param options - The dual-signing options
268
284
  * @returns The signed transaction
269
285
  */
270
- sign(raw_tx: Transaction): Promise<Transaction>;
286
+ sign(raw_tx: Transaction, options?: {
287
+ nonce?: number;
288
+ }): Promise<Transaction>;
271
289
  /**
272
290
  * Signs a message.
273
291
  *
@@ -455,6 +473,47 @@ export declare class Demos {
455
473
  * @param address - The address
456
474
  */
457
475
  getAddressNonce(address: string): Promise<number>;
476
+ /**
477
+ * Enable client-side nonce sequencing for this instance.
478
+ *
479
+ * Once enabled, every transaction builder reserves its nonce from a local
480
+ * per-address counter (seeded once from the node) instead of re-reading
481
+ * `getAddressNonce` for each send. This prevents the collisions that make
482
+ * batched sends from the same address fail — the node rejects two txs
483
+ * that reuse a nonce because `getAddressNonce` lags inclusion.
484
+ *
485
+ * Opt-in for now. Passing an explicit `options.nonce` still overrides the
486
+ * manager. If a send is rejected for a nonce error, call
487
+ * {@link resetNonce} so the next send reseeds from the chain.
488
+ */
489
+ enableAutoNonce(): void;
490
+ /** Disable client-side nonce sequencing and clear its local state. */
491
+ disableAutoNonce(): void;
492
+ /** Whether client-side nonce sequencing is enabled for this instance. */
493
+ get autoNonceEnabled(): boolean;
494
+ /**
495
+ * Reseed the local nonce counter for `address` (or every address) from the
496
+ * node on the next send. Call after a nonce-rejection, or when the same
497
+ * key may have sent from another client.
498
+ */
499
+ resetNonce(address?: string): void;
500
+ /**
501
+ * Reserver passed to `resolveNonce` by the transaction builders. Returns a
502
+ * function that sequences the nonce for `address` when auto-nonce is on,
503
+ * or `undefined` so `resolveNonce` keeps its historical per-send read.
504
+ *
505
+ * Seeds once from the confirmed on-chain nonce (`getAddressNonce() + 1`),
506
+ * then increments locally per send. Seeding from the confirmed nonce (not a
507
+ * mempool-aware value) is deliberate: the node accepts any nonce greater
508
+ * than the confirmed one, and the confirmed nonce is consistent across
509
+ * every RPC — whereas a per-RPC mempool count is not. The local counter is
510
+ * what keeps a batch's nonces distinct (`N+1, N+2, …`) so they don't
511
+ * collide; re-reading `getAddressNonce` for each send would not, because it
512
+ * lags inclusion.
513
+ *
514
+ * @internal
515
+ */
516
+ _nonceReserver(address: string): (() => Promise<number>) | undefined;
458
517
  /**
459
518
  * Get a validator's current record (stake, status, unstake timestamps).
460
519
  * Returns null if the address is not (and never was) a validator.
@@ -664,9 +723,13 @@ export declare class Demos {
664
723
  sign: (raw_tx: Transaction) => Promise<Transaction>;
665
724
  empty: () => Transaction;
666
725
  prepare: (data?: any) => Promise<Transaction>;
667
- pay(to: string, amount: number | bigint, demos: Demos): Promise<Transaction>;
726
+ pay(to: string, amount: number | bigint, demos: Demos, options?: {
727
+ nonce?: number;
728
+ }): Promise<Transaction>;
668
729
  _demNumberToOsBigint(amountDem: number): bigint;
669
- transfer(to: string, amount: number | bigint, demos: Demos): Promise<Transaction>;
730
+ transfer(to: string, amount: number | bigint, demos: Demos, options?: {
731
+ nonce?: number;
732
+ }): Promise<Transaction>;
670
733
  signWithAlgorithm: (data: string, keypair: IKeyPair, options: {
671
734
  algorithm: SigningAlgorithm;
672
735
  }) => Promise<{
@@ -686,18 +749,32 @@ export declare class Demos {
686
749
  blockNumber?: number;
687
750
  };
688
751
  }>;
689
- store(bytes: Uint8Array, demos: Demos): Promise<Transaction>;
690
- createL2PSHashUpdate(l2psUid: string, consolidatedHash: string, transactionCount: number, demos: Demos): Promise<Transaction>;
691
- stake(amount: string, connectionUrl: string, demos: Demos): Promise<Transaction>;
692
- unstake(demos: Demos): Promise<Transaction>;
693
- validatorExit(demos: Demos): Promise<Transaction>;
752
+ store(bytes: Uint8Array, demos: Demos, options?: {
753
+ nonce?: number;
754
+ }): Promise<Transaction>;
755
+ createL2PSHashUpdate(l2psUid: string, consolidatedHash: string, transactionCount: number, demos: Demos, options?: {
756
+ nonce?: number;
757
+ }): Promise<Transaction>;
758
+ stake(amount: string, connectionUrl: string, demos: Demos, options?: {
759
+ nonce?: number;
760
+ }): Promise<Transaction>;
761
+ unstake(demos: Demos, options?: {
762
+ nonce?: number;
763
+ }): Promise<Transaction>;
764
+ validatorExit(demos: Demos, options?: {
765
+ nonce?: number;
766
+ }): Promise<Transaction>;
694
767
  proposeNetworkUpgrade(params: {
695
768
  proposalId: string;
696
769
  proposedParameters: Partial<NetworkParameters>;
697
770
  rationale: string;
698
771
  effectiveAtBlock: number;
699
- }, demos: Demos): Promise<Transaction>;
700
- voteOnUpgrade(proposalId: string, approve: boolean, demos: Demos): Promise<Transaction>;
772
+ }, demos: Demos, options?: {
773
+ nonce?: number;
774
+ }): Promise<Transaction>;
775
+ voteOnUpgrade(proposalId: string, approve: boolean, demos: Demos, options?: {
776
+ nonce?: number;
777
+ }): Promise<Transaction>;
701
778
  };
702
779
  private _run?;
703
780
  /**
@@ -737,9 +814,13 @@ export declare class Demos {
737
814
  DemosTransactions: {
738
815
  empty: () => Transaction;
739
816
  prepare: (data?: any) => Promise<Transaction>;
740
- pay(to: string, amount: number | bigint, demos: Demos): Promise<Transaction>;
817
+ pay(to: string, amount: number | bigint, demos: Demos, options?: {
818
+ nonce?: number;
819
+ }): Promise<Transaction>;
741
820
  _demNumberToOsBigint(amountDem: number): bigint;
742
- transfer(to: string, amount: number | bigint, demos: Demos): Promise<Transaction>;
821
+ transfer(to: string, amount: number | bigint, demos: Demos, options?: {
822
+ nonce?: number;
823
+ }): Promise<Transaction>;
743
824
  sign: (raw_tx: Transaction, keypair: IKeyPair, options: {
744
825
  algorithm: SigningAlgorithm;
745
826
  }) => Promise<Transaction>;
@@ -762,25 +843,43 @@ export declare class Demos {
762
843
  blockNumber?: number;
763
844
  };
764
845
  }>;
765
- store(bytes: Uint8Array, demos: Demos): Promise<Transaction>;
766
- createL2PSHashUpdate(l2psUid: string, consolidatedHash: string, transactionCount: number, demos: Demos): Promise<Transaction>;
767
- stake(amount: string, connectionUrl: string, demos: Demos): Promise<Transaction>;
768
- unstake(demos: Demos): Promise<Transaction>;
769
- validatorExit(demos: Demos): Promise<Transaction>;
846
+ store(bytes: Uint8Array, demos: Demos, options?: {
847
+ nonce?: number;
848
+ }): Promise<Transaction>;
849
+ createL2PSHashUpdate(l2psUid: string, consolidatedHash: string, transactionCount: number, demos: Demos, options?: {
850
+ nonce?: number;
851
+ }): Promise<Transaction>;
852
+ stake(amount: string, connectionUrl: string, demos: Demos, options?: {
853
+ nonce?: number;
854
+ }): Promise<Transaction>;
855
+ unstake(demos: Demos, options?: {
856
+ nonce?: number;
857
+ }): Promise<Transaction>;
858
+ validatorExit(demos: Demos, options?: {
859
+ nonce?: number;
860
+ }): Promise<Transaction>;
770
861
  proposeNetworkUpgrade(params: {
771
862
  proposalId: string;
772
863
  proposedParameters: Partial<NetworkParameters>;
773
864
  rationale: string;
774
865
  effectiveAtBlock: number;
775
- }, demos: Demos): Promise<Transaction>;
776
- voteOnUpgrade(proposalId: string, approve: boolean, demos: Demos): Promise<Transaction>;
866
+ }, demos: Demos, options?: {
867
+ nonce?: number;
868
+ }): Promise<Transaction>;
869
+ voteOnUpgrade(proposalId: string, approve: boolean, demos: Demos, options?: {
870
+ nonce?: number;
871
+ }): Promise<Transaction>;
777
872
  };
778
873
  transactions: {
779
874
  empty: () => Transaction;
780
875
  prepare: (data?: any) => Promise<Transaction>;
781
- pay(to: string, amount: number | bigint, demos: Demos): Promise<Transaction>;
876
+ pay(to: string, amount: number | bigint, demos: Demos, options?: {
877
+ nonce?: number;
878
+ }): Promise<Transaction>;
782
879
  _demNumberToOsBigint(amountDem: number): bigint;
783
- transfer(to: string, amount: number | bigint, demos: Demos): Promise<Transaction>;
880
+ transfer(to: string, amount: number | bigint, demos: Demos, options?: {
881
+ nonce?: number;
882
+ }): Promise<Transaction>;
784
883
  sign: (raw_tx: Transaction, keypair: IKeyPair, options: {
785
884
  algorithm: SigningAlgorithm;
786
885
  }) => Promise<Transaction>;
@@ -803,18 +902,32 @@ export declare class Demos {
803
902
  blockNumber?: number;
804
903
  };
805
904
  }>;
806
- store(bytes: Uint8Array, demos: Demos): Promise<Transaction>;
807
- createL2PSHashUpdate(l2psUid: string, consolidatedHash: string, transactionCount: number, demos: Demos): Promise<Transaction>;
808
- stake(amount: string, connectionUrl: string, demos: Demos): Promise<Transaction>;
809
- unstake(demos: Demos): Promise<Transaction>;
810
- validatorExit(demos: Demos): Promise<Transaction>;
905
+ store(bytes: Uint8Array, demos: Demos, options?: {
906
+ nonce?: number;
907
+ }): Promise<Transaction>;
908
+ createL2PSHashUpdate(l2psUid: string, consolidatedHash: string, transactionCount: number, demos: Demos, options?: {
909
+ nonce?: number;
910
+ }): Promise<Transaction>;
911
+ stake(amount: string, connectionUrl: string, demos: Demos, options?: {
912
+ nonce?: number;
913
+ }): Promise<Transaction>;
914
+ unstake(demos: Demos, options?: {
915
+ nonce?: number;
916
+ }): Promise<Transaction>;
917
+ validatorExit(demos: Demos, options?: {
918
+ nonce?: number;
919
+ }): Promise<Transaction>;
811
920
  proposeNetworkUpgrade(params: {
812
921
  proposalId: string;
813
922
  proposedParameters: Partial<NetworkParameters>;
814
923
  rationale: string;
815
924
  effectiveAtBlock: number;
816
- }, demos: Demos): Promise<Transaction>;
817
- voteOnUpgrade(proposalId: string, approve: boolean, demos: Demos): Promise<Transaction>;
925
+ }, demos: Demos, options?: {
926
+ nonce?: number;
927
+ }): Promise<Transaction>;
928
+ voteOnUpgrade(proposalId: string, approve: boolean, demos: Demos, options?: {
929
+ nonce?: number;
930
+ }): Promise<Transaction>;
818
931
  };
819
932
  DemosWebAuth: typeof DemosWebAuth;
820
933
  skeletons: typeof skeletons;
@@ -8,6 +8,7 @@ import * as skeletons from "./utils/skeletons.js";
8
8
  import { TransportError } from "./TransportError.js";
9
9
  // NOTE Including custom libraries from Demos
10
10
  import { DemosTransactions } from "./DemosTransactions.js";
11
+ import { NonceManager } from "./NonceManager.js";
11
12
  import { DemosWebAuth } from "./DemosWebAuth.js";
12
13
  import { prepareXMPayload } from "./XMTransactions.js";
13
14
  import { _required as required } from "./utils/required.js";
@@ -17,6 +18,7 @@ import { hexToUint8Array, uint8ArrayToHex, UnifiedCrypto, } from "../encryption/
17
18
  import { GCRGeneration } from "./GCRGeneration.js";
18
19
  import { Hashing } from "../encryption/Hashing.js";
19
20
  import { OS_PER_DEM, demToOs, parseOsString } from "../denomination/index.js";
21
+ import { assertValidNonce, resolveNonce } from "../utils/index.js";
20
22
  import { serializeTransactionContent } from "../denomination/serializerGate.js";
21
23
  import { SubDemPrecisionError, } from "../denomination/networkInfo.js";
22
24
  import * as bip39 from "@scure/bip39";
@@ -77,6 +79,14 @@ export class Demos {
77
79
  this._cachedNetworkInfoFailed = false;
78
80
  this._cachedNetworkInfoFailedAt = 0;
79
81
  this._cachedNetworkInfoWarned = false;
82
+ /**
83
+ * Client-side nonce sequencer. Opt-in via {@link enableAutoNonce}. When
84
+ * enabled, transaction builders reserve nonces from this manager instead
85
+ * of re-reading the lagging chain nonce, so batched sends from the same
86
+ * address don't collide. See {@link NonceManager}.
87
+ */
88
+ this._nonceManager = new NonceManager();
89
+ this._autoNonce = false;
80
90
  /** Connection status of the RPC URL */
81
91
  this.connected = false;
82
92
  this.dual_sign = false;
@@ -88,7 +98,7 @@ export class Demos {
88
98
  * @returns The signed transaction
89
99
  *
90
100
  */
91
- sign: async (payload) => {
101
+ sign: async (payload, options) => {
92
102
  required(this.keypair, "Wallet not connected");
93
103
  required(payload.storageAddress, "Storage address Not found in payload");
94
104
  // Sender's nonce must be set on the tx like every other
@@ -100,11 +110,11 @@ export class Demos {
100
110
  // after the first one.
101
111
  const { publicKey } = await this.crypto.getIdentity("ed25519");
102
112
  const publicKeyHex = uint8ArrayToHex(publicKey);
103
- const nonce = await this.getAddressNonce(publicKeyHex);
113
+ const nonce = await resolveNonce(options?.nonce, () => this.getAddressNonce(publicKeyHex), this._nonceReserver(publicKeyHex));
104
114
  const tx = DemosTransactions.empty();
105
115
  tx.content.to = payload.storageAddress;
106
116
  tx.content.type = "storageProgram";
107
- tx.content.nonce = nonce + 1;
117
+ tx.content.nonce = nonce;
108
118
  tx.content.data = ["storageProgram", payload];
109
119
  return await this.sign(tx);
110
120
  },
@@ -436,11 +446,11 @@ export class Demos {
436
446
  * @param amount - DEM `number` (legacy) or OS `bigint` (preferred).
437
447
  * @returns The signed transaction.
438
448
  */
439
- async pay(to, amount) {
449
+ async pay(to, amount, options) {
440
450
  required(this.keypair, "Wallet not connected");
441
451
  const amountOs = typeof amount === "bigint" ? amount : demToOs(amount);
442
452
  await this._assertAmountAcceptableOnTargetNode(amountOs);
443
- return DemosTransactions.pay(to, amountOs, this);
453
+ return DemosTransactions.pay(to, amountOs, this, options);
444
454
  }
445
455
  /**
446
456
  * Create a signed DEMOS transaction to send native tokens to a given address.
@@ -459,8 +469,8 @@ export class Demos {
459
469
  * @param amount - DEM `number` (legacy) or OS `bigint` (preferred).
460
470
  * @returns The signed transaction.
461
471
  */
462
- async transfer(to, amount) {
463
- return this.pay(to, amount);
472
+ async transfer(to, amount, options) {
473
+ return this.pay(to, amount, options);
464
474
  }
465
475
  /**
466
476
  * Create a signed DEMOS transaction to store binary data on the blockchain.
@@ -470,9 +480,9 @@ export class Demos {
470
480
  *
471
481
  * @returns The signed storage transaction.
472
482
  */
473
- store(bytes) {
483
+ store(bytes, options) {
474
484
  required(this.keypair, "Wallet not connected");
475
- return DemosTransactions.store(bytes, this);
485
+ return DemosTransactions.store(bytes, this, options);
476
486
  }
477
487
  /**
478
488
  * Confirms a transaction.
@@ -514,8 +524,11 @@ export class Demos {
514
524
  * @param options - The dual-signing options
515
525
  * @returns The signed transaction
516
526
  */
517
- async sign(raw_tx) {
527
+ async sign(raw_tx, options) {
518
528
  required(this.keypair, "Wallet not connected");
529
+ if (options?.nonce !== undefined) {
530
+ raw_tx.content.nonce = assertValidNonce(options.nonce);
531
+ }
519
532
  if (!raw_tx.content.timestamp || raw_tx.content.timestamp === 0) {
520
533
  raw_tx.content.timestamp = Date.now();
521
534
  }
@@ -1161,6 +1174,66 @@ export class Demos {
1161
1174
  }
1162
1175
  return 0;
1163
1176
  }
1177
+ /**
1178
+ * Enable client-side nonce sequencing for this instance.
1179
+ *
1180
+ * Once enabled, every transaction builder reserves its nonce from a local
1181
+ * per-address counter (seeded once from the node) instead of re-reading
1182
+ * `getAddressNonce` for each send. This prevents the collisions that make
1183
+ * batched sends from the same address fail — the node rejects two txs
1184
+ * that reuse a nonce because `getAddressNonce` lags inclusion.
1185
+ *
1186
+ * Opt-in for now. Passing an explicit `options.nonce` still overrides the
1187
+ * manager. If a send is rejected for a nonce error, call
1188
+ * {@link resetNonce} so the next send reseeds from the chain.
1189
+ */
1190
+ enableAutoNonce() {
1191
+ this._autoNonce = true;
1192
+ }
1193
+ /** Disable client-side nonce sequencing and clear its local state. */
1194
+ disableAutoNonce() {
1195
+ this._autoNonce = false;
1196
+ this._nonceManager.resetAll();
1197
+ }
1198
+ /** Whether client-side nonce sequencing is enabled for this instance. */
1199
+ get autoNonceEnabled() {
1200
+ return this._autoNonce;
1201
+ }
1202
+ /**
1203
+ * Reseed the local nonce counter for `address` (or every address) from the
1204
+ * node on the next send. Call after a nonce-rejection, or when the same
1205
+ * key may have sent from another client.
1206
+ */
1207
+ resetNonce(address) {
1208
+ if (address === undefined) {
1209
+ this._nonceManager.resetAll();
1210
+ }
1211
+ else {
1212
+ this._nonceManager.reset(address);
1213
+ }
1214
+ }
1215
+ /**
1216
+ * Reserver passed to `resolveNonce` by the transaction builders. Returns a
1217
+ * function that sequences the nonce for `address` when auto-nonce is on,
1218
+ * or `undefined` so `resolveNonce` keeps its historical per-send read.
1219
+ *
1220
+ * Seeds once from the confirmed on-chain nonce (`getAddressNonce() + 1`),
1221
+ * then increments locally per send. Seeding from the confirmed nonce (not a
1222
+ * mempool-aware value) is deliberate: the node accepts any nonce greater
1223
+ * than the confirmed one, and the confirmed nonce is consistent across
1224
+ * every RPC — whereas a per-RPC mempool count is not. The local counter is
1225
+ * what keeps a batch's nonces distinct (`N+1, N+2, …`) so they don't
1226
+ * collide; re-reading `getAddressNonce` for each send would not, because it
1227
+ * lags inclusion.
1228
+ *
1229
+ * @internal
1230
+ */
1231
+ _nonceReserver(address) {
1232
+ if (!this._autoNonce) {
1233
+ return undefined;
1234
+ }
1235
+ return () => this._nonceManager.reserve(address, async () => (await this.getAddressNonce(address)) + 1);
1236
+ }
1164
1237
  /**
1165
1238
  * Get a validator's current record (stake, status, unstake timestamps).
1166
1239
  * Returns null if the address is not (and never was) a validator.