@gibs/common 1.7.1 → 1.7.3

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/README.md CHANGED
@@ -1,10 +1,600 @@
1
- # Common Gibs utilities
1
+ # Common Utilities
2
2
 
3
- this package holds common gibs utilities that are not necessarily specific to the bridge itself
3
+ A collection of essential blockchain utilities and helpers that provide foundational functionality for decentralized applications. This package contains reusable, blockchain-agnostic tools that are not specific to bridge operations but commonly needed across DeFi applications.
4
4
 
5
- things like
5
+ ## 🎯 Use Cases
6
6
 
7
- 1) client (rpc connection) creation
8
- 1) erc20 metadata loading from chain
9
- 1) serializing json that contains bigints
10
- 1) caching data indefinitely or with a ttl
7
+ ### Primary Use Cases
8
+ - **RPC Client Management**: Create and cache blockchain RPC connections with fallback support
9
+ - **Token Operations**: Load ERC20 token metadata directly from blockchain contracts
10
+ - **Data Serialization**: Handle BigInt serialization in JSON for blockchain data
11
+ - **Performance Optimization**: Cache expensive blockchain calls and computations
12
+ - **Batch Operations**: Execute multiple blockchain calls efficiently using multicall
13
+
14
+ ### Target Applications
15
+ - Multi-chain DeFi applications
16
+ - Blockchain data aggregators
17
+ - Token analytics platforms
18
+ - Wallet backends
19
+ - DApp infrastructure
20
+ - Bridge applications (used by `@gibs/bridge-sdk`)
21
+
22
+ ## 🔧 Core Functionality
23
+
24
+ ### RPC Client Management
25
+ - **Connection Pooling**: Cached RPC clients to avoid duplicate connections
26
+ - **Fallback Support**: Automatic failover between multiple RPC endpoints
27
+ - **WebSocket & HTTP**: Support for both HTTP and WebSocket connections
28
+ - **Batch Configuration**: Optimized batching for better performance
29
+
30
+ ### ERC20 Token Operations
31
+ - **Metadata Loading**: Fetch token name, symbol, decimals from blockchain
32
+ - **Multiple ABI Support**: Handles both standard and bytes32 symbol formats
33
+ - **Caching**: Memoized token calls to reduce redundant blockchain requests
34
+ - **Error Handling**: Graceful fallbacks for non-standard token contracts
35
+
36
+ ### Advanced Caching
37
+ - **TTL Caching**: Time-based cache expiration for data freshness
38
+ - **Size-Limited Caching**: LRU-style caching with maximum entry limits
39
+ - **Serialization Support**: Cache complex objects including BigInt values
40
+ - **Memory Efficient**: Automatic cleanup of expired cache entries
41
+
42
+ ### Multicall Operations
43
+ - **Batch Calls**: Execute multiple contract calls in a single transaction
44
+ - **Gas Optimization**: Reduce gas costs through call aggregation
45
+ - **Type Safety**: Fully typed multicall results
46
+ - **Error Resilience**: Handle partial failures in batch operations
47
+
48
+ ## 📦 Installation
49
+
50
+ ```sh
51
+ npm install @gibs/common
52
+ # or
53
+ yarn add @gibs/common
54
+ ```
55
+
56
+ ## 📖 API Examples
57
+
58
+ ### Client (`@gibs/common/client`)
59
+
60
+ ```typescript
61
+ import {
62
+ clientFromChain,
63
+ chainKey,
64
+ clientCache,
65
+ defaultBatchConfig
66
+ } from '@gibs/common/client'
67
+ import { mainnet, polygon } from 'viem/chains'
68
+
69
+ // Create a cached RPC client with fallback URLs
70
+ const client = clientFromChain({
71
+ chain: mainnet,
72
+ urls: [
73
+ 'https://mainnet.infura.io/v3/your-key',
74
+ 'https://eth-mainnet.g.alchemy.com/v2/your-key'
75
+ ]
76
+ })
77
+
78
+ // Create client with custom batch configuration
79
+ const polygonClient = clientFromChain({
80
+ chain: polygon,
81
+ urls: ['https://polygon-rpc.com']
82
+ })
83
+
84
+ // Generate cache key for debugging
85
+ const key = chainKey(1, ['https://rpc.url']) // "1,https://rpc.url"
86
+ const multiKey = chainKey(137, ['https://rpc1.url', 'https://rpc2.url']) // "137,https://rpc1.url,https://rpc2.url"
87
+
88
+ // Access client cache directly
89
+ const cached = clientCache.get(1) // { key: string, client: PublicClient } | undefined
90
+ console.log(cached?.key) // Cache key used for this client
91
+
92
+ // View default batch configuration
93
+ console.log(defaultBatchConfig)
94
+ // {
95
+ // batch: {
96
+ // wait: 10, // Wait 10ms before batching
97
+ // batchSize: 32, // Maximum 32 calls per batch
98
+ // }
99
+ // }
100
+
101
+ // Clear cache entry
102
+ clientCache.delete(1)
103
+
104
+ // Check cache size
105
+ console.log(clientCache.size) // Number of cached clients
106
+ ```
107
+
108
+ ### ERC20 (`@gibs/common/erc20`)
109
+
110
+ ```typescript
111
+ import { multicallErc20, erc20MetadataCalls } from '@gibs/common/erc20'
112
+ import { mainnet, arbitrum } from 'viem/chains'
113
+
114
+ // Load token metadata (with automatic caching)
115
+ const tokenAddress = '0xA0b86a33E6441e4f4a1b95c0B5a7F1ac03c7B3B0'
116
+ const [name, symbol, decimals] = await multicallErc20({
117
+ client,
118
+ target: tokenAddress,
119
+ chain: mainnet
120
+ })
121
+
122
+ console.log(name) // "Wrapped Ether"
123
+ console.log(symbol) // "WETH"
124
+ console.log(decimals) // 18
125
+
126
+ // Load multiple tokens efficiently
127
+ const tokens = [
128
+ '0xA0b86a33E6441e4f4a1b95c0B5a7F1ac03c7B3B0', // WETH
129
+ '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI
130
+ '0xdAC17F958D2ee523a2206206994597C13D831ec7' // USDT
131
+ ]
132
+
133
+ const tokenMetadata = await Promise.all(
134
+ tokens.map(async (address) => {
135
+ const [name, symbol, decimals] = await multicallErc20({
136
+ client,
137
+ target: address,
138
+ chain: mainnet
139
+ })
140
+ return { name, symbol, decimals, address }
141
+ })
142
+ )
143
+
144
+ // Handle tokens with bytes32 symbols (automatically handled)
145
+ const [usdcName, usdcSymbol, usdcDecimals] = await multicallErc20({
146
+ client,
147
+ target: '0xA0b86a33E6441e4f4a1b95c0B5a7F1ac03c7B3B0',
148
+ chain: mainnet
149
+ }) // Falls back to bytes32 ABI if standard fails
150
+
151
+ // View the standard metadata calls used
152
+ console.log(erc20MetadataCalls)
153
+ // [
154
+ // { functionName: 'name' },
155
+ // { functionName: 'symbol' },
156
+ // { functionName: 'decimals' }
157
+ // ]
158
+ ```
159
+
160
+ ### Serialize (`@gibs/common/serialize`)
161
+
162
+ ```typescript
163
+ import {
164
+ jsonAnyStringify,
165
+ jsonAnyParse,
166
+ isSerializedBigInt
167
+ } from '@gibs/common/serialize'
168
+
169
+ // Serialize data with BigInt values
170
+ const data = {
171
+ balance: 1500000000000000000n, // 1.5 ETH
172
+ user: '0x123...',
173
+ timestamp: Date.now(),
174
+ amounts: [100n, 200n, 300n], // Array with BigInts
175
+ nested: {
176
+ value: 999999999999999999n
177
+ }
178
+ }
179
+
180
+ // Convert to JSON string
181
+ const jsonString = JSON.stringify(data, jsonAnyStringify)
182
+ console.log(jsonString)
183
+ // '{"balance":{"__type__":"bigint","value":"1500000000000000000"},"user":"0x123...","timestamp":1699123456789,"amounts":[{"__type__":"bigint","value":"100"},{"__type__":"bigint","value":"200"},{"__type__":"bigint","value":"300"}],"nested":{"value":{"__type__":"bigint","value":"999999999999999999"}}}'
184
+
185
+ // Parse back to original types
186
+ const parsed = JSON.parse(jsonString, jsonAnyParse)
187
+ console.log(typeof parsed.balance) // "bigint"
188
+ console.log(parsed.balance === 1500000000000000000n) // true
189
+ console.log(parsed.amounts[0] === 100n) // true
190
+
191
+ // Check if value is serialized BigInt
192
+ const serializedValue = { __type__: 'bigint', value: '123' }
193
+ console.log(isSerializedBigInt(serializedValue)) // true
194
+ console.log(isSerializedBigInt({ type: 'bigint', value: '123' })) // false
195
+ console.log(isSerializedBigInt('123')) // false
196
+
197
+ // Use in localStorage/sessionStorage
198
+ const cacheData = { price: 1234567890123456789n, lastUpdate: Date.now() }
199
+ localStorage.setItem('cache', JSON.stringify(cacheData, jsonAnyStringify))
200
+ const restored = JSON.parse(localStorage.getItem('cache')!, jsonAnyParse)
201
+ console.log(typeof restored.price) // "bigint"
202
+ ```
203
+
204
+ ### Cache (`@gibs/common/cache`)
205
+
206
+ ```typescript
207
+ import { maxMemoize, ttlMemoizeSingle } from '@gibs/common/cache'
208
+
209
+ // Size-limited caching (default: 1024 entries)
210
+ const expensiveCalc = maxMemoize((x: number, y: number) => {
211
+ console.log(`Computing ${x} * ${y}...`) // Only logs on cache miss
212
+ return x * y * Math.random()
213
+ }, 100) // Limit to 100 entries
214
+
215
+ console.log(expensiveCalc(5, 10)) // Computes and caches
216
+ console.log(expensiveCalc(5, 10)) // Returns cached result
217
+ console.log(expensiveCalc(3, 7)) // Computes new value
218
+
219
+ // TTL-based caching (default: 1 hour)
220
+ const fetchPrice = ttlMemoizeSingle((symbol: string) => {
221
+ console.log(`Fetching price for ${symbol}...`)
222
+ return fetch(`/api/price/${symbol}`).then(r => r.json())
223
+ }, 30000) // Cache for 30 seconds
224
+
225
+ const ethPrice1 = await fetchPrice('ETH') // Fetches from API
226
+ const ethPrice2 = await fetchPrice('ETH') // Returns cached result (if within 30s)
227
+
228
+ // Advanced caching with BigInt serialization
229
+ const tokenPriceCache = maxMemoize((tokenAddress: string, chainId: number) => {
230
+ console.log(`Loading price for ${tokenAddress} on chain ${chainId}`)
231
+ return {
232
+ price: 1500000000000000000n, // BigInt price
233
+ timestamp: Date.now()
234
+ }
235
+ }, 500)
236
+
237
+ const wethPrice = tokenPriceCache('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', 1)
238
+ console.log(typeof wethPrice.price) // "bigint"
239
+
240
+ // TTL cache with complex return types
241
+ const getBlockInfo = ttlMemoizeSingle(async (blockNumber: bigint) => {
242
+ return {
243
+ number: blockNumber,
244
+ timestamp: BigInt(Date.now()),
245
+ hash: '0x...',
246
+ gasUsed: 21000n
247
+ }
248
+ }, 15000) // Cache for 15 seconds
249
+
250
+ const block = await getBlockInfo(18500000n)
251
+ console.log(typeof block.number) // "bigint"
252
+ ```
253
+
254
+ ### Multicall (`@gibs/common/multicall`)
255
+
256
+ ```typescript
257
+ import { multicallRead } from '@gibs/common/multicall'
258
+ import { erc20Abi } from 'viem'
259
+
260
+ // Basic multicall - batch multiple contract calls efficiently
261
+ const calls = [
262
+ { functionName: 'balanceOf', args: ['0x123...'] },
263
+ { functionName: 'allowance', args: ['0x123...', '0x456...'] },
264
+ { functionName: 'totalSupply', args: [] }
265
+ ]
266
+
267
+ const results = await multicallRead({
268
+ client,
269
+ chain: mainnet,
270
+ abi: erc20Abi,
271
+ target: '0xA0b86a33E6441e4f4a1b95c0B5a7F1ac03c7B3B0', // WETH
272
+ calls
273
+ })
274
+
275
+ const [balance, allowance, totalSupply] = results
276
+ console.log('Balance:', balance) // bigint
277
+ console.log('Allowance:', allowance) // bigint
278
+ console.log('Total Supply:', totalSupply) // bigint
279
+
280
+ // Advanced multicall with different targets and ABIs
281
+ const mixedCalls = [
282
+ {
283
+ functionName: 'balanceOf',
284
+ args: ['0x123...'],
285
+ target: '0xA0b86a33E6441e4f4a1b95c0B5a7F1ac03c7B3B0', // WETH
286
+ abi: erc20Abi
287
+ },
288
+ {
289
+ functionName: 'balanceOf',
290
+ args: ['0x123...'],
291
+ target: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI
292
+ abi: erc20Abi
293
+ },
294
+ {
295
+ functionName: 'name',
296
+ args: [],
297
+ target: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT
298
+ abi: erc20Abi
299
+ }
300
+ ]
301
+
302
+ const mixedResults = await multicallRead({
303
+ client,
304
+ chain: mainnet,
305
+ abi: erc20Abi, // Default ABI
306
+ calls: mixedCalls
307
+ })
308
+
309
+ const [wethBalance, daiBalance, usdtName] = mixedResults
310
+
311
+ // Multicall with failure handling
312
+ const riskyCalls = [
313
+ {
314
+ functionName: 'balanceOf',
315
+ args: ['0x123...'],
316
+ target: '0xValidToken...',
317
+ allowFailure: false // Will throw if this fails
318
+ },
319
+ {
320
+ functionName: 'balanceOf',
321
+ args: ['0x123...'],
322
+ target: '0xMaybeInvalidToken...',
323
+ allowFailure: true // Will return error object instead of throwing
324
+ }
325
+ ]
326
+
327
+ const riskyResults = await multicallRead({
328
+ client,
329
+ chain: mainnet,
330
+ abi: erc20Abi,
331
+ calls: riskyCalls
332
+ })
333
+
334
+ // riskyResults[1] might be an error object if the call failed
335
+ ```
336
+
337
+ ### Types (`@gibs/common/types`)
338
+
339
+ ```typescript
340
+ import type { Erc20Metadata, Call } from '@gibs/common/types'
341
+
342
+ // ERC20 token metadata structure (returned by multicallErc20)
343
+ const tokenMetadata: Erc20Metadata = ['Wrapped Ether', 'WETH', 18]
344
+ const [name, symbol, decimals] = tokenMetadata
345
+ console.log(`${name} (${symbol}) has ${decimals} decimals`)
346
+
347
+ // Multicall call configuration
348
+ const balanceCall: Call = {
349
+ functionName: 'balanceOf',
350
+ args: ['0x123...'],
351
+ target: '0xTokenAddress...',
352
+ abi: erc20Abi,
353
+ allowFailure: false
354
+ }
355
+
356
+ const nameCall: Call = {
357
+ functionName: 'name',
358
+ args: [],
359
+ // target and abi will be inherited from multicallRead params
360
+ allowFailure: true
361
+ }
362
+
363
+ // Use in function signatures
364
+ function processTokenMetadata(metadata: Erc20Metadata) {
365
+ const [name, symbol, decimals] = metadata
366
+ console.log(`Processing ${symbol} (${name}) with ${decimals} decimals`)
367
+ return {
368
+ displayName: `${name} (${symbol})`,
369
+ precision: decimals,
370
+ isStablecoin: name.toLowerCase().includes('usd')
371
+ }
372
+ }
373
+
374
+ function buildMulticall(calls: Call[]) {
375
+ return multicallRead({
376
+ client,
377
+ chain: mainnet,
378
+ abi: erc20Abi,
379
+ calls
380
+ })
381
+ }
382
+
383
+ // Advanced Call configurations
384
+ const complexCalls: Call[] = [
385
+ {
386
+ functionName: 'getReserves',
387
+ args: [],
388
+ target: '0xPairAddress...',
389
+ abi: pairAbi,
390
+ allowFailure: false
391
+ },
392
+ {
393
+ functionName: 'token0',
394
+ args: [],
395
+ target: '0xPairAddress...',
396
+ abi: pairAbi,
397
+ allowFailure: false
398
+ },
399
+ {
400
+ functionName: 'token1',
401
+ args: [],
402
+ target: '0xPairAddress...',
403
+ abi: pairAbi,
404
+ allowFailure: false
405
+ }
406
+ ]
407
+ ```
408
+
409
+ ## 🔧 Configuration
410
+
411
+ ### Default Batch Configuration
412
+ ```typescript
413
+ import { defaultBatchConfig } from '@gibs/common/client'
414
+
415
+ console.log(defaultBatchConfig)
416
+ // {
417
+ // batch: {
418
+ // wait: 10, // Wait 10ms before batching
419
+ // batchSize: 32, // Maximum 32 calls per batch
420
+ // }
421
+ // }
422
+
423
+ // This configuration is automatically applied to all HTTP transports
424
+ // WebSocket transports get additional configuration:
425
+ // {
426
+ // keepAlive: true,
427
+ // reconnect: true,
428
+ // retryDelay: 250,
429
+ // retryCount: 10,
430
+ // timeout: 4000,
431
+ // ...defaultBatchConfig
432
+ // }
433
+ ```
434
+
435
+ ## 📋 API Reference
436
+
437
+ ### Exports
438
+
439
+ | Export Path | Description |
440
+ |-------------|-------------|
441
+ | `@gibs/common` | Main entry point with all exports |
442
+ | `@gibs/common/client` | RPC client creation and management |
443
+ | `@gibs/common/erc20` | ERC20 token metadata utilities |
444
+ | `@gibs/common/cache` | Caching and memoization functions |
445
+ | `@gibs/common/serialize` | JSON serialization with BigInt support |
446
+ | `@gibs/common/multicall` | Batch contract call utilities |
447
+ | `@gibs/common/types` | TypeScript type definitions |
448
+
449
+ ### Key Functions
450
+
451
+ #### Client Management
452
+ ```typescript
453
+ // Create cached RPC client with fallback support
454
+ function clientFromChain(params: {
455
+ chain: Chain
456
+ urls: string[]
457
+ }): PublicClient
458
+
459
+ // Generate cache key for client identification
460
+ function chainKey(chainId: number, urls: string[]): string
461
+
462
+ // Client cache Map
463
+ const clientCache: Map<number, { key: string, client: PublicClient }>
464
+ ```
465
+
466
+ #### ERC20 Operations
467
+ ```typescript
468
+ // Load ERC20 metadata with caching and fallback ABIs
469
+ function multicallErc20(params: {
470
+ client: PublicClient
471
+ target: Hex
472
+ chain: Chain
473
+ }): Promise<[string, string, number]> // [name, symbol, decimals]
474
+
475
+ // Standard ERC20 metadata calls
476
+ const erc20MetadataCalls: readonly [
477
+ { functionName: 'name' },
478
+ { functionName: 'symbol' },
479
+ { functionName: 'decimals' }
480
+ ]
481
+ ```
482
+
483
+ #### Caching
484
+ ```typescript
485
+ // Size-limited memoization
486
+ function maxMemoize<A extends unknown[], B>(
487
+ fn: (...a: A) => B,
488
+ max?: number
489
+ ): (...a: A) => B
490
+
491
+ // TTL-based single value caching
492
+ function ttlMemoizeSingle<A extends unknown[], B>(
493
+ fn: (...a: A) => B,
494
+ ttl?: number
495
+ ): (...a: A) => B
496
+ ```
497
+
498
+ #### Serialization
499
+ ```typescript
500
+ // JSON replacer for BigInt serialization
501
+ function jsonAnyStringify(key: string, value: any): any
502
+
503
+ // JSON reviver for BigInt deserialization
504
+ function jsonAnyParse(key: string, value: any): any
505
+
506
+ // Type guard for serialized BigInt values
507
+ function isSerializedBigInt(value: unknown): value is SerializedBigInt
508
+ ```
509
+
510
+ #### Multicall
511
+ ```typescript
512
+ // Execute multiple contract calls in a single transaction
513
+ function multicallRead<T = readonly unknown[]>(params: {
514
+ client: PublicClient
515
+ chain: Chain
516
+ abi: Abi
517
+ target: Hex
518
+ calls: readonly unknown[]
519
+ }): Promise<T>
520
+ ```
521
+
522
+ ### Key Types
523
+
524
+ ```typescript
525
+ // ERC20 token metadata tuple
526
+ type Erc20Metadata = [string, string, number] // [name, symbol, decimals]
527
+
528
+ // Multicall call configuration
529
+ interface Call {
530
+ functionName: string
531
+ args?: (bigint | Hex | Hex[] | bigint[] | string | string[])[]
532
+ target?: Hex // Override default target
533
+ abi?: Abi // Override default ABI
534
+ allowFailure?: boolean // Default: false
535
+ }
536
+
537
+ // Serialized BigInt structure
538
+ interface SerializedBigInt {
539
+ __type__: 'bigint'
540
+ value: string
541
+ }
542
+ ```
543
+
544
+ ## ⚡ Performance Features
545
+
546
+ ### Client Caching
547
+ - RPC clients are cached by chain ID and URL combination
548
+ - Prevents unnecessary connection overhead
549
+ - Automatic cache invalidation when URLs change
550
+
551
+ ### Request Optimization
552
+ - Batch configuration reduces RPC call frequency
553
+ - Fallback RPC URLs provide reliability
554
+ - WebSocket connections for real-time data when available
555
+
556
+ ### Memory Management
557
+ - Size-limited caches prevent memory leaks
558
+ - TTL caches automatically expire stale data
559
+ - Efficient cache key generation for complex objects
560
+
561
+ ## 🔗 Dependencies
562
+
563
+ - `viem`: Type-safe Ethereum library for blockchain interactions
564
+ - `lodash`: Utility functions for data manipulation and memoization
565
+
566
+ ## 📝 Best Practices
567
+
568
+ ### Client Management
569
+ ```typescript
570
+ // ✅ Good: Reuse clients with consistent URLs
571
+ const client = clientFromChain({ chain: mainnet, urls: rpcUrls })
572
+
573
+ // ❌ Avoid: Creating new clients with different URL arrays each time
574
+ const client1 = clientFromChain({ chain: mainnet, urls: [url1, url2] })
575
+ const client2 = clientFromChain({ chain: mainnet, urls: [url2, url1] }) // Different cache key!
576
+ ```
577
+
578
+ ### Caching Strategy
579
+ ```typescript
580
+ // ✅ Good: Use appropriate cache types for your use case
581
+ const tokenMetadata = maxMemoize(fetchTokenMetadata, 500) // Bounded cache
582
+ const priceData = ttlMemoizeSingle(fetchPrices, 30000) // 30-second TTL
583
+
584
+ // ✅ Good: Cache expensive computations, not simple operations
585
+ const expensiveCalc = maxMemoize(heavyComputation)
586
+ const simpleCalc = (a, b) => a + b // Don't cache simple operations
587
+ ```
588
+
589
+ ### Error Handling
590
+ ```typescript
591
+ // ✅ Good: Handle multicall failures gracefully
592
+ try {
593
+ const results = await multicallRead({ ... })
594
+ } catch (error) {
595
+ console.warn('Multicall failed, falling back to individual calls')
596
+ // Implement fallback logic
597
+ }
598
+ ```
599
+
600
+ This package provides the foundation for robust, efficient blockchain applications by handling common infrastructure concerns so you can focus on your application logic.
@@ -1,15 +1,29 @@
1
1
  import { type Chain, type PublicClient } from "viem";
2
+ /** The default batch config for the client */
2
3
  export declare const defaultBatchConfig: {
3
4
  batch: {
4
5
  wait: number;
5
6
  batchSize: number;
6
7
  };
7
8
  };
9
+ /**
10
+ * Returns the chain key for the given chain id and urls
11
+ * @param chainId - the chain id
12
+ * @param urls - the urls
13
+ * @returns the chain key
14
+ */
8
15
  export declare const chainKey: (chainId: number, urls: string[]) => string;
16
+ /** The client cache for the given chain id */
9
17
  export declare const clientCache: Map<number, {
10
18
  key: string;
11
19
  client: PublicClient;
12
20
  }>;
21
+ /**
22
+ * Returns the client for the given chain and urls
23
+ * @param chain - the chain
24
+ * @param urls - the urls
25
+ * @returns the client
26
+ */
13
27
  export declare const clientFromChain: ({ chain, urls, }: {
14
28
  chain: Chain;
15
29
  urls: string[];
@@ -1,14 +1,28 @@
1
1
  import { createPublicClient, fallback, http, webSocket } from "viem";
2
+ /** The default batch config for the client */
2
3
  export const defaultBatchConfig = {
3
4
  batch: {
4
5
  wait: 10,
5
6
  batchSize: 32,
6
7
  },
7
8
  };
9
+ /**
10
+ * Returns the chain key for the given chain id and urls
11
+ * @param chainId - the chain id
12
+ * @param urls - the urls
13
+ * @returns the chain key
14
+ */
8
15
  export const chainKey = (chainId, urls) => {
9
16
  return `${chainId},${urls.join(',')}`.toLowerCase();
10
17
  };
18
+ /** The client cache for the given chain id */
11
19
  export const clientCache = new Map();
20
+ /**
21
+ * Returns the client for the given chain and urls
22
+ * @param chain - the chain
23
+ * @param urls - the urls
24
+ * @returns the client
25
+ */
12
26
  export const clientFromChain = ({ chain, urls, }) => {
13
27
  const key = chainKey(chain.id, urls);
14
28
  const existing = clientCache.get(chain.id);
@@ -1,9 +1,11 @@
1
1
  import { type Chain, type PublicClient, type Hex } from 'viem';
2
2
  import _ from 'lodash';
3
3
  import type { Erc20Metadata } from './types.js';
4
+ /** The erc20 metadata calls */
4
5
  export declare const erc20MetadataCalls: {
5
6
  functionName: string;
6
7
  }[];
8
+ /** The multicall for the erc20 metadata */
7
9
  export declare const multicallErc20: (({ client, target, chain }: {
8
10
  client: PublicClient;
9
11
  target: Hex;
package/dist/src/erc20.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import { erc20Abi, erc20Abi_bytes32, getAddress, } from 'viem';
2
2
  import _ from 'lodash';
3
3
  import { multicallRead } from './multicall.js';
4
+ /** The erc20 metadata calls */
4
5
  export const erc20MetadataCalls = [
5
6
  { functionName: 'name' },
6
7
  { functionName: 'symbol' },
7
8
  { functionName: 'decimals' },
8
9
  ];
10
+ /** The multicall for the erc20 metadata */
9
11
  export const multicallErc20 = _.memoize(async ({ client, target, chain }) => {
10
12
  const options = {
11
13
  chain: chain,
@@ -3,3 +3,4 @@ export * from './serialize.js';
3
3
  export * from './cache.js';
4
4
  export * from './multicall.js';
5
5
  export * from './erc20.js';
6
+ export * from './client.js';
package/dist/src/index.js CHANGED
@@ -3,3 +3,4 @@ export * from './serialize.js';
3
3
  export * from './cache.js';
4
4
  export * from './multicall.js';
5
5
  export * from './erc20.js';
6
+ export * from './client.js';