@asentum/sdk 0.1.0 → 0.2.0

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/dist/index.d.ts CHANGED
@@ -1,19 +1,68 @@
1
- import { Dilithium3Keypair } from '@asentum/crypto';
1
+ type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
2
+ interface TransportOptions {
3
+ /** fetch implementation. Default: globalThis.fetch. */
4
+ fetch?: FetchLike;
5
+ /** Retries after the first attempt for 429 / 5xx / network errors. Default 3. */
6
+ retries?: number;
7
+ /** Per-request timeout in ms. Default 30,000 (the gateway gives up at 30 s too). */
8
+ requestTimeoutMs?: number;
9
+ /** First backoff delay in ms. Default 500. */
10
+ backoffBaseMs?: number;
11
+ /** Maximum backoff delay in ms. Default 10,000. */
12
+ backoffMaxMs?: number;
13
+ /** Extra headers on every request (for example Authorization for a private RPC). */
14
+ headers?: Record<string, string>;
15
+ }
16
+ interface RequestOptions {
17
+ method?: 'GET' | 'POST';
18
+ body?: unknown;
19
+ signal?: AbortSignal;
20
+ /** Override the transport's retry count for this request. */
21
+ retries?: number;
22
+ /** Retry on 5xx and network errors (default true). Set false for non-idempotent posts. */
23
+ retryOnServerError?: boolean;
24
+ /** Statuses that return their body instead of throwing (for example 404 on /dev/faucet). */
25
+ allowStatus?: number[];
26
+ }
27
+ interface HttpResult<T> {
28
+ status: number;
29
+ body: T;
30
+ headers: Headers;
31
+ }
32
+ declare class Transport {
33
+ readonly baseUrl: string;
34
+ private readonly fetchImpl;
35
+ private readonly retries;
36
+ private readonly timeoutMs;
37
+ private readonly baseMs;
38
+ private readonly maxMs;
39
+ private readonly headers;
40
+ constructor(baseUrl: string, opts?: TransportOptions);
41
+ backoffDelay(attempt: number, retryAfterMs?: number): number;
42
+ request<T>(path: string, opts?: RequestOptions): Promise<HttpResult<T>>;
43
+ }
2
44
 
3
45
  /**
4
- * AsentumClient — read-only interface to an Asentum node's RPC.
46
+ * Response types, matching node 0.8.1.
5
47
  *
6
- * Wraps the node's HTTP endpoints in a typed, Promise-based API.
7
- * No private keys, no signing — just reads. For sending transactions,
8
- * use {@link AsentumWallet} which extends the client with a keypair.
48
+ * Conventions (same as the node): heights, balances, nonces and gas are
49
+ * decimal STRINGS so big values survive JSON; amounts are wei (1 ASE =
50
+ * 10^18 wei); timestamps are Unix milliseconds; hashes are 0x hex.
9
51
  *
10
- * Works in Node.js (20+) and browsers — only depends on `fetch`.
52
+ * Addresses: every address field the SDK returns is ase1, also where the
53
+ * node itself answers with 0x hex (receipts, /participation, /v3/committee,
54
+ * governance proposers, JSON-RPC to/contractAddress). Hashes, raw bytes,
55
+ * and the contents of contract return values and event data are left
56
+ * exactly as the node sent them, so an address inside event data stays
57
+ * 0x hex (use toAse1 on it if you show it).
11
58
  */
12
- interface ChainInfo {
13
- chainId: string;
14
- height: number;
15
- mempoolSize: number;
16
- latestHeader: BlockHeader;
59
+ /** "tip" = newest block on the best chain; "finalized" = can never change. */
60
+ type BlockTag = 'tip' | 'latest' | 'pending' | 'finalized' | 'safe';
61
+ interface Heads {
62
+ /** Finalized height. A block at or below it can never change. */
63
+ finalized: number;
64
+ /** Newest block on the best chain. Usually 2 to 4 blocks ahead of finalized. */
65
+ tip: number;
17
66
  }
18
67
  interface BlockHeader {
19
68
  parentHash: string;
@@ -21,17 +70,23 @@ interface BlockHeader {
21
70
  transactionsRoot: string;
22
71
  receiptsRoot: string;
23
72
  number: string;
73
+ /** Unix time in milliseconds. */
24
74
  timestamp: string;
25
75
  gasLimit: string;
26
76
  gasUsed: string;
27
77
  baseFeePerGas: string;
78
+ /** ase1. */
28
79
  proposer: string;
80
+ lastCommitBitmap?: string;
29
81
  }
30
- interface Block {
31
- header: BlockHeader;
32
- hash?: string;
33
- transactions: Transaction[];
34
- receipts: Receipt[];
82
+ interface ChainInfo {
83
+ chainId: string;
84
+ /** FINALIZED height (not the tip). Use getHeads() for both. */
85
+ height: number;
86
+ /** This node's own mempool size. */
87
+ mempoolSize: number;
88
+ /** Header of the finalized head. There is no block hash in it. */
89
+ latestHeader: BlockHeader;
35
90
  }
36
91
  interface Transaction {
37
92
  kind: 'transfer' | 'deploy' | 'call';
@@ -41,60 +96,252 @@ interface Transaction {
41
96
  maxPriorityFeePerGas: string;
42
97
  maxFeePerGas: string;
43
98
  gasLimit: string;
99
+ /** ase1. A deploy goes to the zero address. */
44
100
  to: string;
45
101
  value: string;
46
102
  dataSize: number;
47
103
  };
104
+ /** Decoded method and args for calls. */
48
105
  call?: {
49
106
  method: string;
50
107
  args: unknown[];
51
108
  };
109
+ publicKeyLength?: number;
110
+ signatureLength?: number;
111
+ /** Key-less (key-once) transactions name their sender instead of carrying the public key. */
112
+ keyless?: boolean;
113
+ /** ase1. Only on key-less transactions. */
114
+ sender?: string;
115
+ }
116
+ interface ReceiptEvent {
117
+ name: string;
118
+ /** The event payload as the contract emitted it (usually an object). Addresses inside stay 0x hex. */
119
+ data: unknown;
52
120
  }
121
+ /**
122
+ * GET /receipts/<hash>. The success flag is `success` (boolean). There is
123
+ * no `status` on this route; `status: "0x1"` belongs to the JSON-RPC receipt.
124
+ */
53
125
  interface Receipt {
54
126
  txHash: string;
55
127
  blockNumber: string;
56
128
  txIndex: number;
129
+ /** ase1 (the node sends 0x hex; the SDK converts). */
57
130
  sender: string;
131
+ /** ase1. For a deploy this is the new contract. */
58
132
  recipient: string;
59
- kind: string;
133
+ kind: 'transfer' | 'deploy' | 'call' | string;
134
+ /** true: ran OK. false: ran and failed (see `error`). */
60
135
  success: boolean;
61
136
  gasUsed: string;
62
- events: Array<{
63
- name: string;
64
- data: unknown;
65
- }>;
137
+ events: ReceiptEvent[];
66
138
  returnValue?: unknown;
139
+ /** Only on a failed transaction: why it failed (for example a revert message). */
140
+ error?: string;
141
+ /**
142
+ * false: in a block on the best chain, not final yet (it can still move
143
+ * to another block, rarely). true: final, never changes. Absent only on
144
+ * receipts nested in block responses (use the block's own flag there).
145
+ */
146
+ finalized?: boolean;
147
+ /** Tip height minus blockNumber, plus 1 (decimal string). */
148
+ confirmations?: string;
149
+ /** Hash of the block it is in. Compare between polls to spot a move. */
150
+ blockHash?: string;
151
+ /** Only while not final: id of the pending block it is in. */
152
+ auraHash?: string;
153
+ }
154
+ interface Block {
155
+ header: BlockHeader;
156
+ /** Not in the node's block JSON; present only when the SDK knows it. */
157
+ hash?: string;
158
+ transactions: Transaction[];
159
+ receipts: Receipt[];
160
+ /** true for a finalized block; false for a pending tip block (only with { tip: true }). */
161
+ finalized?: boolean;
162
+ /** Only on a tip block. */
163
+ confirmations?: string;
164
+ /** Only on a tip block. */
165
+ auraHash?: string;
166
+ }
167
+ interface BlockReceipts {
168
+ blockNumber: string;
169
+ receipts: Receipt[];
170
+ /**
171
+ * Absent when the node does not have the height (above finalized without
172
+ * { tip: true }, or below this node's history). Then `receipts` is empty
173
+ * even if the block was not.
174
+ */
175
+ finalized?: boolean;
176
+ confirmations?: string;
177
+ auraHash?: string;
178
+ /** SDK convenience: false when the node did not have the height (no `finalized` field). */
179
+ available: boolean;
67
180
  }
68
181
  interface Balance {
182
+ /** ase1. */
69
183
  address: string;
184
+ /** Wei, read at the tip. */
70
185
  balance: string;
186
+ /** Account nonce at the tip. */
71
187
  nonce: string;
188
+ /**
189
+ * Next usable nonce: `nonce` plus this sender's transactions queued in
190
+ * this node's mempool. Sign your next transaction with this.
191
+ */
192
+ pendingNonce?: string;
72
193
  }
73
- interface ValidatorInfo {
194
+ interface AccountInfo {
195
+ /** ase1. */
74
196
  address: string;
75
- stake: string;
76
- bondedAt: string;
77
- pubKeySize: number;
197
+ exists: boolean;
198
+ balance?: string;
199
+ nonce?: string;
200
+ /** BLAKE3 of the contract source; all zeros for an account without code. */
201
+ codeHash?: string;
202
+ storageRoot?: string;
203
+ height: string;
204
+ }
205
+ interface PublicKeyStatus {
206
+ /** ase1. */
207
+ address: string;
208
+ /** The chain has this account's public key on record. */
209
+ recorded: boolean;
210
+ keyHash: string | null;
211
+ keylessActive: boolean;
212
+ keylessFromBlock: string | null;
213
+ nextBlock: string;
214
+ /** A key-less (smaller) transaction from this account would be accepted now. */
215
+ canOmitKey: boolean;
78
216
  }
79
217
  interface ViewCallResult {
80
218
  ok: boolean;
81
219
  reason?: string;
220
+ /** Whatever the method returned. Many contracts return a JSON string; BigInts come back as decimal strings. */
82
221
  returnValue?: unknown;
83
222
  gasUsed?: string;
84
- events?: Array<{
85
- name: string;
86
- data: unknown;
87
- }>;
223
+ events?: ReceiptEvent[];
224
+ /** The block whose state was read. */
225
+ blockNumber?: string;
226
+ /** Whether that state is final. */
227
+ finalized?: boolean;
88
228
  }
89
229
  interface TxResult {
230
+ /**
231
+ * true: the node checked the transaction and put it in its mempool. It
232
+ * has NOT run and is NOT in a block yet; it can still fail or be dropped.
233
+ */
90
234
  accepted: boolean;
235
+ /** Why it was rejected (only when accepted is false). */
91
236
  reason?: string;
92
237
  txHash?: string;
93
238
  }
239
+ interface BatchTxResult {
240
+ accepted: number;
241
+ rejected: number;
242
+ total: number;
243
+ /** Same order as the request. Each has the shape of POST /tx. */
244
+ results: TxResult[];
245
+ }
246
+ interface EpochInfo {
247
+ head: string;
248
+ current: string;
249
+ blocksPerEpoch: string;
250
+ entryWindowBlocks: string;
251
+ currentStart: string;
252
+ currentEnds: string;
253
+ currentWindowOpensAt: string;
254
+ nextWindowOpensAt: string;
255
+ }
256
+ type CommitteeState = 'signing' | 'waiting_epoch_entry' | 'dormant' | 'pending_bond' | 'tombstoned';
257
+ interface ValidatorInfo {
258
+ /** ase1. */
259
+ address: string;
260
+ stake: string;
261
+ bondedAt: string;
262
+ status?: string;
263
+ activeAtBlock?: string;
264
+ pubKeySize: number;
265
+ broadcastUrl?: string;
266
+ /**
267
+ * signing means the validator has voted and is not dormant. It does not
268
+ * mean it holds one of this epoch's committee seats (see getCommittee).
269
+ */
270
+ committeeState?: CommitteeState | string;
271
+ consecutiveMisses?: number;
272
+ lastVotedHeight?: string;
273
+ nextCommitteeEntryAt?: string | null;
274
+ }
275
+ interface ValidatorsResponse {
276
+ count: number;
277
+ /** ase1. */
278
+ stakingContract?: string;
279
+ epoch?: EpochInfo;
280
+ validators: ValidatorInfo[];
281
+ }
282
+ interface ParticipationEntry {
283
+ /** ase1 (the node sends 0x hex). */
284
+ address: string;
285
+ stake: string;
286
+ signedBlocks: number;
287
+ participationRatio: number;
288
+ lastSignedBlock: string | null;
289
+ status: 'signing' | 'idle' | 'dormant' | string;
290
+ }
291
+ interface Participation {
292
+ head: string;
293
+ scannedFrom: string;
294
+ lookback: number;
295
+ totalValidators: number;
296
+ signing: number;
297
+ idle: number;
298
+ dormant: number;
299
+ recentWindow: number;
300
+ validators: ParticipationEntry[];
301
+ }
302
+ interface Committee {
303
+ epoch: string;
304
+ /** Whether the committee lottery chose this committee. */
305
+ lottery: boolean;
306
+ /** ase1, in canonical order (the order commit bitmaps use). */
307
+ committee: string[];
308
+ /** ase1. */
309
+ leaderBase: string[];
310
+ }
311
+ interface FinalizedStatus {
312
+ height: string;
313
+ finalized: boolean;
314
+ /** Aura hash of the block finalized at this height (only when finalized). */
315
+ auraHash?: string;
316
+ }
317
+ interface LivenessEntry {
318
+ /** ase1. */
319
+ address: string;
320
+ lastVotedHeight: string | null;
321
+ consecutiveMisses: number;
322
+ baked: boolean;
323
+ }
324
+ interface Liveness {
325
+ head: string;
326
+ livenessWindow: string;
327
+ maxConsecutiveMisses: number;
328
+ /** ase1. The core validators. */
329
+ baked: string[];
330
+ tracked: LivenessEntry[];
331
+ [extra: string]: unknown;
332
+ }
333
+ interface Tombstones {
334
+ count: number;
335
+ /** ase1. */
336
+ slashingContract: string;
337
+ tombstones: unknown[];
338
+ }
94
339
  interface Metadata {
340
+ /** Hex, e.g. "0x58f". */
95
341
  chainId: string;
96
342
  chainName: string;
97
343
  chainIdDecimal: string;
344
+ /** Cached up to 30 s on the gateway, so it lags. */
98
345
  currentBlock: string;
99
346
  nativeCurrency: {
100
347
  name: string;
@@ -103,205 +350,761 @@ interface Metadata {
103
350
  };
104
351
  rpcUrls: string[];
105
352
  blockExplorerUrls: string[];
106
- faucetUrl: string;
353
+ /** Not a public faucet. Test ASE comes from the airdrop dashboard. */
354
+ faucetUrl?: string;
107
355
  }
108
- declare class AsentumClient {
109
- readonly rpcUrl: string;
110
- constructor(rpcUrl: string);
111
- /** Get chain info including the latest block header. */
112
- getChainInfo(): Promise<ChainInfo>;
113
- /** Get the current block height. */
114
- getBlockNumber(): Promise<number>;
115
- /** Get the chain ID as a bigint. */
116
- getChainId(): Promise<bigint>;
117
- /** Get a block by number, including transactions and receipts. */
118
- getBlock(number: number | bigint): Promise<Block | null>;
119
- /** Get the balance and nonce for an address. */
120
- getBalance(address: string): Promise<Balance>;
121
- /** Get the nonce for an address (shorthand for getBalance().nonce). */
122
- getNonce(address: string): Promise<bigint>;
123
- /** Get the receipt for a transaction by hash. */
124
- getReceipt(txHash: string): Promise<Receipt | null>;
125
- /** Get the source code of a deployed contract (hex-encoded). */
126
- getCode(address: string): Promise<string>;
127
- /** Get the source code of a deployed contract as a UTF-8 string. */
128
- getContractSource(address: string): Promise<string | null>;
129
- /** Call a contract view function (read-only, no transaction). */
130
- viewCall(contract: string, method: string, args?: unknown[]): Promise<ViewCallResult>;
131
- /** Get the current active validator set. */
132
- getValidators(): Promise<{
133
- count: number;
134
- validators: ValidatorInfo[];
135
- }>;
136
- /** Get the chain metadata (EIP-3085 shape). */
137
- getMetadata(): Promise<Metadata>;
138
- /** Health check. */
139
- isHealthy(): Promise<boolean>;
140
- /** Readiness check (chain advancing). */
141
- isReady(): Promise<boolean>;
142
- /** Request test ASE from the faucet. */
143
- faucet(to: string, amount?: string): Promise<TxResult>;
144
- /** Submit a raw signed transaction (hex-encoded SSZ bytes). */
145
- submitRawTx(rawTxHex: string): Promise<TxResult>;
146
- /** Send a raw JSON-RPC request. */
147
- jsonRpc<T>(method: string, params?: unknown[]): Promise<T>;
148
- private get;
149
- private post;
356
+ interface ApiInfo {
357
+ name: string;
358
+ /** A fixed placeholder, not the node release. */
359
+ version: string;
360
+ chainId: string;
361
+ height: string;
362
+ /** ase1. */
363
+ faucetAddress?: string;
364
+ }
365
+ interface GovernanceProposal {
366
+ id: number;
367
+ title: string;
368
+ description: string;
369
+ category?: string;
370
+ /** ase1 (the contract stores 0x hex). */
371
+ proposer: string;
372
+ createdAt: string;
373
+ votingEndsAt: string;
374
+ votesFor: string;
375
+ votesAgainst: string;
376
+ totalVoteWeight: string;
377
+ status: string;
378
+ amendmentCount?: number;
379
+ libraryName?: string | null;
380
+ bond?: string;
381
+ bondReturned?: boolean;
382
+ bondForfeited?: boolean;
383
+ version?: number;
384
+ executedAt?: string | null;
385
+ [extra: string]: unknown;
386
+ }
387
+ interface GovernanceProposalDetail {
388
+ proposal: GovernanceProposal;
389
+ amendments: unknown[];
390
+ }
391
+ interface GovernanceLocked {
392
+ /** ase1. */
393
+ address: string;
394
+ /** Wei locked in votes. */
395
+ locked: string;
396
+ }
397
+ interface GovernanceWithdrawable {
398
+ /** ase1. */
399
+ address: string;
400
+ locked: string;
401
+ withdrawable: string;
402
+ positions: unknown[];
403
+ [extra: string]: unknown;
404
+ }
405
+ /** A decoded contract event from eth_getLogs (finalized blocks only). */
406
+ interface Log {
407
+ /** ase1: the contract that emitted it. */
408
+ address: string;
409
+ /** topics[0]: BLAKE3 of the event name (not Keccak). */
410
+ topic: string;
411
+ topics: string[];
412
+ /** Event name when the SDK knows it (you filtered by name). */
413
+ eventName?: string;
414
+ /** JSON.parse of the UTF-8 data, or the raw text when it is not JSON. */
415
+ data: unknown;
416
+ /** Raw 0x hex data as the node sent it. */
417
+ rawData: string;
418
+ blockNumber: number;
419
+ blockHash: string;
420
+ transactionHash: string;
421
+ transactionIndex: number;
422
+ /** Counts across the whole block, so (blockHash, logIndex) is unique. */
423
+ logIndex: number;
424
+ removed: boolean;
425
+ }
426
+ interface LogFilter {
427
+ /** Contract address (ase1 or 0x), or several. */
428
+ address?: string | string[];
429
+ /** Event name; the SDK computes topics[0] = BLAKE3(name). */
430
+ event?: string;
431
+ /** Raw topics, if you already have them. Ignored when `event` is set. */
432
+ topics?: (string | string[] | null)[];
433
+ /** Height or "latest"/"finalized"/"earliest". Default "latest" (the finalized head). */
434
+ fromBlock?: number | bigint | string;
435
+ toBlock?: number | bigint | string;
436
+ }
437
+ /** Ethereum-shaped transaction from eth_getTransactionByHash, addresses as ase1. */
438
+ interface EthTransaction {
439
+ hash: string;
440
+ blockHash: string | null;
441
+ blockNumber: string | null;
442
+ transactionIndex: string | null;
443
+ /** ase1. */
444
+ from: string;
445
+ /** ase1, null for a deploy. */
446
+ to: string | null;
447
+ nonce: string;
448
+ value: string;
449
+ gas: string;
450
+ gasPrice?: string;
451
+ input: string;
452
+ finalized?: boolean;
453
+ [extra: string]: unknown;
150
454
  }
151
455
 
456
+ /** The public testnet gateway. */
457
+ declare const DEFAULT_RPC = "https://testnet.asentum.com";
458
+ /** Address of the governance contract (0x...0003), ase1. */
459
+ declare const GOVERNANCE_CONTRACT: string;
460
+ /** eth_getLogs scans at most this many blocks per call. */
461
+ declare const MAX_LOG_RANGE = 10000;
462
+ interface ClientOptions extends TransportOptions {
463
+ }
464
+ interface CallOptions {
465
+ signal?: AbortSignal;
466
+ /** Override the retry count for this call. */
467
+ retries?: number;
468
+ }
469
+ interface BlockOptions extends CallOptions {
470
+ /** Also answer heights above the finalized head, from the pending block on the node's best chain. Default false. */
471
+ tip?: boolean;
472
+ }
473
+ interface ReceiptOptions extends CallOptions {
474
+ /** Only return a receipt once its block is final (`?tip=0`). Default false: tip receipts too, flagged finalized: false. */
475
+ finalizedOnly?: boolean;
476
+ }
477
+ interface ViewOptions extends CallOptions {
478
+ /** "tip" (default; "latest"/"pending" mean the same) or "finalized" ("safe"). No historical reads. */
479
+ blockTag?: BlockTag;
480
+ }
481
+ type WaitUntil = 'included' | 'final';
152
482
  /**
153
- * AsentumContract — a deployed contract instance that wraps view calls
154
- * and write transactions.
155
- *
156
- * Usage:
157
- *
158
- * // Deploy via a wallet
159
- * const contract = await wallet.deploy(source);
160
- * console.log(contract.address);
483
+ * Options for {@link AsentumClient.waitForReceipt} and `tx.wait()`.
161
484
  *
162
- * // Or wrap an existing deployed contract
163
- * const contract = new AsentumContract(client, '0xabc...');
164
- *
165
- * // Read (free, no signature)
166
- * const name = await contract.view('name');
167
- * const balance = await contract.view('balanceOf', ['0x...']);
168
- *
169
- * // Write (requires a wallet)
170
- * const tx = await contract.send('transfer', ['0x...', '1000']);
171
- * const receipt = await tx.wait();
485
+ * A transaction goes pending (accepted into a mempool) -> in a block
486
+ * (receipt with finalized: false, about one block after sending) -> final
487
+ * (finalized: true, a few blocks later). Rarely a block loses to a sibling
488
+ * at the same height before it is final: the receipt disappears and the
489
+ * transaction lands again in a later block. onReorg reports that.
172
490
  */
173
-
174
- declare class AsentumContract {
175
- readonly client: AsentumClient;
176
- readonly address: string;
177
- /** The deploy tx, if this contract was deployed in this session. */
178
- readonly deployTx?: SentTx;
179
- /** The wallet used to deploy this contract, if any. Used as default signer for send(). */
180
- private wallet?;
181
- constructor(client: AsentumClient, address: string, deployTx?: SentTx, wallet?: AsentumWallet);
491
+ interface WaitOptions {
492
+ /** Resolve at the first receipt ("included", default) or only once final ("final"). */
493
+ until?: WaitUntil;
494
+ /** Give up after this long. Default 60,000 for "included", 120,000 for "final". */
495
+ timeoutMs?: number;
496
+ /** Poll interval. Default 1,000 (blocks are about 2.5 s apart). */
497
+ pollIntervalMs?: number;
498
+ /** The transaction is in a block (show success now). Fires again after a reorg puts it in another block. */
499
+ onIncluded?: (receipt: Receipt) => void;
500
+ /** The block is final. Only fires with until: "final". */
501
+ onFinal?: (receipt: Receipt) => void;
502
+ /** A block the transaction was in lost to a sibling; `previous` is the receipt that is no longer valid. */
503
+ onReorg?: (previous: Receipt) => void;
504
+ /** Abort waiting (rejects with AbortError). The transaction itself is not affected. */
505
+ signal?: AbortSignal;
506
+ /** Reject with TxFailedError when the receipt has success: false. Default false (resolve with the receipt). */
507
+ throwOnFailure?: boolean;
508
+ /** In a browser, do not poll while the tab is hidden. Default true. */
509
+ pauseWhenHidden?: boolean;
510
+ }
511
+ /** topics[0] of an event: BLAKE3 of the UTF-8 event name, 0x hex. */
512
+ declare function eventTopic(name: string): string;
513
+ declare class AsentumClient {
514
+ readonly rpcUrl: string;
515
+ /** @internal */
516
+ readonly transport: Transport;
517
+ private chainIdCache?;
518
+ constructor(rpcUrl?: string, options?: ClientOptions);
519
+ /** Finalized height and tip in one small call (GET /v3/heads). */
520
+ getHeads(opts?: CallOptions): Promise<Heads>;
521
+ /** Newest block height on the best chain. */
522
+ getTipNumber(opts?: CallOptions): Promise<number>;
523
+ /** Finalized height (same as eth_blockNumber and getBlockNumber). */
524
+ getFinalizedNumber(opts?: CallOptions): Promise<number>;
525
+ /** Chain id, finalized height, this node's mempool size and the finalized header (GET /chain, cached 1 s on the gateway). */
526
+ getChainInfo(opts?: CallOptions): Promise<ChainInfo>;
527
+ /** The FINALIZED height. Use getTipNumber() for the newest block. */
528
+ getBlockNumber(opts?: CallOptions): Promise<number>;
529
+ /** Chain id (1423 on the public testnet). Cached after the first call. */
530
+ getChainId(opts?: CallOptions): Promise<bigint>;
531
+ /** Chain details in EIP-3085 shape (GET /metadata, cached 30 s on the gateway). */
532
+ getMetadata(opts?: CallOptions): Promise<Metadata>;
533
+ /** Node identity (GET /api). `version` is a fixed placeholder, not the node release. */
534
+ getApiInfo(opts?: CallOptions): Promise<ApiInfo>;
535
+ /** The genesis spec (GET /genesis, about 17 KB). Address fields converted to ase1. */
536
+ getGenesis(opts?: CallOptions): Promise<Record<string, unknown>>;
537
+ /** Liveness probe (GET /health). True as long as the HTTP server answers. Does not check sync. */
538
+ isHealthy(opts?: CallOptions): Promise<boolean>;
539
+ /**
540
+ * Readiness probe (GET /ready): true on 200 "ready", false on 503 "stale"
541
+ * or no answer. Caveat: node 0.8.1 compares seconds with milliseconds
542
+ * here, so it reports ready even on a stalled node. To detect a stall,
543
+ * check that getHeads() keeps moving.
544
+ */
545
+ isReady(opts?: CallOptions): Promise<boolean>;
546
+ /** Balance (wei), nonce and pendingNonce at the tip (GET /balance). */
547
+ getBalance(address: string, opts?: CallOptions): Promise<Balance>;
548
+ /**
549
+ * The nonce to SEND with. Default: the node's mempool-aware pendingNonce,
550
+ * so several sends in a row get n, n+1, n+2. `{ pending: false }` gives
551
+ * the account nonce at the tip.
552
+ */
553
+ getNonce(address: string, opts?: CallOptions & {
554
+ pending?: boolean;
555
+ }): Promise<bigint>;
556
+ /** Full account record: balance, nonce, codeHash, storageRoot (GET /asentum/account). */
557
+ getAccount(address: string, opts?: CallOptions): Promise<AccountInfo>;
558
+ /** Whether the chain has this account's public key on record, so it may send key-less transactions (GET /public-key). */
559
+ getPublicKeyStatus(address: string, opts?: CallOptions): Promise<PublicKeyStatus>;
182
560
  /**
183
- * Call a view function (read-only, free, no transaction).
561
+ * A block with decoded transactions and receipts, or null when this node
562
+ * does not have it. Finalized blocks only, unless `{ tip: true }`.
563
+ * (0.1.x returned the node's error object here instead of null.)
564
+ */
565
+ getBlock(number: number | bigint, opts?: BlockOptions): Promise<Block | null>;
566
+ /** Only the receipts of a block (GET /block/<n>/receipts). Check `available` before trusting an empty list. */
567
+ getBlockReceipts(number: number | bigint, opts?: BlockOptions): Promise<BlockReceipts>;
568
+ /** The block as SSZ bytes (0x hex), or null. Note: also serves pending heights without saying so. */
569
+ getRawBlock(number: number | bigint, opts?: CallOptions): Promise<string | null>;
570
+ /** Whether a height is finalized on this node, and the Aura hash finalized there (GET /v3/finalized). */
571
+ getFinalizedStatus(height: number | bigint, opts?: CallOptions): Promise<FinalizedStatus>;
572
+ /**
573
+ * The receipt of a transaction, or null when it is not in a block (yet).
574
+ * Tip receipts are included by default (finalized: false); see
575
+ * `finalizedOnly`. Check `success`, not `status`.
184
576
  *
185
- * @param method - The function name to call.
186
- * @param args - Arguments to pass to the function.
187
- * @returns The return value of the function.
577
+ * Throws RpcError for a malformed hash and HttpError / NetworkError after
578
+ * retries (0.1.x returned null for every error).
579
+ */
580
+ getReceipt(txHash: string, opts?: ReceiptOptions): Promise<Receipt | null>;
581
+ /** The transaction body from eth_getTransactionByHash (in-block transactions only, tip too), or null. */
582
+ getTransaction(txHash: string, opts?: CallOptions): Promise<EthTransaction | null>;
583
+ /**
584
+ * Submit one signed transaction (POST /tx). Does not throw on rejection:
585
+ * check `accepted`. `accepted: true` only means "in this node's mempool".
188
586
  */
189
- view(method: string, args?: unknown[]): Promise<unknown>;
587
+ submitRawTx(rawTxHex: string, opts?: CallOptions): Promise<TxResult>;
190
588
  /**
191
- * Call a view function and return the full result including gas + events.
589
+ * Submit several signed transactions in one request (POST /tx/batch).
590
+ * They are admitted in order; one rejection does not stop the rest.
192
591
  */
193
- viewFull(method: string, args?: unknown[]): Promise<ViewCallResult>;
592
+ submitRawTxBatch(rawTxs: string[], opts?: CallOptions): Promise<BatchTxResult>;
194
593
  /**
195
- * Send a state-changing transaction to the contract.
594
+ * Wait for a transaction's receipt. Polls GET /receipts about once a
595
+ * second, backs off on 429 / 5xx, and follows the receipt through a
596
+ * reorg (onReorg, then onIncluded again for the new block).
196
597
  *
197
- * @param method - The function name to call.
198
- * @param args - Arguments to pass.
199
- * @param opts - Optional: value to attach, gas limit, nonce, wallet override.
200
- * @returns A SentTx with `.hash` and `.wait()`.
598
+ * Resolves with the receipt (until: "included", the default) or with the
599
+ * final receipt (until: "final"). Rejects with TimeoutError (not a
600
+ * failure: the tx may still land), AbortError, or TxFailedError when
601
+ * throwOnFailure is set.
201
602
  */
202
- send(method: string, args?: unknown[], opts?: {
203
- value?: string | number | bigint;
204
- gasLimit?: bigint;
205
- nonce?: bigint;
206
- wallet?: AsentumWallet;
207
- }): Promise<SentTx>;
603
+ waitForReceipt(txHash: string, opts?: WaitOptions): Promise<Receipt>;
208
604
  /**
209
- * Attach a wallet to this contract for future send() calls.
605
+ * Run a contract method read-only (POST /view). ase1 addresses inside
606
+ * `args` are converted to 0x hex first (the node does not convert them,
607
+ * and contracts store accounts as hex). Reads the tip unless
608
+ * `{ blockTag: 'finalized' }`. Does not throw on ok: false; see view().
210
609
  */
211
- connect(wallet: AsentumWallet): AsentumContract;
610
+ viewCall(contract: string, method: string, args?: unknown[], opts?: ViewOptions): Promise<ViewCallResult>;
611
+ /** Like viewCall, but returns the method's return value and throws ViewError on ok: false. */
612
+ view<T = unknown>(contract: string, method: string, args?: unknown[], opts?: ViewOptions): Promise<T>;
613
+ /** A contract's source, hex-encoded UTF-8 (eth_getCode). "0x" for an account without code. */
614
+ getCode(address: string, opts?: CallOptions): Promise<string>;
615
+ /** A contract's JavaScript source as text, or null when the address has no code. */
616
+ getContractSource(address: string, opts?: CallOptions): Promise<string | null>;
617
+ /** A contract storage value by key (a plain string such as "self"), as text, or null when empty (eth_getStorageAt). */
618
+ getStorageAt(address: string, key: string, opts?: CallOptions): Promise<string | null>;
212
619
  /**
213
- * Get the source code of this contract as a UTF-8 string.
214
- * Returns null if the address has no deployed code.
620
+ * Contract events from eth_getLogs, decoded. Finalized blocks only. A
621
+ * range wider than 10,000 blocks is split into several calls.
622
+ *
623
+ * await client.getLogs({ address: 'ase1...', event: 'Transfer', fromBlock: 570000, toBlock: 571000 })
215
624
  */
216
- getSource(): Promise<string | null>;
625
+ getLogs(filter?: LogFilter, opts?: CallOptions): Promise<Log[]>;
626
+ /** Every bonded validator with stake and committee state, plus the epoch (GET /validators, about 260 KB). */
627
+ getValidators(opts?: CallOptions): Promise<ValidatorsResponse>;
628
+ /** Who signed recent blocks (GET /participation). lookback 1 to 10,000, default 1,000. */
629
+ getParticipation(opts?: CallOptions & {
630
+ lookback?: number;
631
+ }): Promise<Participation>;
632
+ /** The voting committee of an epoch (default: current), ase1, in canonical order (GET /v3/committee). */
633
+ getCommittee(opts?: CallOptions & {
634
+ epoch?: number | bigint;
635
+ }): Promise<Committee>;
636
+ /** The node's liveness tracker (GET /consensus/liveness, about 40 KB). */
637
+ getLiveness(opts?: CallOptions): Promise<Liveness>;
638
+ /** Slashed and tombstoned validators (GET /slashing/tombstones). */
639
+ getTombstones(opts?: CallOptions): Promise<Tombstones>;
640
+ /** The newest proposals, up to 50 (GET /governance/proposals). */
641
+ getProposals(opts?: CallOptions): Promise<GovernanceProposal[]>;
642
+ /** One proposal with its amendments, or null for an unknown id (GET /governance/proposal/<id>). */
643
+ getProposal(id: number | string, opts?: CallOptions): Promise<GovernanceProposalDetail | null>;
644
+ /** ASE (wei) an address has locked in governance votes (GET /governance/locked). */
645
+ getGovernanceLocked(address: string, opts?: CallOptions): Promise<GovernanceLocked>;
646
+ /** Vote weight still locked vs ready to withdraw (GET /governance/withdrawable). */
647
+ getGovernanceWithdrawable(address: string, opts?: CallOptions): Promise<GovernanceWithdrawable>;
648
+ /** Approved libraries (GET /governance/libraries). Library approval is disabled, so always empty today. */
649
+ getGovernanceLibraries(opts?: CallOptions): Promise<unknown[]>;
650
+ /** One approved library by name, or null (GET /governance/library/<name>). */
651
+ getGovernanceLibrary(name: string, opts?: CallOptions): Promise<unknown | null>;
217
652
  /**
218
- * Get the ASE balance of this contract.
653
+ * @deprecated The node's POST /dev/faucet is OFF unless the operator sets
654
+ * ASENTUM_DEV_FAUCET=1, which only makes sense on a local devnet. Every
655
+ * public node answers `{ accepted: false, reason: "faucet not enabled on
656
+ * this node" }`. For test ASE use the airdrop dashboard (see the docs page
657
+ * "Get Test ASE"). Kept for local devnets; never throws on 404 / 429.
219
658
  */
220
- getBalance(): Promise<bigint>;
659
+ faucet(to: string, amount?: string, opts?: CallOptions): Promise<TxResult>;
660
+ /** Send one Ethereum-style JSON-RPC request to POST /. Throws JsonRpcError on an error object. */
661
+ jsonRpc<T>(method: string, params?: unknown[], opts?: CallOptions): Promise<T>;
662
+ /** GET and return the body as is. */
663
+ protected get<T>(path: string, opts?: CallOptions & Pick<RequestOptions, 'allowStatus'>): Promise<T>;
664
+ /** GET and throw RpcError when the body carries an `error` field (the node's HTTP 200 errors). */
665
+ protected getChecked<T>(path: string, opts?: CallOptions & Pick<RequestOptions, 'allowStatus'>): Promise<T>;
666
+ }
667
+
668
+ interface ContractSendOpts {
669
+ /** ASE to send with the call, parsed with parseAse ("1.5" = 1.5 ASE, bigint = wei). Prefer valueWei. */
670
+ value?: string | number | bigint;
671
+ /** Value in wei. Takes precedence over `value`. */
672
+ valueWei?: bigint | string;
673
+ gasLimit?: bigint;
674
+ nonce?: bigint;
675
+ /** Signer for this call; default the wallet attached with connect() or deploy(). */
676
+ wallet?: AsentumWallet;
677
+ signal?: AbortSignal;
678
+ }
679
+ declare class AsentumContract {
680
+ readonly client: AsentumClient;
681
+ /** ase1. (0.1.x kept whatever was passed in; a deploy gave 0x hex.) */
682
+ readonly address: string;
683
+ /** Lowercase 0x hex, what other contracts and msg.sender comparisons use. */
684
+ readonly addressHex: string;
685
+ /** The deploy transaction, when this contract was deployed in this session. */
686
+ readonly deployTx?: SentTx;
687
+ private wallet?;
688
+ constructor(client: AsentumClient, address: string, deployTx?: SentTx, wallet?: AsentumWallet);
689
+ /** Call a view method (free, no transaction) and return its value. Throws ViewError on ok: false. */
690
+ view<T = unknown>(method: string, args?: unknown[], opts?: ViewOptions): Promise<T>;
691
+ /** Call a view method and return the full result: value, gas, events, blockNumber, finalized. */
692
+ viewFull(method: string, args?: unknown[], opts?: ViewOptions): Promise<ViewCallResult>;
693
+ /** Send a state-changing call. Needs a wallet (connect() or opts.wallet). */
694
+ send(method: string, args?: unknown[], opts?: ContractSendOpts): Promise<SentTx>;
695
+ /** A copy of this contract that signs with `wallet`. */
696
+ connect(wallet: AsentumWallet): AsentumContract;
697
+ /** The contract's JavaScript source, or null if the address has no code. */
698
+ getSource(opts?: CallOptions): Promise<string | null>;
699
+ /** The contract's ASE balance in wei. */
700
+ getBalance(opts?: CallOptions): Promise<bigint>;
701
+ /** The account record (codeHash = BLAKE3 of the source, storageRoot). */
702
+ getAccount(opts?: CallOptions): Promise<AccountInfo>;
221
703
  /**
222
- * Wait for the deploy transaction to be confirmed (if this contract
223
- * was deployed in this session). Useful after `wallet.deploy()`.
704
+ * Events this contract emitted, decoded (eth_getLogs, finalized blocks
705
+ * only, ranges over 10,000 blocks are split). `eventName` undefined = all.
224
706
  */
225
- waitForDeploy(timeoutMs?: number): Promise<Receipt>;
707
+ getEvents(eventName?: string, range?: {
708
+ fromBlock?: number | bigint | string;
709
+ toBlock?: number | bigint | string;
710
+ }, opts?: CallOptions): Promise<Log[]>;
711
+ /**
712
+ * Wait for the deploy transaction (only when deployed in this session).
713
+ * Accepts a timeout in ms (0.1.x) or WaitOptions, e.g. { until: 'final' }.
714
+ */
715
+ waitForDeploy(timeoutOrOpts?: number | WaitOptions): Promise<Receipt>;
716
+ }
717
+
718
+ interface Dilithium3Keypair {
719
+ publicKey: Uint8Array;
720
+ secretKey: Uint8Array;
226
721
  }
227
722
 
228
723
  /**
229
- * Parse an ASE amount string into wei (bigint).
230
- * Accepts: "1", "1.5", "0.001", or a raw wei integer string.
724
+ * Strict ASE to wei: the input is ALWAYS read as ASE.
725
+ * "1" -> 10^18, "0.5" -> 5 * 10^17, 2 -> 2 * 10^18. At most 18 decimals.
726
+ */
727
+ declare function aseToWei(amount: string | number): bigint;
728
+ /**
729
+ * Parse an amount into wei, the way 0.1.x did. Kept for compatibility; it
730
+ * has one trap, so prefer {@link aseToWei} (always ASE) or pass wei as a
731
+ * bigint:
732
+ *
733
+ * - bigint: already wei, returned as is.
734
+ * - number or decimal string ("1", "1.5"): ASE.
735
+ * - an integer string with MORE than 18 digits: treated as wei.
736
+ * ("1000000000000000000000" is 1,000 ASE in wei; "100" is 100 ASE.)
231
737
  */
232
738
  declare function parseAse(amount: string | number | bigint): bigint;
739
+ /** Format wei as an ASE decimal string without trailing zeros: 1500000000000000000n -> "1.5". */
740
+ declare function formatAse(wei: bigint | string | number): string;
741
+ /** Wei from a bigint, a decimal integer string or a safe integer number. Throws on anything else. */
742
+ declare function toWei(v: bigint | string | number): bigint;
743
+
233
744
  /**
234
- * Format a wei bigint as a human-readable ASE string.
745
+ * Format an address for display: ase1 by default. The env override
746
+ * `ASENTUM_ADDR_FORMAT=hex` returns lowercase 0x hex instead.
235
747
  */
236
- declare function formatAse(wei: bigint | string): string;
237
- interface SendTransferOpts {
238
- /** Recipient address (0x-prefixed, 40 hex chars). */
239
- to: string;
240
- /** Amount in ASE (e.g. "1.5") or wei (bigint). */
241
- amount: string | number | bigint;
242
- /** Override the gas limit. Default: 21,000. */
243
- gasLimit?: bigint;
244
- /** Override the nonce. Default: auto-fetched from the chain. */
748
+ declare function formatAddress(input: string | Uint8Array): string;
749
+ /**
750
+ * Key-less transactions (key-once, live since block 528,000): once the chain
751
+ * has an account's public key on record, its transactions may name the
752
+ * sender instead of carrying the 1,952-byte key, which makes them about a
753
+ * third smaller.
754
+ * "off" always include the key (default, works for every account)
755
+ * "auto" go key-less once GET /public-key says canOmitKey
756
+ * "always" always key-less (rejected if the key is not on record)
757
+ */
758
+ type KeylessMode = 'off' | 'auto' | 'always';
759
+ interface WalletOptions {
760
+ keyless?: KeylessMode;
761
+ }
762
+ interface CommonTxOpts {
763
+ /** Override the nonce. Default: allocated by the wallet (see getNonce / resetNonce). */
245
764
  nonce?: bigint;
765
+ /** Override the gas limit. */
766
+ gasLimit?: bigint;
767
+ /** Max fee per gas in wei. Default 1 (the base fee is 1 wei per gas). */
768
+ maxFeePerGas?: bigint;
769
+ /** Override the wallet's key-less mode for this transaction. */
770
+ keyless?: KeylessMode;
771
+ signal?: AbortSignal;
246
772
  }
247
- interface SendCallOpts {
248
- /** Contract address (0x-prefixed, 40 hex chars). */
773
+ interface SendTransferOpts extends CommonTxOpts {
774
+ /** Recipient, ase1 or 0x hex. */
249
775
  to: string;
250
- /** Method name to call on the contract. */
776
+ /**
777
+ * Amount, parsed with parseAse: a number or decimal string is ASE
778
+ * ("1.5" = 1.5 ASE), a bigint is wei. Careful: an integer STRING longer
779
+ * than 18 digits is read as wei. Prefer `amountWei` for exact values.
780
+ */
781
+ amount?: string | number | bigint;
782
+ /** Amount in wei (bigint or decimal integer string). Takes precedence over `amount`. */
783
+ amountWei?: bigint | string;
784
+ }
785
+ interface SendCallOpts extends CommonTxOpts {
786
+ /** Contract address, ase1 or 0x hex. */
787
+ to: string;
788
+ /** Method name. */
251
789
  method: string;
252
- /** Method arguments (passed as JSON to the contract). */
790
+ /**
791
+ * Arguments, sent as JSON. Every ase1 address string, at any depth, is
792
+ * converted to lowercase 0x hex before signing (contracts compare with hex
793
+ * msg.sender).
794
+ */
253
795
  args?: unknown[];
254
- /** ASE to attach to the call (default: 0). */
796
+ /**
797
+ * ASE to send with the call, parsed with parseAse: "1.5" or 2 is ASE, a
798
+ * bigint is wei (and an integer string over 18 digits is wei). Prefer
799
+ * `valueWei` for exact values.
800
+ */
255
801
  value?: string | number | bigint;
256
- /** Override the gas limit. Default: 2,000,000. */
257
- gasLimit?: bigint;
258
- /** Override the nonce. Default: auto-fetched. */
259
- nonce?: bigint;
802
+ /** Value in wei. Takes precedence over `value`. */
803
+ valueWei?: bigint | string;
260
804
  }
261
- interface DeployOpts {
262
- /** The JavaScript source code of the contract. */
805
+ interface DeployOpts extends CommonTxOpts {
806
+ /** The contract's JavaScript source. */
263
807
  source: string;
264
- /** ASE to attach to the deploy (default: 0). */
808
+ /** ASE to send with the deploy, parsed like SendCallOpts.value. */
265
809
  value?: string | number | bigint;
266
- /** Override the gas limit. Default: based on source length. */
267
- gasLimit?: bigint;
268
- /** Override the nonce. Default: auto-fetched. */
269
- nonce?: bigint;
810
+ /** Value in wei. Takes precedence over `value`. */
811
+ valueWei?: bigint | string;
812
+ }
813
+ /** A signed transaction that has not been submitted (see sign* and sendBatch). */
814
+ interface SignedTx {
815
+ /** 0x hex wire bytes, what POST /tx takes. */
816
+ rawTx: string;
817
+ /** The transaction hash (0x hex, BLAKE3 of rawTx). Hashes stay hex: there is no ase1 form. */
818
+ hash: string;
819
+ nonce: bigint;
820
+ /** ase1 of the signer. */
821
+ from: string;
822
+ /** For a deploy: the new contract's address (ase1). */
823
+ contractAddress?: string;
270
824
  }
271
825
  interface SentTx {
272
- /** The transaction hash (0x-prefixed). */
826
+ /** The transaction hash (0x hex). */
273
827
  hash: string;
274
- /** Wait for the transaction to be included in a block. */
275
- wait(timeoutMs?: number): Promise<Receipt>;
828
+ nonce: bigint;
829
+ /** ase1 of the signer. */
830
+ from: string;
831
+ /** For a deploy: the new contract's address (ase1). */
832
+ contractAddress?: string;
833
+ /**
834
+ * Wait for the receipt.
835
+ *
836
+ * await tx.wait() // first receipt: in a block (default, as in 0.1.x)
837
+ * await tx.wait(30_000) // same, 30 s timeout (0.1.x signature)
838
+ * await tx.wait({ until: 'final' }) // only once its block is final
839
+ *
840
+ * Resolves with the receipt even when it has success: false (as in 0.1.x);
841
+ * pass `{ throwOnFailure: true }` to reject with TxFailedError instead.
842
+ * Default timeout: 60 s ("included"), 120 s ("final"); rejects with
843
+ * TimeoutError, which does not mean the transaction failed.
844
+ */
845
+ wait(timeoutOrOpts?: number | WaitOptions): Promise<Receipt>;
846
+ }
847
+ interface BatchSendResult {
848
+ accepted: number;
849
+ rejected: number;
850
+ total: number;
851
+ /** Same order as the input. Rejected entries have accepted: false and a reason; they will not land. */
852
+ results: Array<TxResult & {
853
+ hash: string;
854
+ nonce: bigint;
855
+ wait: SentTx['wait'];
856
+ }>;
276
857
  }
277
858
  declare class AsentumWallet {
278
859
  readonly client: AsentumClient;
279
860
  readonly keypair: Dilithium3Keypair;
861
+ /**
862
+ * The wallet's address as ase1. (0.1.x returned checksummed 0x hex here;
863
+ * use `addressHex` for the hex form.)
864
+ */
280
865
  readonly address: string;
866
+ /** The same address as lowercase 0x hex: what contracts see as msg.sender. */
867
+ readonly addressHex: string;
868
+ /** Key-less mode for transactions from this wallet. */
869
+ keyless: KeylessMode;
870
+ private readonly addressBytes;
871
+ private nextNonce?;
872
+ private queue;
873
+ private keyOnRecord;
874
+ private keyCheckedAt;
281
875
  private constructor();
282
- /** Create a wallet with a random Dilithium3 keypair. */
283
- static create(client: AsentumClient): AsentumWallet;
284
- /** Create a wallet from a 32-byte seed. */
285
- static fromSeed(client: AsentumClient, seed: Uint8Array): AsentumWallet;
286
- /** Create a wallet from a hex-encoded secret key. */
287
- static fromSecretKey(client: AsentumClient, secretKeyHex: string, publicKeyHex: string): AsentumWallet;
288
- /** Get the secret key as a hex string (for export/backup). */
876
+ /** A wallet with a random keypair. */
877
+ static create(client: AsentumClient, opts?: WalletOptions): AsentumWallet;
878
+ /** A wallet from a seed (the first 32 bytes are used). Same seed, same keys. */
879
+ static fromSeed(client: AsentumClient, seed: Uint8Array, opts?: WalletOptions): AsentumWallet;
880
+ /** A wallet from exported hex keys (secretKeyHex / publicKeyHex). */
881
+ static fromSecretKey(client: AsentumClient, secretKeyHex: string, publicKeyHex: string, opts?: WalletOptions): AsentumWallet;
882
+ /** The secret key as hex, for backup. Treat it like a password. */
289
883
  get secretKeyHex(): string;
290
- /** Get the public key as a hex string. */
884
+ /** The public key as hex. */
291
885
  get publicKeyHex(): string;
292
- /** Get the current balance in wei. */
886
+ /** Balance in wei. */
293
887
  getBalance(): Promise<bigint>;
294
- /** Get the current nonce. */
888
+ /** The node's pendingNonce for this wallet (the nonce the next transaction would use, ignoring local allocations). */
295
889
  getNonce(): Promise<bigint>;
296
- /** Request test ASE from the faucet. */
890
+ /**
891
+ * Forget locally allocated nonces; the next transaction asks the node
892
+ * again. The wallet does this itself after a rejection.
893
+ */
894
+ resetNonce(): void;
895
+ /**
896
+ * @deprecated POST /dev/faucet is off on every public node (see
897
+ * AsentumClient.faucet). Use the airdrop dashboard for test ASE.
898
+ */
297
899
  requestFaucet(amount?: string): Promise<TxResult>;
298
- /** Send ASE to another address. */
900
+ /** Send ASE. Throws TxRejectedError when the node does not accept it. */
299
901
  sendTransfer(opts: SendTransferOpts): Promise<SentTx>;
300
- /** Call a method on a deployed contract (state-changing). */
902
+ /** Call a contract method (state-changing). Throws TxRejectedError when the node does not accept it. */
301
903
  sendCall(opts: SendCallOpts): Promise<SentTx>;
302
- /** Deploy a new smart contract. Returns an AsentumContract instance. */
904
+ /**
905
+ * Same as sendCall, but `value` is in wei. Use this when you hold wei
906
+ * amounts (balances, contract return values) so nothing is reinterpreted.
907
+ */
908
+ sendCallWei(opts: Omit<SendCallOpts, 'value' | 'valueWei'> & {
909
+ value?: bigint | string;
910
+ }): Promise<SentTx>;
911
+ /** Same as sendTransfer, but `amount` is in wei. */
912
+ sendTransferWei(opts: Omit<SendTransferOpts, 'amount' | 'amountWei'> & {
913
+ amount: bigint | string;
914
+ }): Promise<SentTx>;
915
+ /**
916
+ * Deploy a contract. Returns an AsentumContract at the derived address
917
+ * right away; the deploy is only accepted, so `await contract.waitForDeploy()`
918
+ * before using it.
919
+ */
303
920
  deploy(sourceOrOpts: string | DeployOpts): Promise<AsentumContract>;
304
- private signAndSubmit;
921
+ /** Sign a transfer without submitting it (allocates the next nonce unless given). */
922
+ signTransfer(opts: SendTransferOpts): Promise<SignedTx>;
923
+ /** Sign a contract call without submitting it. */
924
+ signCall(opts: SendCallOpts): Promise<SignedTx>;
925
+ /** Sign a deploy without submitting it. `contractAddress` is the address it will get. */
926
+ signDeploy(opts: DeployOpts): Promise<SignedTx>;
927
+ /**
928
+ * Submit several signed transactions in one request (POST /tx/batch), in
929
+ * the given order. Sign them first with signTransfer / signCall /
930
+ * signDeploy (consecutive calls get consecutive nonces). One rejection
931
+ * does not stop the rest, but a nonce gap leaves later ones waiting.
932
+ * Does not throw on rejections: check each result.
933
+ */
934
+ sendBatch(txs: SignedTx[], opts?: {
935
+ signal?: AbortSignal;
936
+ }): Promise<BatchSendResult>;
937
+ /** Run fn after every earlier send/sign of this wallet, so nonces are handed out in order. */
938
+ private serial;
939
+ private allocateNonce;
940
+ private useKeyless;
941
+ private build;
942
+ private buildTransfer;
943
+ private buildCall;
944
+ private buildDeploy;
945
+ private submit;
305
946
  }
947
+ /** The address a deploy from `sender` with `nonce` gets (ase1). */
948
+ declare function getContractAddress(sender: string, nonce: bigint | number): string;
949
+
950
+ /**
951
+ * If `s` is a valid ase1 address (bech32 checksum OK, HRP exactly "ase",
952
+ * 20-byte payload, single case, no surrounding whitespace) return its
953
+ * lowercase `0x` hex form. Otherwise return null.
954
+ */
955
+ declare function ase1ToHexOrNull(s: string): string | null;
956
+ /** ase1 to lowercase 0x hex, or null when the checksum or length is wrong. Same as ase1ToHexOrNull. */
957
+ declare function ase1ToHex(s: string): string | null;
958
+ /** True for a well-formed ase1 address with a valid checksum. */
959
+ declare function isAse1(s: unknown): boolean;
960
+ /** True for a 0x hex address (20 bytes, any case). */
961
+ declare function isHexAddress(s: unknown): boolean;
962
+ /** True for either accepted address form. */
963
+ declare function isAddress(s: unknown): boolean;
964
+ /** 0x hex (20 bytes) to ase1. Returns '' when the input is not a hex address (same as @asentum/connect). */
965
+ declare function hexToAse1(hex: string): string;
966
+ /**
967
+ * Any address (hex or ase1) to lowercase ase1, for display. Input that is
968
+ * not an address is returned unchanged (empty string for null/undefined).
969
+ */
970
+ declare function toAse1(a: string | null | undefined): string;
971
+ /**
972
+ * Any address (hex or ase1) to lowercase 0x hex: the form contracts use.
973
+ * Throws InvalidAddress-style Error on anything else.
974
+ */
975
+ declare function toHexAddress(a: string): string;
976
+ /** Parse either address form into 20 raw bytes. Throws on invalid input. */
977
+ declare function addressToBytes(a: string): Uint8Array;
978
+ /** 20 raw bytes to ase1. */
979
+ declare function bytesToAse1(bytes: Uint8Array): string;
980
+ /** Shortened ase1 for buttons and chips, e.g. ase1qxyz12...ab34cd. */
981
+ declare function shortAse1(a: string | null | undefined, lead?: number, tail?: number): string;
982
+ /**
983
+ * Recursively walk contract call arguments (arrays and plain objects,
984
+ * values only, never keys) and replace every string that is a valid ase1
985
+ * address with its lowercase `0x` hex form. Everything else is returned
986
+ * unchanged. The input is never mutated; a new structure is returned.
987
+ * Idempotent: hex input stays hex.
988
+ *
989
+ * Why: contract code runs with hex. `msg.sender` is lowercase `0x...`, so an
990
+ * ase1 string stored by a contract would never match that person's sender.
991
+ * The SDK applies this to every call it signs and every view it sends.
992
+ */
993
+ declare function ase1ArgsToHex<T>(value: T): T;
994
+
995
+ /**
996
+ * Typed errors. Every error the SDK throws on purpose extends AsentumError,
997
+ * so `err instanceof AsentumError` separates SDK errors from bugs, and the
998
+ * `code` string is stable for switch statements.
999
+ */
1000
+
1001
+ type AsentumErrorCode = 'HTTP_ERROR' | 'RATE_LIMITED' | 'NETWORK_ERROR' | 'RPC_ERROR' | 'JSON_RPC_ERROR' | 'TX_REJECTED' | 'TX_FAILED' | 'TIMEOUT' | 'ABORTED' | 'VIEW_FAILED' | 'INVALID_ARGUMENT';
1002
+ declare class AsentumError extends Error {
1003
+ readonly code: AsentumErrorCode;
1004
+ constructor(code: AsentumErrorCode, message: string, options?: {
1005
+ cause?: unknown;
1006
+ });
1007
+ }
1008
+ /** The node or gateway answered with a non-2xx HTTP status. */
1009
+ declare class HttpError extends AsentumError {
1010
+ readonly status: number;
1011
+ readonly url: string;
1012
+ /** Parsed JSON body when there was one, otherwise the text (the gateway sends HTML for 429). */
1013
+ readonly body: unknown;
1014
+ constructor(status: number, url: string, body: unknown, message?: string, code?: AsentumErrorCode);
1015
+ }
1016
+ /**
1017
+ * HTTP 429. The public gateway allows about 25 requests a second per IP and
1018
+ * answers 429 with an HTML page and no Retry-After; a node's own block-read
1019
+ * budget answers JSON with Retry-After. The SDK already retried with backoff
1020
+ * before throwing this.
1021
+ */
1022
+ declare class RateLimitError extends HttpError {
1023
+ /** From the Retry-After header, when the server sent one. */
1024
+ readonly retryAfterMs?: number;
1025
+ constructor(url: string, body: unknown, retryAfterMs?: number);
1026
+ }
1027
+ /** fetch itself failed (DNS, connection reset, CORS, per-request timeout). */
1028
+ declare class NetworkError extends AsentumError {
1029
+ readonly url: string;
1030
+ constructor(url: string, cause: unknown);
1031
+ }
1032
+ /**
1033
+ * HTTP 200 with an error body. Most node errors look like this: a bad
1034
+ * address, a bad tx hash, a governance read that failed. (A missing receipt
1035
+ * or block is NOT an error: those methods return null.)
1036
+ */
1037
+ declare class RpcError extends AsentumError {
1038
+ readonly path: string;
1039
+ readonly body: unknown;
1040
+ constructor(path: string, message: string, body: unknown);
1041
+ }
1042
+ /** A JSON-RPC (POST /) error object. */
1043
+ declare class JsonRpcError extends AsentumError {
1044
+ readonly rpcCode: number;
1045
+ readonly method: string;
1046
+ readonly data?: unknown;
1047
+ constructor(method: string, rpcCode: number, message: string, data?: unknown);
1048
+ }
1049
+ /**
1050
+ * POST /tx answered `accepted: false`. The transaction never reached the
1051
+ * mempool and will not land. `reason` is the node's text, for example
1052
+ * "stale nonce: account is at 153, tx has 152" or "insufficient balance".
1053
+ */
1054
+ declare class TxRejectedError extends AsentumError {
1055
+ readonly reason: string;
1056
+ /** The locally computed hash of the rejected transaction (it is not on chain). */
1057
+ readonly txHash?: string;
1058
+ constructor(reason: string, txHash?: string);
1059
+ /** True when the reason is about the nonce (stale, too far ahead, duplicate nonce). */
1060
+ get isNonceError(): boolean;
1061
+ }
1062
+ /** The transaction is in a block but ran and failed (`success: false`). */
1063
+ declare class TxFailedError extends AsentumError {
1064
+ readonly receipt: Receipt;
1065
+ constructor(receipt: Receipt);
1066
+ }
1067
+ /**
1068
+ * Waiting ran out of time. This is NOT a failure: the transaction may still
1069
+ * land. `lastReceipt` is set when it was seen in a block but not final yet.
1070
+ */
1071
+ declare class TimeoutError extends AsentumError {
1072
+ readonly txHash: string;
1073
+ readonly lastReceipt: Receipt | null;
1074
+ constructor(txHash: string, timeoutMs: number, until: string, lastReceipt: Receipt | null);
1075
+ }
1076
+ /** The caller's AbortSignal fired. `name` is "AbortError", as with fetch. */
1077
+ declare class AbortError extends AsentumError {
1078
+ constructor(message?: string);
1079
+ }
1080
+ /** POST /view answered `ok: false` (method missing, contract threw, bad blockTag). */
1081
+ declare class ViewError extends AsentumError {
1082
+ readonly method: string;
1083
+ readonly reason: string;
1084
+ constructor(method: string, reason: string);
1085
+ }
1086
+
1087
+ /**
1088
+ * @asentum/sdk: TypeScript SDK for building on Asentum.
1089
+ *
1090
+ * - {@link AsentumClient}: reads, submission of signed transactions, waitForReceipt
1091
+ * - {@link AsentumWallet}: keypair, signing, nonces, sending
1092
+ * - {@link AsentumContract}: view, send and events for one contract
1093
+ *
1094
+ * ```ts
1095
+ * import { AsentumClient, AsentumWallet } from '@asentum/sdk';
1096
+ *
1097
+ * const client = new AsentumClient('https://testnet.asentum.com');
1098
+ * const { finalized, tip } = await client.getHeads();
1099
+ *
1100
+ * const wallet = AsentumWallet.fromSecretKey(client, SECRET_HEX, PUBLIC_HEX);
1101
+ * const tx = await wallet.sendTransfer({ to: 'ase1...', amountWei: 10n ** 18n });
1102
+ * await tx.wait(); // in a block (about 2.5 s)
1103
+ * await tx.wait({ until: 'final' }); // final (a few blocks later)
1104
+ * ```
1105
+ */
1106
+
1107
+ /** SDK version. */
1108
+ declare const VERSION = "0.2.0";
306
1109
 
307
- export { AsentumClient, AsentumContract, AsentumWallet, type Balance, type Block, type BlockHeader, type ChainInfo, type DeployOpts, type Metadata, type Receipt, type SendCallOpts, type SendTransferOpts, type SentTx, type Transaction, type TxResult, type ValidatorInfo, type ViewCallResult, formatAse, parseAse };
1110
+ export { AbortError, type AccountInfo, type ApiInfo, AsentumClient, AsentumContract, AsentumError, type AsentumErrorCode, AsentumWallet, type Balance, type BatchSendResult, type BatchTxResult, type Block, type BlockHeader, type BlockOptions, type BlockReceipts, type BlockTag, type CallOptions, type ChainInfo, type ClientOptions, type Committee, type CommitteeState, type ContractSendOpts, DEFAULT_RPC, type DeployOpts, type Dilithium3Keypair, type EpochInfo, type EthTransaction, type FetchLike, type FinalizedStatus, GOVERNANCE_CONTRACT, type GovernanceLocked, type GovernanceProposal, type GovernanceProposalDetail, type GovernanceWithdrawable, type Heads, HttpError, JsonRpcError, type KeylessMode, type Liveness, type LivenessEntry, type Log, type LogFilter, MAX_LOG_RANGE, type Metadata, NetworkError, type Participation, type ParticipationEntry, type PublicKeyStatus, RateLimitError, type Receipt, type ReceiptEvent, type ReceiptOptions, RpcError, type SendCallOpts, type SendTransferOpts, type SentTx, type SignedTx, TimeoutError, type Tombstones, type Transaction, type TransportOptions, TxFailedError, TxRejectedError, type TxResult, VERSION, type ValidatorInfo, type ValidatorsResponse, type ViewCallResult, ViewError, type ViewOptions, type WaitOptions, type WaitUntil, type WalletOptions, addressToBytes, ase1ArgsToHex, ase1ToHex, ase1ToHexOrNull, aseToWei, bytesToAse1, eventTopic, formatAddress, formatAse, getContractAddress, hexToAse1, isAddress, isAse1, isHexAddress, parseAse, shortAse1, toAse1, toHexAddress, toWei };