zattera-js 0.1.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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +694 -0
  3. package/dist/browser/index.js +2466 -0
  4. package/dist/browser/index.js.map +1 -0
  5. package/dist/node/auth/index.js +188 -0
  6. package/dist/node/auth/index.js.map +1 -0
  7. package/dist/node/auth/keys.js +264 -0
  8. package/dist/node/auth/keys.js.map +1 -0
  9. package/dist/node/auth/memo.js +79 -0
  10. package/dist/node/auth/memo.js.map +1 -0
  11. package/dist/node/auth/serializer.js +162 -0
  12. package/dist/node/auth/serializer.js.map +1 -0
  13. package/dist/node/client/index.js +838 -0
  14. package/dist/node/client/index.js.map +1 -0
  15. package/dist/node/index.js +30 -0
  16. package/dist/node/index.js.map +1 -0
  17. package/dist/node/node_modules/@noble/ciphers/aes.js +254 -0
  18. package/dist/node/node_modules/@noble/ciphers/aes.js.map +1 -0
  19. package/dist/node/node_modules/@noble/ciphers/utils.js +113 -0
  20. package/dist/node/node_modules/@noble/ciphers/utils.js.map +1 -0
  21. package/dist/node/node_modules/@noble/hashes/esm/_md.js +146 -0
  22. package/dist/node/node_modules/@noble/hashes/esm/_md.js.map +1 -0
  23. package/dist/node/node_modules/@noble/hashes/esm/_u64.js +51 -0
  24. package/dist/node/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
  25. package/dist/node/node_modules/@noble/hashes/esm/legacy.js +123 -0
  26. package/dist/node/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
  27. package/dist/node/node_modules/@noble/hashes/esm/sha2.js +346 -0
  28. package/dist/node/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
  29. package/dist/node/node_modules/@noble/hashes/esm/utils.js +73 -0
  30. package/dist/node/node_modules/@noble/hashes/esm/utils.js.map +1 -0
  31. package/dist/node/node_modules/@noble/secp256k1/index.js +578 -0
  32. package/dist/node/node_modules/@noble/secp256k1/index.js.map +1 -0
  33. package/dist/node/node_modules/bs58/node_modules/base-x/src/esm/index.js +132 -0
  34. package/dist/node/node_modules/bs58/node_modules/base-x/src/esm/index.js.map +1 -0
  35. package/dist/node/node_modules/bs58/src/esm/index.js +7 -0
  36. package/dist/node/node_modules/bs58/src/esm/index.js.map +1 -0
  37. package/dist/node/types/index.js +48 -0
  38. package/dist/node/types/index.js.map +1 -0
  39. package/dist/node/utils/chain-id.js +9 -0
  40. package/dist/node/utils/chain-id.js.map +1 -0
  41. package/dist/types/auth/index.d.ts +134 -0
  42. package/dist/types/auth/index.d.ts.map +1 -0
  43. package/dist/types/auth/keys.d.ts +112 -0
  44. package/dist/types/auth/keys.d.ts.map +1 -0
  45. package/dist/types/auth/memo.d.ts +51 -0
  46. package/dist/types/auth/memo.d.ts.map +1 -0
  47. package/dist/types/auth/serializer.d.ts +57 -0
  48. package/dist/types/auth/serializer.d.ts.map +1 -0
  49. package/dist/types/client/index.d.ts +360 -0
  50. package/dist/types/client/index.d.ts.map +1 -0
  51. package/dist/types/index.d.ts +16 -0
  52. package/dist/types/index.d.ts.map +1 -0
  53. package/dist/types/types/index.d.ts +593 -0
  54. package/dist/types/types/index.d.ts.map +1 -0
  55. package/dist/types/utils/chain-id.d.ts +10 -0
  56. package/dist/types/utils/chain-id.d.ts.map +1 -0
  57. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Zattera Protocol
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,694 @@
1
+ # Zattera JS
2
+
3
+ TypeScript library for Zattera blockchain RPC calls. Works in both browser and Node.js environments with 100% ESM support.
4
+
5
+ ## Features
6
+
7
+ - **100% TypeScript** with full type safety
8
+ - **Zero runtime dependencies** - uses native Fetch API
9
+ - **Cross-platform** - works in both browser and Node.js (18+)
10
+ - **ESM-only** - modern module system
11
+ - **Built with Vite** for optimal performance
12
+ - **JSON-RPC 2.0** protocol compliant
13
+ - **Automatic retry logic** with exponential backoff
14
+ - **Batch requests** support
15
+ - **Comprehensive test coverage** with Vitest
16
+ - **Complete Zattera RPC API** implementation
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install zattera-js
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ### Node.js (ESM)
27
+
28
+ ```typescript
29
+ import { ZatteraClient } from 'zattera-js';
30
+
31
+ // Default: uses 'zattera' network
32
+ const client = new ZatteraClient({
33
+ endpoint: 'https://rpc.zattera.network',
34
+ timeout: 30000, // optional, default: 30000ms
35
+ retries: 3, // optional, default: 3
36
+ });
37
+
38
+ // Or specify network name
39
+ const testnetClient = new ZatteraClient({
40
+ endpoint: 'https://testnet.zattera.network',
41
+ networkName: 'testnet', // 'zattera' (default) | 'testnet'
42
+ });
43
+
44
+ // Get dynamic global properties
45
+ const props = await client.getDynamicGlobalProperties();
46
+ console.log('Head block:', props.head_block_number);
47
+
48
+ // Get account information
49
+ const accounts = await client.findAccounts({ accounts: ['alice'] });
50
+ console.log('Account:', accounts[0]);
51
+
52
+ // Get block
53
+ const block = await client.getBlock(12345);
54
+ console.log('Block:', block);
55
+ ```
56
+
57
+ ### Browser
58
+
59
+ ```typescript
60
+ import { ZatteraClient } from 'zattera-js';
61
+
62
+ const client = new ZatteraClient({
63
+ endpoint: 'https://rpc.zattera.network',
64
+ });
65
+
66
+ const props = await client.getDynamicGlobalProperties();
67
+ console.log('Current block:', props.head_block_number);
68
+ ```
69
+
70
+ ## API Reference
71
+
72
+ ### Constructor
73
+
74
+ ```typescript
75
+ new ZatteraClient(config: ZatteraClientConfig)
76
+ ```
77
+
78
+ **Config options:**
79
+ - `endpoint` (string, required): RPC endpoint URL
80
+ - `networkName` (NetworkName, optional): Network name for chain ID computation
81
+ - `'zattera'` (default) - Zattera mainnet
82
+ - `'testnet'` - Zattera testnet
83
+ - Chain ID is automatically computed using SHA256 hash
84
+ - `timeout` (number, optional): Request timeout in milliseconds (default: 30000)
85
+ - `retries` (number, optional): Number of retry attempts (default: 3)
86
+
87
+ **Network Examples:**
88
+ ```typescript
89
+ // Default: 'zattera' network (SHA256 hash computed automatically)
90
+ const client1 = new ZatteraClient({
91
+ endpoint: 'https://rpc.zattera.network'
92
+ });
93
+
94
+ // Testnet network
95
+ const client2 = new ZatteraClient({
96
+ endpoint: 'https://testnet.zattera.network',
97
+ networkName: 'testnet'
98
+ });
99
+
100
+ // Retrieve the computed chain ID
101
+ const chainId = client1.getChainId();
102
+ console.log('Chain ID:', chainId); // SHA256 hash of 'zattera'
103
+ ```
104
+
105
+ ### Core Methods
106
+
107
+ #### Get Chain ID
108
+
109
+ ```typescript
110
+ getChainId(): string
111
+ ```
112
+
113
+ Returns the computed or configured chain ID as a hex string (without 0x prefix).
114
+
115
+ **Example:**
116
+ ```typescript
117
+ const client = new ZatteraClient({
118
+ endpoint: 'https://rpc.zattera.network',
119
+ networkName: 'zattera'
120
+ });
121
+
122
+ const chainId = client.getChainId();
123
+ console.log('Chain ID:', chainId); // SHA256('zattera')
124
+ ```
125
+
126
+ #### Generic RPC Call
127
+
128
+ ```typescript
129
+ call<T>(method: string, params?: unknown[] | Record<string, unknown>): Promise<T>
130
+ ```
131
+
132
+ Makes a generic JSON-RPC call with the specified method and parameters.
133
+
134
+ #### Batch Requests
135
+
136
+ ```typescript
137
+ batch<T>(requests: Array<{method: string, params?: unknown[]}>): Promise<T[]>
138
+ ```
139
+
140
+ Execute multiple RPC requests in a single batch call for better performance.
141
+
142
+ **Example:**
143
+ ```typescript
144
+ const [props, witnesses] = await client.batch([
145
+ { method: 'database_api.get_dynamic_global_properties' },
146
+ { method: 'database_api.get_active_witnesses' }
147
+ ]);
148
+ ```
149
+
150
+ ## Database API
151
+
152
+ ### Global Properties
153
+
154
+ #### `getConfig(): Promise<ChainConfig>`
155
+
156
+ Get compile-time chain configuration constants.
157
+
158
+ #### `getDynamicGlobalProperties(): Promise<DynamicGlobalProperties>`
159
+
160
+ Get current dynamic global properties (head block, supply, etc.)
161
+
162
+ **Example:**
163
+ ```typescript
164
+ const props = await client.getDynamicGlobalProperties();
165
+ console.log('Head block:', props.head_block_number);
166
+ console.log('Last irreversible block:', props.last_irreversible_block_num);
167
+ ```
168
+
169
+ #### `getWitnessSchedule(): Promise<WitnessSchedule>`
170
+
171
+ Get active witness schedule.
172
+
173
+ #### `getHardforkProperties(): Promise<HardforkProperties>`
174
+
175
+ Get hardfork properties and version information.
176
+
177
+ #### `getRewardFunds(): Promise<RewardFund[]>`
178
+
179
+ Get reward fund details.
180
+
181
+ #### `getCurrentPriceFeed(): Promise<PriceFeed>`
182
+
183
+ Get current median price feed.
184
+
185
+ #### `getFeedHistory(): Promise<FeedHistory>`
186
+
187
+ Get price feed history.
188
+
189
+ ### Accounts
190
+
191
+ #### `listAccounts(params: ListAccountsParams): Promise<Account[]>`
192
+
193
+ List accounts by specified order.
194
+
195
+ **Example:**
196
+ ```typescript
197
+ import { ListOrder } from 'zattera-js';
198
+
199
+ const accounts = await client.listAccounts({
200
+ start: null,
201
+ limit: 100,
202
+ order: ListOrder.BY_NAME
203
+ });
204
+ ```
205
+
206
+ #### `findAccounts(params: FindAccountsParams): Promise<Account[]>`
207
+
208
+ Find specific accounts by names.
209
+
210
+ **Example:**
211
+ ```typescript
212
+ const accounts = await client.findAccounts({
213
+ accounts: ['alice', 'bob', 'charlie']
214
+ });
215
+ ```
216
+
217
+ #### `listOwnerHistories(start, limit): Promise<OwnerHistory[]>`
218
+
219
+ List account owner authority change history.
220
+
221
+ #### `findOwnerHistories(owner): Promise<OwnerHistory[]>`
222
+
223
+ Find owner history for specific account.
224
+
225
+ #### `listAccountRecoveryRequests(start, limit, order): Promise<AccountRecoveryRequest[]>`
226
+
227
+ List account recovery requests.
228
+
229
+ #### `findAccountRecoveryRequests(accounts): Promise<AccountRecoveryRequest[]>`
230
+
231
+ Find account recovery requests.
232
+
233
+ #### `listEscrows(start, limit, order): Promise<Escrow[]>`
234
+
235
+ List escrows.
236
+
237
+ #### `findEscrows(from): Promise<Escrow[]>`
238
+
239
+ Find escrows for an account.
240
+
241
+ #### `listVestingDelegations(start, limit, order): Promise<VestingDelegation[]>`
242
+
243
+ List vesting delegations.
244
+
245
+ #### `findVestingDelegations(account): Promise<VestingDelegation[]>`
246
+
247
+ Find vesting delegations for an account.
248
+
249
+ #### `listDollarConversionRequests(start, limit, order): Promise<ConversionRequest[]>`
250
+
251
+ List SBD conversion requests.
252
+
253
+ #### `findDollarConversionRequests(account): Promise<ConversionRequest[]>`
254
+
255
+ Find SBD conversion requests for an account.
256
+
257
+ ### Witnesses
258
+
259
+ #### `listWitnesses(params: ListWitnessesParams): Promise<Witness[]>`
260
+
261
+ List witnesses by specified order.
262
+
263
+ #### `findWitnesses(owners: AccountName[]): Promise<Witness[]>`
264
+
265
+ Find specific witnesses by account names.
266
+
267
+ #### `listWitnessVotes(start, limit, order): Promise<WitnessVote[]>`
268
+
269
+ List witness votes.
270
+
271
+ #### `getActiveWitnesses(): Promise<AccountName[]>`
272
+
273
+ Get currently active witnesses.
274
+
275
+ **Example:**
276
+ ```typescript
277
+ const witnesses = await client.getActiveWitnesses();
278
+ console.log('Active witnesses:', witnesses);
279
+ ```
280
+
281
+ ### Comments & Discussions
282
+
283
+ #### `listComments(start, limit, order): Promise<Comment[]>`
284
+
285
+ List comments by specified order.
286
+
287
+ #### `findComments(comments): Promise<Comment[]>`
288
+
289
+ Find specific comments.
290
+
291
+ #### `listVotes(start, limit, order): Promise<Vote[]>`
292
+
293
+ List votes.
294
+
295
+ #### `findVotes(author, permlink): Promise<Vote[]>`
296
+
297
+ Find specific votes on a post.
298
+
299
+ ### Market
300
+
301
+ #### `listLimitOrders(start, limit, order): Promise<LimitOrder[]>`
302
+
303
+ List limit orders.
304
+
305
+ #### `findLimitOrders(account): Promise<LimitOrder[]>`
306
+
307
+ Find limit orders for an account.
308
+
309
+ #### `getOrderBook(limit?): Promise<OrderBook>`
310
+
311
+ Get current order book.
312
+
313
+ ### Authority & Validation
314
+
315
+ #### `getTransactionHex(trx): Promise<string>`
316
+
317
+ Get transaction as hex string.
318
+
319
+ #### `getRequiredSignatures(trx, availableKeys): Promise<PublicKey[]>`
320
+
321
+ Get required signatures for transaction.
322
+
323
+ #### `getPotentialSignatures(trx): Promise<PublicKey[]>`
324
+
325
+ Get all potential signatures for transaction.
326
+
327
+ #### `verifyAuthority(trx): Promise<VerifyAuthorityResult>`
328
+
329
+ Verify transaction has required authority.
330
+
331
+ #### `verifyAccountAuthority(account, signers): Promise<VerifyAuthorityResult>`
332
+
333
+ Verify account has authority from signers.
334
+
335
+ #### `verifySignatures(hash, signatures, ...): Promise<VerifyAuthorityResult>`
336
+
337
+ Verify arbitrary signatures.
338
+
339
+ ## Network Broadcast API
340
+
341
+ #### `broadcastTransaction(trx, maxBlockAge?): Promise<BroadcastTransactionResult>`
342
+
343
+ Broadcast transaction to the network.
344
+
345
+ **Example:**
346
+ ```typescript
347
+ const result = await client.broadcastTransaction(signedTx);
348
+ console.log('Transaction ID:', result.id);
349
+ console.log('Block number:', result.block_num);
350
+ ```
351
+
352
+ #### `broadcastBlock(block): Promise<void>`
353
+
354
+ Broadcast block to the network.
355
+
356
+ ## Block API
357
+
358
+ #### `getBlockHeader(blockNum): Promise<SignedBlock>`
359
+
360
+ Get block header by block number.
361
+
362
+ #### `getBlock(blockNum): Promise<SignedBlock>`
363
+
364
+ Get full block by block number.
365
+
366
+ **Example:**
367
+ ```typescript
368
+ const block = await client.getBlock(12345);
369
+ console.log('Witness:', block.witness);
370
+ console.log('Transactions:', block.transactions.length);
371
+ ```
372
+
373
+ ## Account History API
374
+
375
+ #### `getOpsInBlock(params): Promise<unknown[]>`
376
+
377
+ Get operations in a specific block.
378
+
379
+ **Example:**
380
+ ```typescript
381
+ const ops = await client.getOpsInBlock({
382
+ block_num: 12345,
383
+ only_virtual: false
384
+ });
385
+ ```
386
+
387
+ #### `getTransaction(id): Promise<GetTransactionResult>`
388
+
389
+ Get transaction by ID.
390
+
391
+ #### `getAccountHistory(params): Promise<Record<number, AccountHistoryEntry>>`
392
+
393
+ Get account operation history.
394
+
395
+ **Example:**
396
+ ```typescript
397
+ const history = await client.getAccountHistory({
398
+ account: 'alice',
399
+ start: -1,
400
+ limit: 100
401
+ });
402
+ ```
403
+
404
+ #### `enumVirtualOps(blockRangeBegin, blockRangeEnd): Promise<unknown[]>`
405
+
406
+ Enumerate virtual operations in block range.
407
+
408
+ ## Tags/Discussion API
409
+
410
+ #### `getTrendingTags(startTag?, limit?): Promise<unknown[]>`
411
+
412
+ Get trending tags.
413
+
414
+ #### `getTagsUsedByAuthor(author): Promise<unknown[]>`
415
+
416
+ Get tags used by author.
417
+
418
+ #### `getDiscussion(author, permlink): Promise<Comment>`
419
+
420
+ Get single discussion/post.
421
+
422
+ **Example:**
423
+ ```typescript
424
+ const post = await client.getDiscussion('alice', 'my-first-post');
425
+ console.log('Title:', post.title);
426
+ console.log('Body:', post.body);
427
+ ```
428
+
429
+ #### `getContentReplies(author, permlink): Promise<Comment[]>`
430
+
431
+ Get replies to a post.
432
+
433
+ #### Discussion Queries
434
+
435
+ All discussion query methods accept a `DiscussionQuery` parameter:
436
+
437
+ ```typescript
438
+ interface DiscussionQuery {
439
+ tag?: string;
440
+ limit?: number;
441
+ filter_tags?: string[];
442
+ select_authors?: AccountName[];
443
+ select_tags?: string[];
444
+ truncate_body?: number;
445
+ start_author?: AccountName;
446
+ start_permlink?: string;
447
+ }
448
+ ```
449
+
450
+ **Methods:**
451
+ - `getDiscussionsByTrending(query): Promise<Comment[]>`
452
+ - `getDiscussionsByCreated(query): Promise<Comment[]>`
453
+ - `getDiscussionsByActive(query): Promise<Comment[]>`
454
+ - `getDiscussionsByCashout(query): Promise<Comment[]>`
455
+ - `getDiscussionsByVotes(query): Promise<Comment[]>`
456
+ - `getDiscussionsByChildren(query): Promise<Comment[]>`
457
+ - `getDiscussionsByHot(query): Promise<Comment[]>`
458
+ - `getDiscussionsByFeed(query): Promise<Comment[]>`
459
+ - `getDiscussionsByBlog(query): Promise<Comment[]>`
460
+ - `getDiscussionsByComments(query): Promise<Comment[]>`
461
+ - `getDiscussionsByPromoted(query): Promise<Comment[]>`
462
+
463
+ **Example:**
464
+ ```typescript
465
+ const trending = await client.getDiscussionsByTrending({
466
+ tag: 'technology',
467
+ limit: 10
468
+ });
469
+ ```
470
+
471
+ #### `getActiveVotes(author, permlink): Promise<ActiveVote[]>`
472
+
473
+ Get active votes on a post.
474
+
475
+ ## Follow API
476
+
477
+ #### `getFollowers(params): Promise<unknown[]>`
478
+
479
+ Get followers of an account.
480
+
481
+ **Example:**
482
+ ```typescript
483
+ const followers = await client.getFollowers({
484
+ account: 'alice',
485
+ start: null,
486
+ type: 'blog',
487
+ limit: 100
488
+ });
489
+ ```
490
+
491
+ #### `getFollowing(params): Promise<unknown[]>`
492
+
493
+ Get accounts that an account is following.
494
+
495
+ #### `getFollowCount(account): Promise<{account, follower_count, following_count}>`
496
+
497
+ Get follower and following counts.
498
+
499
+ #### `getFeedEntries(account, startEntryId?, limit?): Promise<unknown[]>`
500
+
501
+ Get feed entries.
502
+
503
+ #### `getFeed(account, startEntryId?, limit?): Promise<Comment[]>`
504
+
505
+ Get feed with full comments.
506
+
507
+ #### `getBlogEntries(account, startEntryId?, limit?): Promise<unknown[]>`
508
+
509
+ Get blog entries.
510
+
511
+ #### `getBlog(account, startEntryId?, limit?): Promise<Comment[]>`
512
+
513
+ Get blog with full comments.
514
+
515
+ #### `getAccountReputations(accountLowerBound?, limit?): Promise<unknown[]>`
516
+
517
+ Get account reputation scores.
518
+
519
+ #### `getRebloggedBy(author, permlink): Promise<AccountName[]>`
520
+
521
+ Get accounts that reblogged a post.
522
+
523
+ #### `getBlogAuthors(blogAccount): Promise<unknown[]>`
524
+
525
+ Get blog author statistics.
526
+
527
+ ## Market History API
528
+
529
+ #### `getTicker(): Promise<Ticker>`
530
+
531
+ Get market ticker.
532
+
533
+ #### `getVolume(): Promise<Volume>`
534
+
535
+ Get market volume.
536
+
537
+ #### `getMarketOrderBook(limit?): Promise<OrderBook>`
538
+
539
+ Get market order book.
540
+
541
+ #### `getTradeHistory(start, end, limit?): Promise<TradeHistory[]>`
542
+
543
+ Get trade history.
544
+
545
+ #### `getRecentTrades(limit?): Promise<TradeHistory[]>`
546
+
547
+ Get recent trades.
548
+
549
+ #### `getMarketHistory(bucketSeconds, start, end): Promise<MarketHistory[]>`
550
+
551
+ Get market history buckets.
552
+
553
+ #### `getMarketHistoryBuckets(): Promise<Bucket[]>`
554
+
555
+ Get available bucket sizes.
556
+
557
+ ## Account By Key API
558
+
559
+ #### `getKeyReferences(keys): Promise<AccountName[][]>`
560
+
561
+ Get accounts that can sign with given public keys.
562
+
563
+ ## JSON-RPC Meta API
564
+
565
+ #### `getMethods(): Promise<string[]>`
566
+
567
+ Get list of all available RPC methods.
568
+
569
+ #### `getSignature(method): Promise<unknown>`
570
+
571
+ Get signature (parameters and return type) for an RPC method.
572
+
573
+ ## Types
574
+
575
+ The library exports comprehensive TypeScript types for all API methods:
576
+
577
+ ```typescript
578
+ import {
579
+ ZatteraClient,
580
+ Account,
581
+ Witness,
582
+ Comment,
583
+ SignedBlock,
584
+ SignedTransaction,
585
+ DynamicGlobalProperties,
586
+ ListOrder,
587
+ // ... and many more
588
+ } from 'zattera-js';
589
+ ```
590
+
591
+ ## Error Handling
592
+
593
+ The client automatically handles:
594
+ - Network errors with retry logic (exponential backoff)
595
+ - Timeout errors (configurable timeout)
596
+ - JSON-RPC errors (with error codes and messages)
597
+
598
+ ```typescript
599
+ try {
600
+ const result = await client.getBlock(12345);
601
+ } catch (error) {
602
+ console.error('RPC call failed:', error.message);
603
+ }
604
+ ```
605
+
606
+ ## Development
607
+
608
+ ### Setup
609
+
610
+ ```bash
611
+ npm install
612
+ ```
613
+
614
+ ### Build
615
+
616
+ ```bash
617
+ # Build all targets (Node.js + browser + types)
618
+ npm run build
619
+
620
+ # Build Node.js version only
621
+ npm run build:node
622
+
623
+ # Build browser version only
624
+ npm run build:browser
625
+
626
+ # Generate TypeScript declarations
627
+ npm run build:types
628
+
629
+ # Development mode with watch
630
+ npm run dev
631
+ ```
632
+
633
+ ### Testing
634
+
635
+ ```bash
636
+ # Run tests once
637
+ npm test
638
+
639
+ # Watch mode
640
+ npm run test:watch
641
+
642
+ # UI mode
643
+ npm run test:ui
644
+ ```
645
+
646
+ ### Type Checking
647
+
648
+ ```bash
649
+ npm run type-check
650
+ ```
651
+
652
+ ## Project Structure
653
+
654
+ ```
655
+ zattera-js/
656
+ ├── src/
657
+ │ ├── client/ # RPC client implementation
658
+ │ │ ├── index.ts # Client class with all API methods
659
+ │ │ └── index.test.ts # Comprehensive tests
660
+ │ ├── types/ # TypeScript type definitions
661
+ │ │ └── index.ts # All type exports
662
+ │ └── index.ts # Main entry point
663
+ ├── dist/
664
+ │ ├── browser/ # Browser build (bundled & minified)
665
+ │ ├── node/ # Node.js build (preserveModules)
666
+ │ └── types/ # TypeScript declarations
667
+ ├── vite.config.browser.ts # Browser build config
668
+ ├── vite.config.node.ts # Node.js build config
669
+ ├── vitest.config.ts # Test config
670
+ └── tsconfig.json # TypeScript config
671
+ ```
672
+
673
+ ## Requirements
674
+
675
+ - Node.js 18 or higher (for native Fetch API support)
676
+ - Modern browser with Fetch API support
677
+
678
+ ## License
679
+
680
+ MIT - See LICENSE file for details
681
+
682
+ ## Contributing
683
+
684
+ Contributions are welcome! Please ensure:
685
+ 1. All tests pass (`npm test`)
686
+ 2. Code follows TypeScript strict mode
687
+ 3. ESM compatibility is maintained
688
+ 4. Both browser and Node.js builds work
689
+ 5. Update documentation for new features
690
+
691
+ ## Links
692
+
693
+ - [Project Documentation](./CLAUDE.md)
694
+ - [Zattera Protocol](https://github.com/zattera-protocol/zattera)