@lombard.finance/sdk-agentkit 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.
package/dist/index.js ADDED
@@ -0,0 +1,3719 @@
1
+ import 'reflect-metadata';
2
+ import { CreateAction, EvmWalletProvider, ActionProvider } from '@coinbase/agentkit';
3
+ import { ChainId, CHAIN_ID_TO_VIEM_CHAIN_MAP, makePublicClient, getTokenContractInfo, getAssetRouterAddress, Token, getTokenAllowance, approveToken, depositToken, unstakeLBTC, redeemToken, depositEarn, getDepositsByAddress, getDepositStatus, getDepositStatusDisplay, claimLBTC, getLBTCExchangeRate, fromSatoshi, getUnstakesByAddress, requiresAutoMintFee, getNetworkFeeSignature, getLBTCMintingFee, signNetworkFee, storeNetworkFeeSignature } from '@lombard.finance/sdk';
4
+ import { z } from 'zod';
5
+ import { Env } from '@lombard.finance/sdk-common';
6
+ import { formatUnits as formatUnits$1 } from 'viem';
7
+
8
+ function defineChain(chain) {
9
+ const chainInstance = {
10
+ formatters: undefined,
11
+ fees: undefined,
12
+ serializers: undefined,
13
+ ...chain,
14
+ };
15
+ function extend(base) {
16
+ return (fnOrExtended) => {
17
+ const properties = (typeof fnOrExtended === 'function' ? fnOrExtended(base) : fnOrExtended);
18
+ const combined = { ...base, ...properties };
19
+ return Object.assign(combined, { extend: extend(combined) });
20
+ };
21
+ }
22
+ return Object.assign(chainInstance, {
23
+ extend: extend(chainInstance),
24
+ });
25
+ }
26
+
27
+ const version = '2.47.6';
28
+
29
+ let errorConfig = {
30
+ getDocsUrl: ({ docsBaseUrl, docsPath = '', docsSlug, }) => docsPath
31
+ ? `${docsBaseUrl ?? 'https://viem.sh'}${docsPath}${docsSlug ? `#${docsSlug}` : ''}`
32
+ : undefined,
33
+ version: `viem@${version}`,
34
+ };
35
+ class BaseError extends Error {
36
+ constructor(shortMessage, args = {}) {
37
+ const details = (() => {
38
+ if (args.cause instanceof BaseError)
39
+ return args.cause.details;
40
+ if (args.cause?.message)
41
+ return args.cause.message;
42
+ return args.details;
43
+ })();
44
+ const docsPath = (() => {
45
+ if (args.cause instanceof BaseError)
46
+ return args.cause.docsPath || args.docsPath;
47
+ return args.docsPath;
48
+ })();
49
+ const docsUrl = errorConfig.getDocsUrl?.({ ...args, docsPath });
50
+ const message = [
51
+ shortMessage || 'An error occurred.',
52
+ '',
53
+ ...(args.metaMessages ? [...args.metaMessages, ''] : []),
54
+ ...(docsUrl ? [`Docs: ${docsUrl}`] : []),
55
+ ...(details ? [`Details: ${details}`] : []),
56
+ ...(errorConfig.version ? [`Version: ${errorConfig.version}`] : []),
57
+ ].join('\n');
58
+ super(message, args.cause ? { cause: args.cause } : undefined);
59
+ Object.defineProperty(this, "details", {
60
+ enumerable: true,
61
+ configurable: true,
62
+ writable: true,
63
+ value: void 0
64
+ });
65
+ Object.defineProperty(this, "docsPath", {
66
+ enumerable: true,
67
+ configurable: true,
68
+ writable: true,
69
+ value: void 0
70
+ });
71
+ Object.defineProperty(this, "metaMessages", {
72
+ enumerable: true,
73
+ configurable: true,
74
+ writable: true,
75
+ value: void 0
76
+ });
77
+ Object.defineProperty(this, "shortMessage", {
78
+ enumerable: true,
79
+ configurable: true,
80
+ writable: true,
81
+ value: void 0
82
+ });
83
+ Object.defineProperty(this, "version", {
84
+ enumerable: true,
85
+ configurable: true,
86
+ writable: true,
87
+ value: void 0
88
+ });
89
+ Object.defineProperty(this, "name", {
90
+ enumerable: true,
91
+ configurable: true,
92
+ writable: true,
93
+ value: 'BaseError'
94
+ });
95
+ this.details = details;
96
+ this.docsPath = docsPath;
97
+ this.metaMessages = args.metaMessages;
98
+ this.name = args.name ?? this.name;
99
+ this.shortMessage = shortMessage;
100
+ this.version = version;
101
+ }
102
+ walk(fn) {
103
+ return walk(this, fn);
104
+ }
105
+ }
106
+ function walk(err, fn) {
107
+ if (fn?.(err))
108
+ return err;
109
+ if (err &&
110
+ typeof err === 'object' &&
111
+ 'cause' in err &&
112
+ err.cause !== undefined)
113
+ return walk(err.cause, fn);
114
+ return fn ? null : err;
115
+ }
116
+
117
+ class IntegerOutOfRangeError extends BaseError {
118
+ constructor({ max, min, signed, size, value, }) {
119
+ super(`Number "${value}" is not in safe ${size ? `${size * 8}-bit ${signed ? 'signed' : 'unsigned'} ` : ''}integer range ${max ? `(${min} to ${max})` : `(above ${min})`}`, { name: 'IntegerOutOfRangeError' });
120
+ }
121
+ }
122
+ class SizeOverflowError extends BaseError {
123
+ constructor({ givenSize, maxSize }) {
124
+ super(`Size cannot exceed ${maxSize} bytes. Given size: ${givenSize} bytes.`, { name: 'SizeOverflowError' });
125
+ }
126
+ }
127
+
128
+ function isHex(value, { strict = true } = {}) {
129
+ if (!value)
130
+ return false;
131
+ if (typeof value !== 'string')
132
+ return false;
133
+ return strict ? /^0x[0-9a-fA-F]*$/.test(value) : value.startsWith('0x');
134
+ }
135
+
136
+ /**
137
+ * @description Retrieves the size of the value (in bytes).
138
+ *
139
+ * @param value The value (hex or byte array) to retrieve the size of.
140
+ * @returns The size of the value (in bytes).
141
+ */
142
+ function size(value) {
143
+ if (isHex(value, { strict: false }))
144
+ return Math.ceil((value.length - 2) / 2);
145
+ return value.length;
146
+ }
147
+
148
+ function trim(hexOrBytes, { dir = 'left' } = {}) {
149
+ let data = typeof hexOrBytes === 'string' ? hexOrBytes.replace('0x', '') : hexOrBytes;
150
+ let sliceLength = 0;
151
+ for (let i = 0; i < data.length - 1; i++) {
152
+ if (data[dir === 'left' ? i : data.length - i - 1].toString() === '0')
153
+ sliceLength++;
154
+ else
155
+ break;
156
+ }
157
+ data =
158
+ dir === 'left'
159
+ ? data.slice(sliceLength)
160
+ : data.slice(0, data.length - sliceLength);
161
+ if (typeof hexOrBytes === 'string') {
162
+ if (data.length === 1 && dir === 'right')
163
+ data = `${data}0`;
164
+ return `0x${data.length % 2 === 1 ? `0${data}` : data}`;
165
+ }
166
+ return data;
167
+ }
168
+
169
+ class SliceOffsetOutOfBoundsError extends BaseError {
170
+ constructor({ offset, position, size, }) {
171
+ super(`Slice ${position === 'start' ? 'starting' : 'ending'} at offset "${offset}" is out-of-bounds (size: ${size}).`, { name: 'SliceOffsetOutOfBoundsError' });
172
+ }
173
+ }
174
+ class SizeExceedsPaddingSizeError extends BaseError {
175
+ constructor({ size, targetSize, type, }) {
176
+ super(`${type.charAt(0).toUpperCase()}${type
177
+ .slice(1)
178
+ .toLowerCase()} size (${size}) exceeds padding size (${targetSize}).`, { name: 'SizeExceedsPaddingSizeError' });
179
+ }
180
+ }
181
+
182
+ function pad(hexOrBytes, { dir, size = 32 } = {}) {
183
+ if (typeof hexOrBytes === 'string')
184
+ return padHex(hexOrBytes, { dir, size });
185
+ return padBytes(hexOrBytes, { dir, size });
186
+ }
187
+ function padHex(hex_, { dir, size = 32 } = {}) {
188
+ if (size === null)
189
+ return hex_;
190
+ const hex = hex_.replace('0x', '');
191
+ if (hex.length > size * 2)
192
+ throw new SizeExceedsPaddingSizeError({
193
+ size: Math.ceil(hex.length / 2),
194
+ targetSize: size,
195
+ type: 'hex',
196
+ });
197
+ return `0x${hex[dir === 'right' ? 'padEnd' : 'padStart'](size * 2, '0')}`;
198
+ }
199
+ function padBytes(bytes, { dir, size = 32 } = {}) {
200
+ if (size === null)
201
+ return bytes;
202
+ if (bytes.length > size)
203
+ throw new SizeExceedsPaddingSizeError({
204
+ size: bytes.length,
205
+ targetSize: size,
206
+ type: 'bytes',
207
+ });
208
+ const paddedBytes = new Uint8Array(size);
209
+ for (let i = 0; i < size; i++) {
210
+ const padEnd = dir === 'right';
211
+ paddedBytes[padEnd ? i : size - i - 1] =
212
+ bytes[padEnd ? i : bytes.length - i - 1];
213
+ }
214
+ return paddedBytes;
215
+ }
216
+
217
+ const hexes = /*#__PURE__*/ Array.from({ length: 256 }, (_v, i) => i.toString(16).padStart(2, '0'));
218
+ /**
219
+ * Encodes a string, number, bigint, or ByteArray into a hex string
220
+ *
221
+ * - Docs: https://viem.sh/docs/utilities/toHex
222
+ * - Example: https://viem.sh/docs/utilities/toHex#usage
223
+ *
224
+ * @param value Value to encode.
225
+ * @param opts Options.
226
+ * @returns Hex value.
227
+ *
228
+ * @example
229
+ * import { toHex } from 'viem'
230
+ * const data = toHex('Hello world')
231
+ * // '0x48656c6c6f20776f726c6421'
232
+ *
233
+ * @example
234
+ * import { toHex } from 'viem'
235
+ * const data = toHex(420)
236
+ * // '0x1a4'
237
+ *
238
+ * @example
239
+ * import { toHex } from 'viem'
240
+ * const data = toHex('Hello world', { size: 32 })
241
+ * // '0x48656c6c6f20776f726c64210000000000000000000000000000000000000000'
242
+ */
243
+ function toHex(value, opts = {}) {
244
+ if (typeof value === 'number' || typeof value === 'bigint')
245
+ return numberToHex(value, opts);
246
+ if (typeof value === 'string') {
247
+ return stringToHex(value, opts);
248
+ }
249
+ if (typeof value === 'boolean')
250
+ return boolToHex(value, opts);
251
+ return bytesToHex(value, opts);
252
+ }
253
+ /**
254
+ * Encodes a boolean into a hex string
255
+ *
256
+ * - Docs: https://viem.sh/docs/utilities/toHex#booltohex
257
+ *
258
+ * @param value Value to encode.
259
+ * @param opts Options.
260
+ * @returns Hex value.
261
+ *
262
+ * @example
263
+ * import { boolToHex } from 'viem'
264
+ * const data = boolToHex(true)
265
+ * // '0x1'
266
+ *
267
+ * @example
268
+ * import { boolToHex } from 'viem'
269
+ * const data = boolToHex(false)
270
+ * // '0x0'
271
+ *
272
+ * @example
273
+ * import { boolToHex } from 'viem'
274
+ * const data = boolToHex(true, { size: 32 })
275
+ * // '0x0000000000000000000000000000000000000000000000000000000000000001'
276
+ */
277
+ function boolToHex(value, opts = {}) {
278
+ const hex = `0x${Number(value)}`;
279
+ if (typeof opts.size === 'number') {
280
+ assertSize(hex, { size: opts.size });
281
+ return pad(hex, { size: opts.size });
282
+ }
283
+ return hex;
284
+ }
285
+ /**
286
+ * Encodes a bytes array into a hex string
287
+ *
288
+ * - Docs: https://viem.sh/docs/utilities/toHex#bytestohex
289
+ *
290
+ * @param value Value to encode.
291
+ * @param opts Options.
292
+ * @returns Hex value.
293
+ *
294
+ * @example
295
+ * import { bytesToHex } from 'viem'
296
+ * const data = bytesToHex(Uint8Array.from([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
297
+ * // '0x48656c6c6f20576f726c6421'
298
+ *
299
+ * @example
300
+ * import { bytesToHex } from 'viem'
301
+ * const data = bytesToHex(Uint8Array.from([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]), { size: 32 })
302
+ * // '0x48656c6c6f20576f726c64210000000000000000000000000000000000000000'
303
+ */
304
+ function bytesToHex(value, opts = {}) {
305
+ let string = '';
306
+ for (let i = 0; i < value.length; i++) {
307
+ string += hexes[value[i]];
308
+ }
309
+ const hex = `0x${string}`;
310
+ if (typeof opts.size === 'number') {
311
+ assertSize(hex, { size: opts.size });
312
+ return pad(hex, { dir: 'right', size: opts.size });
313
+ }
314
+ return hex;
315
+ }
316
+ /**
317
+ * Encodes a number or bigint into a hex string
318
+ *
319
+ * - Docs: https://viem.sh/docs/utilities/toHex#numbertohex
320
+ *
321
+ * @param value Value to encode.
322
+ * @param opts Options.
323
+ * @returns Hex value.
324
+ *
325
+ * @example
326
+ * import { numberToHex } from 'viem'
327
+ * const data = numberToHex(420)
328
+ * // '0x1a4'
329
+ *
330
+ * @example
331
+ * import { numberToHex } from 'viem'
332
+ * const data = numberToHex(420, { size: 32 })
333
+ * // '0x00000000000000000000000000000000000000000000000000000000000001a4'
334
+ */
335
+ function numberToHex(value_, opts = {}) {
336
+ const { signed, size } = opts;
337
+ const value = BigInt(value_);
338
+ let maxValue;
339
+ if (size) {
340
+ if (signed)
341
+ maxValue = (1n << (BigInt(size) * 8n - 1n)) - 1n;
342
+ else
343
+ maxValue = 2n ** (BigInt(size) * 8n) - 1n;
344
+ }
345
+ else if (typeof value_ === 'number') {
346
+ maxValue = BigInt(Number.MAX_SAFE_INTEGER);
347
+ }
348
+ const minValue = typeof maxValue === 'bigint' && signed ? -maxValue - 1n : 0;
349
+ if ((maxValue && value > maxValue) || value < minValue) {
350
+ const suffix = typeof value_ === 'bigint' ? 'n' : '';
351
+ throw new IntegerOutOfRangeError({
352
+ max: maxValue ? `${maxValue}${suffix}` : undefined,
353
+ min: `${minValue}${suffix}`,
354
+ signed,
355
+ size,
356
+ value: `${value_}${suffix}`,
357
+ });
358
+ }
359
+ const hex = `0x${(signed && value < 0 ? (1n << BigInt(size * 8)) + BigInt(value) : value).toString(16)}`;
360
+ if (size)
361
+ return pad(hex, { size });
362
+ return hex;
363
+ }
364
+ const encoder$1 = /*#__PURE__*/ new TextEncoder();
365
+ /**
366
+ * Encodes a UTF-8 string into a hex string
367
+ *
368
+ * - Docs: https://viem.sh/docs/utilities/toHex#stringtohex
369
+ *
370
+ * @param value Value to encode.
371
+ * @param opts Options.
372
+ * @returns Hex value.
373
+ *
374
+ * @example
375
+ * import { stringToHex } from 'viem'
376
+ * const data = stringToHex('Hello World!')
377
+ * // '0x48656c6c6f20576f726c6421'
378
+ *
379
+ * @example
380
+ * import { stringToHex } from 'viem'
381
+ * const data = stringToHex('Hello World!', { size: 32 })
382
+ * // '0x48656c6c6f20576f726c64210000000000000000000000000000000000000000'
383
+ */
384
+ function stringToHex(value_, opts = {}) {
385
+ const value = encoder$1.encode(value_);
386
+ return bytesToHex(value, opts);
387
+ }
388
+
389
+ const encoder = /*#__PURE__*/ new TextEncoder();
390
+ /**
391
+ * Encodes a UTF-8 string, hex value, bigint, number or boolean to a byte array.
392
+ *
393
+ * - Docs: https://viem.sh/docs/utilities/toBytes
394
+ * - Example: https://viem.sh/docs/utilities/toBytes#usage
395
+ *
396
+ * @param value Value to encode.
397
+ * @param opts Options.
398
+ * @returns Byte array value.
399
+ *
400
+ * @example
401
+ * import { toBytes } from 'viem'
402
+ * const data = toBytes('Hello world')
403
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
404
+ *
405
+ * @example
406
+ * import { toBytes } from 'viem'
407
+ * const data = toBytes(420)
408
+ * // Uint8Array([1, 164])
409
+ *
410
+ * @example
411
+ * import { toBytes } from 'viem'
412
+ * const data = toBytes(420, { size: 4 })
413
+ * // Uint8Array([0, 0, 1, 164])
414
+ */
415
+ function toBytes$1(value, opts = {}) {
416
+ if (typeof value === 'number' || typeof value === 'bigint')
417
+ return numberToBytes(value, opts);
418
+ if (typeof value === 'boolean')
419
+ return boolToBytes(value, opts);
420
+ if (isHex(value))
421
+ return hexToBytes(value, opts);
422
+ return stringToBytes(value, opts);
423
+ }
424
+ /**
425
+ * Encodes a boolean into a byte array.
426
+ *
427
+ * - Docs: https://viem.sh/docs/utilities/toBytes#booltobytes
428
+ *
429
+ * @param value Boolean value to encode.
430
+ * @param opts Options.
431
+ * @returns Byte array value.
432
+ *
433
+ * @example
434
+ * import { boolToBytes } from 'viem'
435
+ * const data = boolToBytes(true)
436
+ * // Uint8Array([1])
437
+ *
438
+ * @example
439
+ * import { boolToBytes } from 'viem'
440
+ * const data = boolToBytes(true, { size: 32 })
441
+ * // Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
442
+ */
443
+ function boolToBytes(value, opts = {}) {
444
+ const bytes = new Uint8Array(1);
445
+ bytes[0] = Number(value);
446
+ if (typeof opts.size === 'number') {
447
+ assertSize(bytes, { size: opts.size });
448
+ return pad(bytes, { size: opts.size });
449
+ }
450
+ return bytes;
451
+ }
452
+ // We use very optimized technique to convert hex string to byte array
453
+ const charCodeMap = {
454
+ zero: 48,
455
+ nine: 57,
456
+ A: 65,
457
+ F: 70,
458
+ a: 97,
459
+ f: 102,
460
+ };
461
+ function charCodeToBase16(char) {
462
+ if (char >= charCodeMap.zero && char <= charCodeMap.nine)
463
+ return char - charCodeMap.zero;
464
+ if (char >= charCodeMap.A && char <= charCodeMap.F)
465
+ return char - (charCodeMap.A - 10);
466
+ if (char >= charCodeMap.a && char <= charCodeMap.f)
467
+ return char - (charCodeMap.a - 10);
468
+ return undefined;
469
+ }
470
+ /**
471
+ * Encodes a hex string into a byte array.
472
+ *
473
+ * - Docs: https://viem.sh/docs/utilities/toBytes#hextobytes
474
+ *
475
+ * @param hex Hex string to encode.
476
+ * @param opts Options.
477
+ * @returns Byte array value.
478
+ *
479
+ * @example
480
+ * import { hexToBytes } from 'viem'
481
+ * const data = hexToBytes('0x48656c6c6f20776f726c6421')
482
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
483
+ *
484
+ * @example
485
+ * import { hexToBytes } from 'viem'
486
+ * const data = hexToBytes('0x48656c6c6f20776f726c6421', { size: 32 })
487
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
488
+ */
489
+ function hexToBytes(hex_, opts = {}) {
490
+ let hex = hex_;
491
+ if (opts.size) {
492
+ assertSize(hex, { size: opts.size });
493
+ hex = pad(hex, { dir: 'right', size: opts.size });
494
+ }
495
+ let hexString = hex.slice(2);
496
+ if (hexString.length % 2)
497
+ hexString = `0${hexString}`;
498
+ const length = hexString.length / 2;
499
+ const bytes = new Uint8Array(length);
500
+ for (let index = 0, j = 0; index < length; index++) {
501
+ const nibbleLeft = charCodeToBase16(hexString.charCodeAt(j++));
502
+ const nibbleRight = charCodeToBase16(hexString.charCodeAt(j++));
503
+ if (nibbleLeft === undefined || nibbleRight === undefined) {
504
+ throw new BaseError(`Invalid byte sequence ("${hexString[j - 2]}${hexString[j - 1]}" in "${hexString}").`);
505
+ }
506
+ bytes[index] = nibbleLeft * 16 + nibbleRight;
507
+ }
508
+ return bytes;
509
+ }
510
+ /**
511
+ * Encodes a number into a byte array.
512
+ *
513
+ * - Docs: https://viem.sh/docs/utilities/toBytes#numbertobytes
514
+ *
515
+ * @param value Number to encode.
516
+ * @param opts Options.
517
+ * @returns Byte array value.
518
+ *
519
+ * @example
520
+ * import { numberToBytes } from 'viem'
521
+ * const data = numberToBytes(420)
522
+ * // Uint8Array([1, 164])
523
+ *
524
+ * @example
525
+ * import { numberToBytes } from 'viem'
526
+ * const data = numberToBytes(420, { size: 4 })
527
+ * // Uint8Array([0, 0, 1, 164])
528
+ */
529
+ function numberToBytes(value, opts) {
530
+ const hex = numberToHex(value, opts);
531
+ return hexToBytes(hex);
532
+ }
533
+ /**
534
+ * Encodes a UTF-8 string into a byte array.
535
+ *
536
+ * - Docs: https://viem.sh/docs/utilities/toBytes#stringtobytes
537
+ *
538
+ * @param value String to encode.
539
+ * @param opts Options.
540
+ * @returns Byte array value.
541
+ *
542
+ * @example
543
+ * import { stringToBytes } from 'viem'
544
+ * const data = stringToBytes('Hello world!')
545
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33])
546
+ *
547
+ * @example
548
+ * import { stringToBytes } from 'viem'
549
+ * const data = stringToBytes('Hello world!', { size: 32 })
550
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
551
+ */
552
+ function stringToBytes(value, opts = {}) {
553
+ const bytes = encoder.encode(value);
554
+ if (typeof opts.size === 'number') {
555
+ assertSize(bytes, { size: opts.size });
556
+ return pad(bytes, { dir: 'right', size: opts.size });
557
+ }
558
+ return bytes;
559
+ }
560
+
561
+ function assertSize(hexOrBytes, { size: size$1 }) {
562
+ if (size(hexOrBytes) > size$1)
563
+ throw new SizeOverflowError({
564
+ givenSize: size(hexOrBytes),
565
+ maxSize: size$1,
566
+ });
567
+ }
568
+ /**
569
+ * Decodes a hex value into a bigint.
570
+ *
571
+ * - Docs: https://viem.sh/docs/utilities/fromHex#hextobigint
572
+ *
573
+ * @param hex Hex value to decode.
574
+ * @param opts Options.
575
+ * @returns BigInt value.
576
+ *
577
+ * @example
578
+ * import { hexToBigInt } from 'viem'
579
+ * const data = hexToBigInt('0x1a4', { signed: true })
580
+ * // 420n
581
+ *
582
+ * @example
583
+ * import { hexToBigInt } from 'viem'
584
+ * const data = hexToBigInt('0x00000000000000000000000000000000000000000000000000000000000001a4', { size: 32 })
585
+ * // 420n
586
+ */
587
+ function hexToBigInt(hex, opts = {}) {
588
+ const { signed } = opts;
589
+ if (opts.size)
590
+ assertSize(hex, { size: opts.size });
591
+ const value = BigInt(hex);
592
+ if (!signed)
593
+ return value;
594
+ const size = (hex.length - 2) / 2;
595
+ const max = (1n << (BigInt(size) * 8n - 1n)) - 1n;
596
+ if (value <= max)
597
+ return value;
598
+ return value - BigInt(`0x${'f'.padStart(size * 2, 'f')}`) - 1n;
599
+ }
600
+ /**
601
+ * Decodes a hex string into a number.
602
+ *
603
+ * - Docs: https://viem.sh/docs/utilities/fromHex#hextonumber
604
+ *
605
+ * @param hex Hex value to decode.
606
+ * @param opts Options.
607
+ * @returns Number value.
608
+ *
609
+ * @example
610
+ * import { hexToNumber } from 'viem'
611
+ * const data = hexToNumber('0x1a4')
612
+ * // 420
613
+ *
614
+ * @example
615
+ * import { hexToNumber } from 'viem'
616
+ * const data = hexToBigInt('0x00000000000000000000000000000000000000000000000000000000000001a4', { size: 32 })
617
+ * // 420
618
+ */
619
+ function hexToNumber(hex, opts = {}) {
620
+ const value = hexToBigInt(hex, opts);
621
+ const number = Number(value);
622
+ if (!Number.isSafeInteger(number))
623
+ throw new IntegerOutOfRangeError({
624
+ max: `${Number.MAX_SAFE_INTEGER}`,
625
+ min: `${Number.MIN_SAFE_INTEGER}`,
626
+ signed: opts.signed,
627
+ size: opts.size,
628
+ value: `${value}n`,
629
+ });
630
+ return number;
631
+ }
632
+
633
+ function defineFormatter(type, format) {
634
+ return ({ exclude, format: overrides, }) => {
635
+ return {
636
+ exclude,
637
+ format: (args, action) => {
638
+ const formatted = format(args, action);
639
+ if (exclude) {
640
+ for (const key of exclude) {
641
+ delete formatted[key];
642
+ }
643
+ }
644
+ return {
645
+ ...formatted,
646
+ ...overrides(args, action),
647
+ };
648
+ },
649
+ type,
650
+ };
651
+ };
652
+ }
653
+
654
+ const transactionType = {
655
+ '0x0': 'legacy',
656
+ '0x1': 'eip2930',
657
+ '0x2': 'eip1559',
658
+ '0x3': 'eip4844',
659
+ '0x4': 'eip7702',
660
+ };
661
+ function formatTransaction(transaction, _) {
662
+ const transaction_ = {
663
+ ...transaction,
664
+ blockHash: transaction.blockHash ? transaction.blockHash : null,
665
+ blockNumber: transaction.blockNumber
666
+ ? BigInt(transaction.blockNumber)
667
+ : null,
668
+ chainId: transaction.chainId ? hexToNumber(transaction.chainId) : undefined,
669
+ gas: transaction.gas ? BigInt(transaction.gas) : undefined,
670
+ gasPrice: transaction.gasPrice ? BigInt(transaction.gasPrice) : undefined,
671
+ maxFeePerBlobGas: transaction.maxFeePerBlobGas
672
+ ? BigInt(transaction.maxFeePerBlobGas)
673
+ : undefined,
674
+ maxFeePerGas: transaction.maxFeePerGas
675
+ ? BigInt(transaction.maxFeePerGas)
676
+ : undefined,
677
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas
678
+ ? BigInt(transaction.maxPriorityFeePerGas)
679
+ : undefined,
680
+ nonce: transaction.nonce ? hexToNumber(transaction.nonce) : undefined,
681
+ to: transaction.to ? transaction.to : null,
682
+ transactionIndex: transaction.transactionIndex
683
+ ? Number(transaction.transactionIndex)
684
+ : null,
685
+ type: transaction.type
686
+ ? transactionType[transaction.type]
687
+ : undefined,
688
+ typeHex: transaction.type ? transaction.type : undefined,
689
+ value: transaction.value ? BigInt(transaction.value) : undefined,
690
+ v: transaction.v ? BigInt(transaction.v) : undefined,
691
+ };
692
+ if (transaction.authorizationList)
693
+ transaction_.authorizationList = formatAuthorizationList(transaction.authorizationList);
694
+ transaction_.yParity = (() => {
695
+ // If `yParity` is provided, we will use it.
696
+ if (transaction.yParity)
697
+ return Number(transaction.yParity);
698
+ // If no `yParity` provided, try derive from `v`.
699
+ if (typeof transaction_.v === 'bigint') {
700
+ if (transaction_.v === 0n || transaction_.v === 27n)
701
+ return 0;
702
+ if (transaction_.v === 1n || transaction_.v === 28n)
703
+ return 1;
704
+ if (transaction_.v >= 35n)
705
+ return transaction_.v % 2n === 0n ? 1 : 0;
706
+ }
707
+ return undefined;
708
+ })();
709
+ if (transaction_.type === 'legacy') {
710
+ delete transaction_.accessList;
711
+ delete transaction_.maxFeePerBlobGas;
712
+ delete transaction_.maxFeePerGas;
713
+ delete transaction_.maxPriorityFeePerGas;
714
+ delete transaction_.yParity;
715
+ }
716
+ if (transaction_.type === 'eip2930') {
717
+ delete transaction_.maxFeePerBlobGas;
718
+ delete transaction_.maxFeePerGas;
719
+ delete transaction_.maxPriorityFeePerGas;
720
+ }
721
+ if (transaction_.type === 'eip1559')
722
+ delete transaction_.maxFeePerBlobGas;
723
+ return transaction_;
724
+ }
725
+ const defineTransaction = /*#__PURE__*/ defineFormatter('transaction', formatTransaction);
726
+ //////////////////////////////////////////////////////////////////////////////
727
+ function formatAuthorizationList(authorizationList) {
728
+ return authorizationList.map((authorization) => ({
729
+ address: authorization.address,
730
+ chainId: Number(authorization.chainId),
731
+ nonce: Number(authorization.nonce),
732
+ r: authorization.r,
733
+ s: authorization.s,
734
+ yParity: Number(authorization.yParity),
735
+ }));
736
+ }
737
+
738
+ function formatBlock(block, _) {
739
+ const transactions = (block.transactions ?? []).map((transaction) => {
740
+ if (typeof transaction === 'string')
741
+ return transaction;
742
+ return formatTransaction(transaction);
743
+ });
744
+ return {
745
+ ...block,
746
+ baseFeePerGas: block.baseFeePerGas ? BigInt(block.baseFeePerGas) : null,
747
+ blobGasUsed: block.blobGasUsed ? BigInt(block.blobGasUsed) : undefined,
748
+ difficulty: block.difficulty ? BigInt(block.difficulty) : undefined,
749
+ excessBlobGas: block.excessBlobGas
750
+ ? BigInt(block.excessBlobGas)
751
+ : undefined,
752
+ gasLimit: block.gasLimit ? BigInt(block.gasLimit) : undefined,
753
+ gasUsed: block.gasUsed ? BigInt(block.gasUsed) : undefined,
754
+ hash: block.hash ? block.hash : null,
755
+ logsBloom: block.logsBloom ? block.logsBloom : null,
756
+ nonce: block.nonce ? block.nonce : null,
757
+ number: block.number ? BigInt(block.number) : null,
758
+ size: block.size ? BigInt(block.size) : undefined,
759
+ timestamp: block.timestamp ? BigInt(block.timestamp) : undefined,
760
+ transactions,
761
+ totalDifficulty: block.totalDifficulty
762
+ ? BigInt(block.totalDifficulty)
763
+ : null,
764
+ };
765
+ }
766
+ const defineBlock = /*#__PURE__*/ defineFormatter('block', formatBlock);
767
+
768
+ function formatLog(log, { args, eventName, } = {}) {
769
+ return {
770
+ ...log,
771
+ blockHash: log.blockHash ? log.blockHash : null,
772
+ blockNumber: log.blockNumber ? BigInt(log.blockNumber) : null,
773
+ blockTimestamp: log.blockTimestamp
774
+ ? BigInt(log.blockTimestamp)
775
+ : log.blockTimestamp === null
776
+ ? null
777
+ : undefined,
778
+ logIndex: log.logIndex ? Number(log.logIndex) : null,
779
+ transactionHash: log.transactionHash ? log.transactionHash : null,
780
+ transactionIndex: log.transactionIndex
781
+ ? Number(log.transactionIndex)
782
+ : null,
783
+ ...(eventName ? { args, eventName } : {}),
784
+ };
785
+ }
786
+
787
+ const receiptStatuses = {
788
+ '0x0': 'reverted',
789
+ '0x1': 'success',
790
+ };
791
+ function formatTransactionReceipt(transactionReceipt, _) {
792
+ const receipt = {
793
+ ...transactionReceipt,
794
+ blockNumber: transactionReceipt.blockNumber
795
+ ? BigInt(transactionReceipt.blockNumber)
796
+ : null,
797
+ contractAddress: transactionReceipt.contractAddress
798
+ ? transactionReceipt.contractAddress
799
+ : null,
800
+ cumulativeGasUsed: transactionReceipt.cumulativeGasUsed
801
+ ? BigInt(transactionReceipt.cumulativeGasUsed)
802
+ : null,
803
+ effectiveGasPrice: transactionReceipt.effectiveGasPrice
804
+ ? BigInt(transactionReceipt.effectiveGasPrice)
805
+ : null,
806
+ gasUsed: transactionReceipt.gasUsed
807
+ ? BigInt(transactionReceipt.gasUsed)
808
+ : null,
809
+ logs: transactionReceipt.logs
810
+ ? transactionReceipt.logs.map((log) => formatLog(log))
811
+ : null,
812
+ to: transactionReceipt.to ? transactionReceipt.to : null,
813
+ transactionIndex: transactionReceipt.transactionIndex
814
+ ? hexToNumber(transactionReceipt.transactionIndex)
815
+ : null,
816
+ status: transactionReceipt.status
817
+ ? receiptStatuses[transactionReceipt.status]
818
+ : null,
819
+ type: transactionReceipt.type
820
+ ? transactionType[transactionReceipt.type] || transactionReceipt.type
821
+ : null,
822
+ };
823
+ if (transactionReceipt.blobGasPrice)
824
+ receipt.blobGasPrice = BigInt(transactionReceipt.blobGasPrice);
825
+ if (transactionReceipt.blobGasUsed)
826
+ receipt.blobGasUsed = BigInt(transactionReceipt.blobGasUsed);
827
+ return receipt;
828
+ }
829
+ const defineTransactionReceipt = /*#__PURE__*/ defineFormatter('transactionReceipt', formatTransactionReceipt);
830
+
831
+ const maxUint256 = 2n ** 256n - 1n;
832
+
833
+ function concatHex(values) {
834
+ return `0x${values.reduce((acc, x) => acc + x.replace('0x', ''), '')}`;
835
+ }
836
+
837
+ class NegativeOffsetError extends BaseError {
838
+ constructor({ offset }) {
839
+ super(`Offset \`${offset}\` cannot be negative.`, {
840
+ name: 'NegativeOffsetError',
841
+ });
842
+ }
843
+ }
844
+ class PositionOutOfBoundsError extends BaseError {
845
+ constructor({ length, position }) {
846
+ super(`Position \`${position}\` is out of bounds (\`0 < position < ${length}\`).`, { name: 'PositionOutOfBoundsError' });
847
+ }
848
+ }
849
+ class RecursiveReadLimitExceededError extends BaseError {
850
+ constructor({ count, limit }) {
851
+ super(`Recursive read limit of \`${limit}\` exceeded (recursive read count: \`${count}\`).`, { name: 'RecursiveReadLimitExceededError' });
852
+ }
853
+ }
854
+
855
+ const staticCursor = {
856
+ bytes: new Uint8Array(),
857
+ dataView: new DataView(new ArrayBuffer(0)),
858
+ position: 0,
859
+ positionReadCount: new Map(),
860
+ recursiveReadCount: 0,
861
+ recursiveReadLimit: Number.POSITIVE_INFINITY,
862
+ assertReadLimit() {
863
+ if (this.recursiveReadCount >= this.recursiveReadLimit)
864
+ throw new RecursiveReadLimitExceededError({
865
+ count: this.recursiveReadCount + 1,
866
+ limit: this.recursiveReadLimit,
867
+ });
868
+ },
869
+ assertPosition(position) {
870
+ if (position < 0 || position > this.bytes.length - 1)
871
+ throw new PositionOutOfBoundsError({
872
+ length: this.bytes.length,
873
+ position,
874
+ });
875
+ },
876
+ decrementPosition(offset) {
877
+ if (offset < 0)
878
+ throw new NegativeOffsetError({ offset });
879
+ const position = this.position - offset;
880
+ this.assertPosition(position);
881
+ this.position = position;
882
+ },
883
+ getReadCount(position) {
884
+ return this.positionReadCount.get(position || this.position) || 0;
885
+ },
886
+ incrementPosition(offset) {
887
+ if (offset < 0)
888
+ throw new NegativeOffsetError({ offset });
889
+ const position = this.position + offset;
890
+ this.assertPosition(position);
891
+ this.position = position;
892
+ },
893
+ inspectByte(position_) {
894
+ const position = position_ ?? this.position;
895
+ this.assertPosition(position);
896
+ return this.bytes[position];
897
+ },
898
+ inspectBytes(length, position_) {
899
+ const position = position_ ?? this.position;
900
+ this.assertPosition(position + length - 1);
901
+ return this.bytes.subarray(position, position + length);
902
+ },
903
+ inspectUint8(position_) {
904
+ const position = position_ ?? this.position;
905
+ this.assertPosition(position);
906
+ return this.bytes[position];
907
+ },
908
+ inspectUint16(position_) {
909
+ const position = position_ ?? this.position;
910
+ this.assertPosition(position + 1);
911
+ return this.dataView.getUint16(position);
912
+ },
913
+ inspectUint24(position_) {
914
+ const position = position_ ?? this.position;
915
+ this.assertPosition(position + 2);
916
+ return ((this.dataView.getUint16(position) << 8) +
917
+ this.dataView.getUint8(position + 2));
918
+ },
919
+ inspectUint32(position_) {
920
+ const position = position_ ?? this.position;
921
+ this.assertPosition(position + 3);
922
+ return this.dataView.getUint32(position);
923
+ },
924
+ pushByte(byte) {
925
+ this.assertPosition(this.position);
926
+ this.bytes[this.position] = byte;
927
+ this.position++;
928
+ },
929
+ pushBytes(bytes) {
930
+ this.assertPosition(this.position + bytes.length - 1);
931
+ this.bytes.set(bytes, this.position);
932
+ this.position += bytes.length;
933
+ },
934
+ pushUint8(value) {
935
+ this.assertPosition(this.position);
936
+ this.bytes[this.position] = value;
937
+ this.position++;
938
+ },
939
+ pushUint16(value) {
940
+ this.assertPosition(this.position + 1);
941
+ this.dataView.setUint16(this.position, value);
942
+ this.position += 2;
943
+ },
944
+ pushUint24(value) {
945
+ this.assertPosition(this.position + 2);
946
+ this.dataView.setUint16(this.position, value >> 8);
947
+ this.dataView.setUint8(this.position + 2, value & 255);
948
+ this.position += 3;
949
+ },
950
+ pushUint32(value) {
951
+ this.assertPosition(this.position + 3);
952
+ this.dataView.setUint32(this.position, value);
953
+ this.position += 4;
954
+ },
955
+ readByte() {
956
+ this.assertReadLimit();
957
+ this._touch();
958
+ const value = this.inspectByte();
959
+ this.position++;
960
+ return value;
961
+ },
962
+ readBytes(length, size) {
963
+ this.assertReadLimit();
964
+ this._touch();
965
+ const value = this.inspectBytes(length);
966
+ this.position += size ?? length;
967
+ return value;
968
+ },
969
+ readUint8() {
970
+ this.assertReadLimit();
971
+ this._touch();
972
+ const value = this.inspectUint8();
973
+ this.position += 1;
974
+ return value;
975
+ },
976
+ readUint16() {
977
+ this.assertReadLimit();
978
+ this._touch();
979
+ const value = this.inspectUint16();
980
+ this.position += 2;
981
+ return value;
982
+ },
983
+ readUint24() {
984
+ this.assertReadLimit();
985
+ this._touch();
986
+ const value = this.inspectUint24();
987
+ this.position += 3;
988
+ return value;
989
+ },
990
+ readUint32() {
991
+ this.assertReadLimit();
992
+ this._touch();
993
+ const value = this.inspectUint32();
994
+ this.position += 4;
995
+ return value;
996
+ },
997
+ get remaining() {
998
+ return this.bytes.length - this.position;
999
+ },
1000
+ setPosition(position) {
1001
+ const oldPosition = this.position;
1002
+ this.assertPosition(position);
1003
+ this.position = position;
1004
+ return () => (this.position = oldPosition);
1005
+ },
1006
+ _touch() {
1007
+ if (this.recursiveReadLimit === Number.POSITIVE_INFINITY)
1008
+ return;
1009
+ const count = this.getReadCount();
1010
+ this.positionReadCount.set(this.position, count + 1);
1011
+ if (count > 0)
1012
+ this.recursiveReadCount++;
1013
+ },
1014
+ };
1015
+ function createCursor(bytes, { recursiveReadLimit = 8_192 } = {}) {
1016
+ const cursor = Object.create(staticCursor);
1017
+ cursor.bytes = bytes;
1018
+ cursor.dataView = new DataView(bytes.buffer ?? bytes, bytes.byteOffset, bytes.byteLength);
1019
+ cursor.positionReadCount = new Map();
1020
+ cursor.recursiveReadLimit = recursiveReadLimit;
1021
+ return cursor;
1022
+ }
1023
+
1024
+ function toRlp(bytes, to = 'hex') {
1025
+ const encodable = getEncodable(bytes);
1026
+ const cursor = createCursor(new Uint8Array(encodable.length));
1027
+ encodable.encode(cursor);
1028
+ if (to === 'hex')
1029
+ return bytesToHex(cursor.bytes);
1030
+ return cursor.bytes;
1031
+ }
1032
+ function getEncodable(bytes) {
1033
+ if (Array.isArray(bytes))
1034
+ return getEncodableList(bytes.map((x) => getEncodable(x)));
1035
+ return getEncodableBytes(bytes);
1036
+ }
1037
+ function getEncodableList(list) {
1038
+ const bodyLength = list.reduce((acc, x) => acc + x.length, 0);
1039
+ const sizeOfBodyLength = getSizeOfLength(bodyLength);
1040
+ const length = (() => {
1041
+ if (bodyLength <= 55)
1042
+ return 1 + bodyLength;
1043
+ return 1 + sizeOfBodyLength + bodyLength;
1044
+ })();
1045
+ return {
1046
+ length,
1047
+ encode(cursor) {
1048
+ if (bodyLength <= 55) {
1049
+ cursor.pushByte(0xc0 + bodyLength);
1050
+ }
1051
+ else {
1052
+ cursor.pushByte(0xc0 + 55 + sizeOfBodyLength);
1053
+ if (sizeOfBodyLength === 1)
1054
+ cursor.pushUint8(bodyLength);
1055
+ else if (sizeOfBodyLength === 2)
1056
+ cursor.pushUint16(bodyLength);
1057
+ else if (sizeOfBodyLength === 3)
1058
+ cursor.pushUint24(bodyLength);
1059
+ else
1060
+ cursor.pushUint32(bodyLength);
1061
+ }
1062
+ for (const { encode } of list) {
1063
+ encode(cursor);
1064
+ }
1065
+ },
1066
+ };
1067
+ }
1068
+ function getEncodableBytes(bytesOrHex) {
1069
+ const bytes = typeof bytesOrHex === 'string' ? hexToBytes(bytesOrHex) : bytesOrHex;
1070
+ const sizeOfBytesLength = getSizeOfLength(bytes.length);
1071
+ const length = (() => {
1072
+ if (bytes.length === 1 && bytes[0] < 0x80)
1073
+ return 1;
1074
+ if (bytes.length <= 55)
1075
+ return 1 + bytes.length;
1076
+ return 1 + sizeOfBytesLength + bytes.length;
1077
+ })();
1078
+ return {
1079
+ length,
1080
+ encode(cursor) {
1081
+ if (bytes.length === 1 && bytes[0] < 0x80) {
1082
+ cursor.pushBytes(bytes);
1083
+ }
1084
+ else if (bytes.length <= 55) {
1085
+ cursor.pushByte(0x80 + bytes.length);
1086
+ cursor.pushBytes(bytes);
1087
+ }
1088
+ else {
1089
+ cursor.pushByte(0x80 + 55 + sizeOfBytesLength);
1090
+ if (sizeOfBytesLength === 1)
1091
+ cursor.pushUint8(bytes.length);
1092
+ else if (sizeOfBytesLength === 2)
1093
+ cursor.pushUint16(bytes.length);
1094
+ else if (sizeOfBytesLength === 3)
1095
+ cursor.pushUint24(bytes.length);
1096
+ else
1097
+ cursor.pushUint32(bytes.length);
1098
+ cursor.pushBytes(bytes);
1099
+ }
1100
+ },
1101
+ };
1102
+ }
1103
+ function getSizeOfLength(length) {
1104
+ if (length < 2 ** 8)
1105
+ return 1;
1106
+ if (length < 2 ** 16)
1107
+ return 2;
1108
+ if (length < 2 ** 24)
1109
+ return 3;
1110
+ if (length < 2 ** 32)
1111
+ return 4;
1112
+ throw new BaseError('Length is too large.');
1113
+ }
1114
+
1115
+ const gweiUnits = {
1116
+ ether: -9,
1117
+ wei: 9,
1118
+ };
1119
+
1120
+ /**
1121
+ * Divides a number by a given exponent of base 10 (10exponent), and formats it into a string representation of the number..
1122
+ *
1123
+ * - Docs: https://viem.sh/docs/utilities/formatUnits
1124
+ *
1125
+ * @example
1126
+ * import { formatUnits } from 'viem'
1127
+ *
1128
+ * formatUnits(420000000000n, 9)
1129
+ * // '420'
1130
+ */
1131
+ function formatUnits(value, decimals) {
1132
+ let display = value.toString();
1133
+ const negative = display.startsWith('-');
1134
+ if (negative)
1135
+ display = display.slice(1);
1136
+ display = display.padStart(decimals, '0');
1137
+ let [integer, fraction] = [
1138
+ display.slice(0, display.length - decimals),
1139
+ display.slice(display.length - decimals),
1140
+ ];
1141
+ fraction = fraction.replace(/(0+)$/, '');
1142
+ return `${negative ? '-' : ''}${integer || '0'}${fraction ? `.${fraction}` : ''}`;
1143
+ }
1144
+
1145
+ /**
1146
+ * Converts numerical wei to a string representation of gwei.
1147
+ *
1148
+ * - Docs: https://viem.sh/docs/utilities/formatGwei
1149
+ *
1150
+ * @example
1151
+ * import { formatGwei } from 'viem'
1152
+ *
1153
+ * formatGwei(1000000000n)
1154
+ * // '1'
1155
+ */
1156
+ function formatGwei(wei, unit = 'wei') {
1157
+ return formatUnits(wei, gweiUnits[unit]);
1158
+ }
1159
+
1160
+ function prettyPrint(args) {
1161
+ const entries = Object.entries(args)
1162
+ .map(([key, value]) => {
1163
+ if (value === undefined || value === false)
1164
+ return null;
1165
+ return [key, value];
1166
+ })
1167
+ .filter(Boolean);
1168
+ const maxLength = entries.reduce((acc, [key]) => Math.max(acc, key.length), 0);
1169
+ return entries
1170
+ .map(([key, value]) => ` ${`${key}:`.padEnd(maxLength + 1)} ${value}`)
1171
+ .join('\n');
1172
+ }
1173
+ class InvalidLegacyVError extends BaseError {
1174
+ constructor({ v }) {
1175
+ super(`Invalid \`v\` value "${v}". Expected 27 or 28.`, {
1176
+ name: 'InvalidLegacyVError',
1177
+ });
1178
+ }
1179
+ }
1180
+ class InvalidSerializableTransactionError extends BaseError {
1181
+ constructor({ transaction }) {
1182
+ super('Cannot infer a transaction type from provided transaction.', {
1183
+ metaMessages: [
1184
+ 'Provided Transaction:',
1185
+ '{',
1186
+ prettyPrint(transaction),
1187
+ '}',
1188
+ '',
1189
+ 'To infer the type, either provide:',
1190
+ '- a `type` to the Transaction, or',
1191
+ '- an EIP-1559 Transaction with `maxFeePerGas`, or',
1192
+ '- an EIP-2930 Transaction with `gasPrice` & `accessList`, or',
1193
+ '- an EIP-4844 Transaction with `blobs`, `blobVersionedHashes`, `sidecars`, or',
1194
+ '- an EIP-7702 Transaction with `authorizationList`, or',
1195
+ '- a Legacy Transaction with `gasPrice`',
1196
+ ],
1197
+ name: 'InvalidSerializableTransactionError',
1198
+ });
1199
+ }
1200
+ }
1201
+ class InvalidStorageKeySizeError extends BaseError {
1202
+ constructor({ storageKey }) {
1203
+ super(`Size for storage key "${storageKey}" is invalid. Expected 32 bytes. Got ${Math.floor((storageKey.length - 2) / 2)} bytes.`, { name: 'InvalidStorageKeySizeError' });
1204
+ }
1205
+ }
1206
+
1207
+ /*
1208
+ * Serializes an EIP-7702 authorization list.
1209
+ */
1210
+ function serializeAuthorizationList(authorizationList) {
1211
+ if (!authorizationList || authorizationList.length === 0)
1212
+ return [];
1213
+ const serializedAuthorizationList = [];
1214
+ for (const authorization of authorizationList) {
1215
+ const { chainId, nonce, ...signature } = authorization;
1216
+ const contractAddress = authorization.address;
1217
+ serializedAuthorizationList.push([
1218
+ chainId ? toHex(chainId) : '0x',
1219
+ contractAddress,
1220
+ nonce ? toHex(nonce) : '0x',
1221
+ ...toYParitySignatureArray({}, signature),
1222
+ ]);
1223
+ }
1224
+ return serializedAuthorizationList;
1225
+ }
1226
+
1227
+ /**
1228
+ * Compute commitments from a list of blobs.
1229
+ *
1230
+ * @example
1231
+ * ```ts
1232
+ * import { blobsToCommitments, toBlobs } from 'viem'
1233
+ * import { kzg } from './kzg'
1234
+ *
1235
+ * const blobs = toBlobs({ data: '0x1234' })
1236
+ * const commitments = blobsToCommitments({ blobs, kzg })
1237
+ * ```
1238
+ */
1239
+ function blobsToCommitments(parameters) {
1240
+ const { kzg } = parameters;
1241
+ const to = parameters.to ?? (typeof parameters.blobs[0] === 'string' ? 'hex' : 'bytes');
1242
+ const blobs = (typeof parameters.blobs[0] === 'string'
1243
+ ? parameters.blobs.map((x) => hexToBytes(x))
1244
+ : parameters.blobs);
1245
+ const commitments = [];
1246
+ for (const blob of blobs)
1247
+ commitments.push(Uint8Array.from(kzg.blobToKzgCommitment(blob)));
1248
+ return (to === 'bytes'
1249
+ ? commitments
1250
+ : commitments.map((x) => bytesToHex(x)));
1251
+ }
1252
+
1253
+ /**
1254
+ * Compute the proofs for a list of blobs and their commitments.
1255
+ *
1256
+ * @example
1257
+ * ```ts
1258
+ * import {
1259
+ * blobsToCommitments,
1260
+ * toBlobs
1261
+ * } from 'viem'
1262
+ * import { kzg } from './kzg'
1263
+ *
1264
+ * const blobs = toBlobs({ data: '0x1234' })
1265
+ * const commitments = blobsToCommitments({ blobs, kzg })
1266
+ * const proofs = blobsToProofs({ blobs, commitments, kzg })
1267
+ * ```
1268
+ */
1269
+ function blobsToProofs(parameters) {
1270
+ const { kzg } = parameters;
1271
+ const to = parameters.to ?? (typeof parameters.blobs[0] === 'string' ? 'hex' : 'bytes');
1272
+ const blobs = (typeof parameters.blobs[0] === 'string'
1273
+ ? parameters.blobs.map((x) => hexToBytes(x))
1274
+ : parameters.blobs);
1275
+ const commitments = (typeof parameters.commitments[0] === 'string'
1276
+ ? parameters.commitments.map((x) => hexToBytes(x))
1277
+ : parameters.commitments);
1278
+ const proofs = [];
1279
+ for (let i = 0; i < blobs.length; i++) {
1280
+ const blob = blobs[i];
1281
+ const commitment = commitments[i];
1282
+ proofs.push(Uint8Array.from(kzg.computeBlobKzgProof(blob, commitment)));
1283
+ }
1284
+ return (to === 'bytes'
1285
+ ? proofs
1286
+ : proofs.map((x) => bytesToHex(x)));
1287
+ }
1288
+
1289
+ /**
1290
+ * Utilities for hex, bytes, CSPRNG.
1291
+ * @module
1292
+ */
1293
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
1294
+ // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
1295
+ // node.js versions earlier than v19 don't declare it in global scope.
1296
+ // For node.js, package.json#exports field mapping rewrites import
1297
+ // from `crypto` to `cryptoNode`, which imports native module.
1298
+ // Makes the utils un-importable in browsers without a bundler.
1299
+ // Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
1300
+ /** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
1301
+ function isBytes(a) {
1302
+ return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
1303
+ }
1304
+ /** Asserts something is positive integer. */
1305
+ function anumber(n) {
1306
+ if (!Number.isSafeInteger(n) || n < 0)
1307
+ throw new Error('positive integer expected, got ' + n);
1308
+ }
1309
+ /** Asserts something is Uint8Array. */
1310
+ function abytes(b, ...lengths) {
1311
+ if (!isBytes(b))
1312
+ throw new Error('Uint8Array expected');
1313
+ if (lengths.length > 0 && !lengths.includes(b.length))
1314
+ throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
1315
+ }
1316
+ /** Asserts a hash instance has not been destroyed / finished */
1317
+ function aexists(instance, checkFinished = true) {
1318
+ if (instance.destroyed)
1319
+ throw new Error('Hash instance has been destroyed');
1320
+ if (checkFinished && instance.finished)
1321
+ throw new Error('Hash#digest() has already been called');
1322
+ }
1323
+ /** Asserts output is properly-sized byte array */
1324
+ function aoutput(out, instance) {
1325
+ abytes(out);
1326
+ const min = instance.outputLen;
1327
+ if (out.length < min) {
1328
+ throw new Error('digestInto() expects output buffer of length at least ' + min);
1329
+ }
1330
+ }
1331
+ /** Cast u8 / u16 / u32 to u32. */
1332
+ function u32(arr) {
1333
+ return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
1334
+ }
1335
+ /** Zeroize a byte array. Warning: JS provides no guarantees. */
1336
+ function clean(...arrays) {
1337
+ for (let i = 0; i < arrays.length; i++) {
1338
+ arrays[i].fill(0);
1339
+ }
1340
+ }
1341
+ /** Create DataView of an array for easy byte-level manipulation. */
1342
+ function createView(arr) {
1343
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
1344
+ }
1345
+ /** The rotate right (circular right shift) operation for uint32 */
1346
+ function rotr(word, shift) {
1347
+ return (word << (32 - shift)) | (word >>> shift);
1348
+ }
1349
+ /** Is current platform little-endian? Most are. Big-Endian platform: IBM */
1350
+ const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();
1351
+ /** The byte swap operation for uint32 */
1352
+ function byteSwap(word) {
1353
+ return (((word << 24) & 0xff000000) |
1354
+ ((word << 8) & 0xff0000) |
1355
+ ((word >>> 8) & 0xff00) |
1356
+ ((word >>> 24) & 0xff));
1357
+ }
1358
+ /** In place byte swap for Uint32Array */
1359
+ function byteSwap32(arr) {
1360
+ for (let i = 0; i < arr.length; i++) {
1361
+ arr[i] = byteSwap(arr[i]);
1362
+ }
1363
+ return arr;
1364
+ }
1365
+ const swap32IfBE = isLE
1366
+ ? (u) => u
1367
+ : byteSwap32;
1368
+ /**
1369
+ * Converts string to bytes using UTF8 encoding.
1370
+ * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
1371
+ */
1372
+ function utf8ToBytes(str) {
1373
+ if (typeof str !== 'string')
1374
+ throw new Error('string expected');
1375
+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
1376
+ }
1377
+ /**
1378
+ * Normalizes (non-hex) string or Uint8Array to Uint8Array.
1379
+ * Warning: when Uint8Array is passed, it would NOT get copied.
1380
+ * Keep in mind for future mutable operations.
1381
+ */
1382
+ function toBytes(data) {
1383
+ if (typeof data === 'string')
1384
+ data = utf8ToBytes(data);
1385
+ abytes(data);
1386
+ return data;
1387
+ }
1388
+ /** For runtime check if class implements interface */
1389
+ class Hash {
1390
+ }
1391
+ /** Wraps hash function, creating an interface on top of it */
1392
+ function createHasher(hashCons) {
1393
+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
1394
+ const tmp = hashCons();
1395
+ hashC.outputLen = tmp.outputLen;
1396
+ hashC.blockLen = tmp.blockLen;
1397
+ hashC.create = () => hashCons();
1398
+ return hashC;
1399
+ }
1400
+
1401
+ /**
1402
+ * Internal Merkle-Damgard hash utils.
1403
+ * @module
1404
+ */
1405
+ /** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
1406
+ function setBigUint64(view, byteOffset, value, isLE) {
1407
+ if (typeof view.setBigUint64 === 'function')
1408
+ return view.setBigUint64(byteOffset, value, isLE);
1409
+ const _32n = BigInt(32);
1410
+ const _u32_max = BigInt(0xffffffff);
1411
+ const wh = Number((value >> _32n) & _u32_max);
1412
+ const wl = Number(value & _u32_max);
1413
+ const h = isLE ? 4 : 0;
1414
+ const l = isLE ? 0 : 4;
1415
+ view.setUint32(byteOffset + h, wh, isLE);
1416
+ view.setUint32(byteOffset + l, wl, isLE);
1417
+ }
1418
+ /** Choice: a ? b : c */
1419
+ function Chi(a, b, c) {
1420
+ return (a & b) ^ (~a & c);
1421
+ }
1422
+ /** Majority function, true if any two inputs is true. */
1423
+ function Maj(a, b, c) {
1424
+ return (a & b) ^ (a & c) ^ (b & c);
1425
+ }
1426
+ /**
1427
+ * Merkle-Damgard hash construction base class.
1428
+ * Could be used to create MD5, RIPEMD, SHA1, SHA2.
1429
+ */
1430
+ class HashMD extends Hash {
1431
+ constructor(blockLen, outputLen, padOffset, isLE) {
1432
+ super();
1433
+ this.finished = false;
1434
+ this.length = 0;
1435
+ this.pos = 0;
1436
+ this.destroyed = false;
1437
+ this.blockLen = blockLen;
1438
+ this.outputLen = outputLen;
1439
+ this.padOffset = padOffset;
1440
+ this.isLE = isLE;
1441
+ this.buffer = new Uint8Array(blockLen);
1442
+ this.view = createView(this.buffer);
1443
+ }
1444
+ update(data) {
1445
+ aexists(this);
1446
+ data = toBytes(data);
1447
+ abytes(data);
1448
+ const { view, buffer, blockLen } = this;
1449
+ const len = data.length;
1450
+ for (let pos = 0; pos < len;) {
1451
+ const take = Math.min(blockLen - this.pos, len - pos);
1452
+ // Fast path: we have at least one block in input, cast it to view and process
1453
+ if (take === blockLen) {
1454
+ const dataView = createView(data);
1455
+ for (; blockLen <= len - pos; pos += blockLen)
1456
+ this.process(dataView, pos);
1457
+ continue;
1458
+ }
1459
+ buffer.set(data.subarray(pos, pos + take), this.pos);
1460
+ this.pos += take;
1461
+ pos += take;
1462
+ if (this.pos === blockLen) {
1463
+ this.process(view, 0);
1464
+ this.pos = 0;
1465
+ }
1466
+ }
1467
+ this.length += data.length;
1468
+ this.roundClean();
1469
+ return this;
1470
+ }
1471
+ digestInto(out) {
1472
+ aexists(this);
1473
+ aoutput(out, this);
1474
+ this.finished = true;
1475
+ // Padding
1476
+ // We can avoid allocation of buffer for padding completely if it
1477
+ // was previously not allocated here. But it won't change performance.
1478
+ const { buffer, view, blockLen, isLE } = this;
1479
+ let { pos } = this;
1480
+ // append the bit '1' to the message
1481
+ buffer[pos++] = 0b10000000;
1482
+ clean(this.buffer.subarray(pos));
1483
+ // we have less than padOffset left in buffer, so we cannot put length in
1484
+ // current block, need process it and pad again
1485
+ if (this.padOffset > blockLen - pos) {
1486
+ this.process(view, 0);
1487
+ pos = 0;
1488
+ }
1489
+ // Pad until full block byte with zeros
1490
+ for (let i = pos; i < blockLen; i++)
1491
+ buffer[i] = 0;
1492
+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
1493
+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
1494
+ // So we just write lowest 64 bits of that value.
1495
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
1496
+ this.process(view, 0);
1497
+ const oview = createView(out);
1498
+ const len = this.outputLen;
1499
+ // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
1500
+ if (len % 4)
1501
+ throw new Error('_sha2: outputLen should be aligned to 32bit');
1502
+ const outLen = len / 4;
1503
+ const state = this.get();
1504
+ if (outLen > state.length)
1505
+ throw new Error('_sha2: outputLen bigger than state');
1506
+ for (let i = 0; i < outLen; i++)
1507
+ oview.setUint32(4 * i, state[i], isLE);
1508
+ }
1509
+ digest() {
1510
+ const { buffer, outputLen } = this;
1511
+ this.digestInto(buffer);
1512
+ const res = buffer.slice(0, outputLen);
1513
+ this.destroy();
1514
+ return res;
1515
+ }
1516
+ _cloneInto(to) {
1517
+ to || (to = new this.constructor());
1518
+ to.set(...this.get());
1519
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
1520
+ to.destroyed = destroyed;
1521
+ to.finished = finished;
1522
+ to.length = length;
1523
+ to.pos = pos;
1524
+ if (length % blockLen)
1525
+ to.buffer.set(buffer);
1526
+ return to;
1527
+ }
1528
+ clone() {
1529
+ return this._cloneInto();
1530
+ }
1531
+ }
1532
+ /**
1533
+ * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
1534
+ * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
1535
+ */
1536
+ /** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
1537
+ const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
1538
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
1539
+ ]);
1540
+
1541
+ /**
1542
+ * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
1543
+ * @todo re-check https://issues.chromium.org/issues/42212588
1544
+ * @module
1545
+ */
1546
+ const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
1547
+ const _32n = /* @__PURE__ */ BigInt(32);
1548
+ function fromBig(n, le = false) {
1549
+ if (le)
1550
+ return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
1551
+ return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
1552
+ }
1553
+ function split(lst, le = false) {
1554
+ const len = lst.length;
1555
+ let Ah = new Uint32Array(len);
1556
+ let Al = new Uint32Array(len);
1557
+ for (let i = 0; i < len; i++) {
1558
+ const { h, l } = fromBig(lst[i], le);
1559
+ [Ah[i], Al[i]] = [h, l];
1560
+ }
1561
+ return [Ah, Al];
1562
+ }
1563
+ // Left rotate for Shift in [1, 32)
1564
+ const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
1565
+ const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
1566
+ // Left rotate for Shift in (32, 64), NOTE: 32 is special case.
1567
+ const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
1568
+ const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
1569
+
1570
+ /**
1571
+ * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
1572
+ * SHA256 is the fastest hash implementable in JS, even faster than Blake3.
1573
+ * Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
1574
+ * [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
1575
+ * @module
1576
+ */
1577
+ /**
1578
+ * Round constants:
1579
+ * First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
1580
+ */
1581
+ // prettier-ignore
1582
+ const SHA256_K = /* @__PURE__ */ Uint32Array.from([
1583
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1584
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1585
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1586
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1587
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1588
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1589
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1590
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
1591
+ ]);
1592
+ /** Reusable temporary buffer. "W" comes straight from spec. */
1593
+ const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
1594
+ class SHA256 extends HashMD {
1595
+ constructor(outputLen = 32) {
1596
+ super(64, outputLen, 8, false);
1597
+ // We cannot use array here since array allows indexing by variable
1598
+ // which means optimizer/compiler cannot use registers.
1599
+ this.A = SHA256_IV[0] | 0;
1600
+ this.B = SHA256_IV[1] | 0;
1601
+ this.C = SHA256_IV[2] | 0;
1602
+ this.D = SHA256_IV[3] | 0;
1603
+ this.E = SHA256_IV[4] | 0;
1604
+ this.F = SHA256_IV[5] | 0;
1605
+ this.G = SHA256_IV[6] | 0;
1606
+ this.H = SHA256_IV[7] | 0;
1607
+ }
1608
+ get() {
1609
+ const { A, B, C, D, E, F, G, H } = this;
1610
+ return [A, B, C, D, E, F, G, H];
1611
+ }
1612
+ // prettier-ignore
1613
+ set(A, B, C, D, E, F, G, H) {
1614
+ this.A = A | 0;
1615
+ this.B = B | 0;
1616
+ this.C = C | 0;
1617
+ this.D = D | 0;
1618
+ this.E = E | 0;
1619
+ this.F = F | 0;
1620
+ this.G = G | 0;
1621
+ this.H = H | 0;
1622
+ }
1623
+ process(view, offset) {
1624
+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
1625
+ for (let i = 0; i < 16; i++, offset += 4)
1626
+ SHA256_W[i] = view.getUint32(offset, false);
1627
+ for (let i = 16; i < 64; i++) {
1628
+ const W15 = SHA256_W[i - 15];
1629
+ const W2 = SHA256_W[i - 2];
1630
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
1631
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
1632
+ SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
1633
+ }
1634
+ // Compression function main loop, 64 rounds
1635
+ let { A, B, C, D, E, F, G, H } = this;
1636
+ for (let i = 0; i < 64; i++) {
1637
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
1638
+ const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
1639
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
1640
+ const T2 = (sigma0 + Maj(A, B, C)) | 0;
1641
+ H = G;
1642
+ G = F;
1643
+ F = E;
1644
+ E = (D + T1) | 0;
1645
+ D = C;
1646
+ C = B;
1647
+ B = A;
1648
+ A = (T1 + T2) | 0;
1649
+ }
1650
+ // Add the compressed chunk to the current hash value
1651
+ A = (A + this.A) | 0;
1652
+ B = (B + this.B) | 0;
1653
+ C = (C + this.C) | 0;
1654
+ D = (D + this.D) | 0;
1655
+ E = (E + this.E) | 0;
1656
+ F = (F + this.F) | 0;
1657
+ G = (G + this.G) | 0;
1658
+ H = (H + this.H) | 0;
1659
+ this.set(A, B, C, D, E, F, G, H);
1660
+ }
1661
+ roundClean() {
1662
+ clean(SHA256_W);
1663
+ }
1664
+ destroy() {
1665
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
1666
+ clean(this.buffer);
1667
+ }
1668
+ }
1669
+ /**
1670
+ * SHA2-256 hash function from RFC 4634.
1671
+ *
1672
+ * It is the fastest JS hash, even faster than Blake3.
1673
+ * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
1674
+ * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
1675
+ */
1676
+ const sha256$2 = /* @__PURE__ */ createHasher(() => new SHA256());
1677
+
1678
+ /**
1679
+ * SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
1680
+ *
1681
+ * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
1682
+ * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
1683
+ *
1684
+ * Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
1685
+ * @module
1686
+ * @deprecated
1687
+ */
1688
+ /** @deprecated Use import from `noble/hashes/sha2` module */
1689
+ const sha256$1 = sha256$2;
1690
+
1691
+ function sha256(value, to_) {
1692
+ const bytes = sha256$1(isHex(value, { strict: false }) ? toBytes$1(value) : value);
1693
+ return bytes;
1694
+ }
1695
+
1696
+ /**
1697
+ * Transform a commitment to it's versioned hash.
1698
+ *
1699
+ * @example
1700
+ * ```ts
1701
+ * import {
1702
+ * blobsToCommitments,
1703
+ * commitmentToVersionedHash,
1704
+ * toBlobs
1705
+ * } from 'viem'
1706
+ * import { kzg } from './kzg'
1707
+ *
1708
+ * const blobs = toBlobs({ data: '0x1234' })
1709
+ * const [commitment] = blobsToCommitments({ blobs, kzg })
1710
+ * const versionedHash = commitmentToVersionedHash({ commitment })
1711
+ * ```
1712
+ */
1713
+ function commitmentToVersionedHash(parameters) {
1714
+ const { commitment, version = 1 } = parameters;
1715
+ const to = parameters.to ?? (typeof commitment === 'string' ? 'hex' : 'bytes');
1716
+ const versionedHash = sha256(commitment);
1717
+ versionedHash.set([version], 0);
1718
+ return (to === 'bytes' ? versionedHash : bytesToHex(versionedHash));
1719
+ }
1720
+
1721
+ /**
1722
+ * Transform a list of commitments to their versioned hashes.
1723
+ *
1724
+ * @example
1725
+ * ```ts
1726
+ * import {
1727
+ * blobsToCommitments,
1728
+ * commitmentsToVersionedHashes,
1729
+ * toBlobs
1730
+ * } from 'viem'
1731
+ * import { kzg } from './kzg'
1732
+ *
1733
+ * const blobs = toBlobs({ data: '0x1234' })
1734
+ * const commitments = blobsToCommitments({ blobs, kzg })
1735
+ * const versionedHashes = commitmentsToVersionedHashes({ commitments })
1736
+ * ```
1737
+ */
1738
+ function commitmentsToVersionedHashes(parameters) {
1739
+ const { commitments, version } = parameters;
1740
+ const to = parameters.to ?? (typeof commitments[0] === 'string' ? 'hex' : 'bytes');
1741
+ const hashes = [];
1742
+ for (const commitment of commitments) {
1743
+ hashes.push(commitmentToVersionedHash({
1744
+ commitment,
1745
+ to,
1746
+ version,
1747
+ }));
1748
+ }
1749
+ return hashes;
1750
+ }
1751
+
1752
+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4844.md#parameters
1753
+ /** Blob limit per transaction. */
1754
+ const blobsPerTransaction = 6;
1755
+ /** The number of bytes in a BLS scalar field element. */
1756
+ const bytesPerFieldElement = 32;
1757
+ /** The number of field elements in a blob. */
1758
+ const fieldElementsPerBlob = 4096;
1759
+ /** The number of bytes in a blob. */
1760
+ const bytesPerBlob = bytesPerFieldElement * fieldElementsPerBlob;
1761
+ /** Blob bytes limit per transaction. */
1762
+ const maxBytesPerTransaction = bytesPerBlob * blobsPerTransaction -
1763
+ // terminator byte (0x80).
1764
+ 1 -
1765
+ // zero byte (0x00) appended to each field element.
1766
+ 1 * fieldElementsPerBlob * blobsPerTransaction;
1767
+
1768
+ // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4844.md#parameters
1769
+ const versionedHashVersionKzg = 1;
1770
+
1771
+ class BlobSizeTooLargeError extends BaseError {
1772
+ constructor({ maxSize, size }) {
1773
+ super('Blob size is too large.', {
1774
+ metaMessages: [`Max: ${maxSize} bytes`, `Given: ${size} bytes`],
1775
+ name: 'BlobSizeTooLargeError',
1776
+ });
1777
+ }
1778
+ }
1779
+ class EmptyBlobError extends BaseError {
1780
+ constructor() {
1781
+ super('Blob data must not be empty.', { name: 'EmptyBlobError' });
1782
+ }
1783
+ }
1784
+ class InvalidVersionedHashSizeError extends BaseError {
1785
+ constructor({ hash, size, }) {
1786
+ super(`Versioned hash "${hash}" size is invalid.`, {
1787
+ metaMessages: ['Expected: 32', `Received: ${size}`],
1788
+ name: 'InvalidVersionedHashSizeError',
1789
+ });
1790
+ }
1791
+ }
1792
+ class InvalidVersionedHashVersionError extends BaseError {
1793
+ constructor({ hash, version, }) {
1794
+ super(`Versioned hash "${hash}" version is invalid.`, {
1795
+ metaMessages: [
1796
+ `Expected: ${versionedHashVersionKzg}`,
1797
+ `Received: ${version}`,
1798
+ ],
1799
+ name: 'InvalidVersionedHashVersionError',
1800
+ });
1801
+ }
1802
+ }
1803
+
1804
+ /**
1805
+ * Transforms arbitrary data to blobs.
1806
+ *
1807
+ * @example
1808
+ * ```ts
1809
+ * import { toBlobs, stringToHex } from 'viem'
1810
+ *
1811
+ * const blobs = toBlobs({ data: stringToHex('hello world') })
1812
+ * ```
1813
+ */
1814
+ function toBlobs(parameters) {
1815
+ const to = parameters.to ?? (typeof parameters.data === 'string' ? 'hex' : 'bytes');
1816
+ const data = (typeof parameters.data === 'string'
1817
+ ? hexToBytes(parameters.data)
1818
+ : parameters.data);
1819
+ const size_ = size(data);
1820
+ if (!size_)
1821
+ throw new EmptyBlobError();
1822
+ if (size_ > maxBytesPerTransaction)
1823
+ throw new BlobSizeTooLargeError({
1824
+ maxSize: maxBytesPerTransaction,
1825
+ size: size_,
1826
+ });
1827
+ const blobs = [];
1828
+ let active = true;
1829
+ let position = 0;
1830
+ while (active) {
1831
+ const blob = createCursor(new Uint8Array(bytesPerBlob));
1832
+ let size = 0;
1833
+ while (size < fieldElementsPerBlob) {
1834
+ const bytes = data.slice(position, position + (bytesPerFieldElement - 1));
1835
+ // Push a zero byte so the field element doesn't overflow the BLS modulus.
1836
+ blob.pushByte(0x00);
1837
+ // Push the current segment of data bytes.
1838
+ blob.pushBytes(bytes);
1839
+ // If we detect that the current segment of data bytes is less than 31 bytes,
1840
+ // we can stop processing and push a terminator byte to indicate the end of the blob.
1841
+ if (bytes.length < 31) {
1842
+ blob.pushByte(0x80);
1843
+ active = false;
1844
+ break;
1845
+ }
1846
+ size++;
1847
+ position += 31;
1848
+ }
1849
+ blobs.push(blob);
1850
+ }
1851
+ return (to === 'bytes'
1852
+ ? blobs.map((x) => x.bytes)
1853
+ : blobs.map((x) => bytesToHex(x.bytes)));
1854
+ }
1855
+
1856
+ /**
1857
+ * Transforms arbitrary data (or blobs, commitments, & proofs) into a sidecar array.
1858
+ *
1859
+ * @example
1860
+ * ```ts
1861
+ * import { toBlobSidecars, stringToHex } from 'viem'
1862
+ *
1863
+ * const sidecars = toBlobSidecars({ data: stringToHex('hello world') })
1864
+ * ```
1865
+ *
1866
+ * @example
1867
+ * ```ts
1868
+ * import {
1869
+ * blobsToCommitments,
1870
+ * toBlobs,
1871
+ * blobsToProofs,
1872
+ * toBlobSidecars,
1873
+ * stringToHex
1874
+ * } from 'viem'
1875
+ *
1876
+ * const blobs = toBlobs({ data: stringToHex('hello world') })
1877
+ * const commitments = blobsToCommitments({ blobs, kzg })
1878
+ * const proofs = blobsToProofs({ blobs, commitments, kzg })
1879
+ *
1880
+ * const sidecars = toBlobSidecars({ blobs, commitments, proofs })
1881
+ * ```
1882
+ */
1883
+ function toBlobSidecars(parameters) {
1884
+ const { data, kzg, to } = parameters;
1885
+ const blobs = parameters.blobs ?? toBlobs({ data: data, to });
1886
+ const commitments = parameters.commitments ?? blobsToCommitments({ blobs, kzg: kzg, to });
1887
+ const proofs = parameters.proofs ?? blobsToProofs({ blobs, commitments, kzg: kzg, to });
1888
+ const sidecars = [];
1889
+ for (let i = 0; i < blobs.length; i++)
1890
+ sidecars.push({
1891
+ blob: blobs[i],
1892
+ commitment: commitments[i],
1893
+ proof: proofs[i],
1894
+ });
1895
+ return sidecars;
1896
+ }
1897
+
1898
+ class InvalidAddressError extends BaseError {
1899
+ constructor({ address }) {
1900
+ super(`Address "${address}" is invalid.`, {
1901
+ metaMessages: [
1902
+ '- Address must be a hex value of 20 bytes (40 hex characters).',
1903
+ '- Address must match its checksum counterpart.',
1904
+ ],
1905
+ name: 'InvalidAddressError',
1906
+ });
1907
+ }
1908
+ }
1909
+
1910
+ class InvalidChainIdError extends BaseError {
1911
+ constructor({ chainId }) {
1912
+ super(typeof chainId === 'number'
1913
+ ? `Chain ID "${chainId}" is invalid.`
1914
+ : 'Chain ID is invalid.', { name: 'InvalidChainIdError' });
1915
+ }
1916
+ }
1917
+
1918
+ class FeeCapTooHighError extends BaseError {
1919
+ constructor({ cause, maxFeePerGas, } = {}) {
1920
+ super(`The fee cap (\`maxFeePerGas\`${maxFeePerGas ? ` = ${formatGwei(maxFeePerGas)} gwei` : ''}) cannot be higher than the maximum allowed value (2^256-1).`, {
1921
+ cause,
1922
+ name: 'FeeCapTooHighError',
1923
+ });
1924
+ }
1925
+ }
1926
+ Object.defineProperty(FeeCapTooHighError, "nodeMessage", {
1927
+ enumerable: true,
1928
+ configurable: true,
1929
+ writable: true,
1930
+ value: /max fee per gas higher than 2\^256-1|fee cap higher than 2\^256-1/
1931
+ });
1932
+ class TipAboveFeeCapError extends BaseError {
1933
+ constructor({ cause, maxPriorityFeePerGas, maxFeePerGas, } = {}) {
1934
+ super([
1935
+ `The provided tip (\`maxPriorityFeePerGas\`${maxPriorityFeePerGas
1936
+ ? ` = ${formatGwei(maxPriorityFeePerGas)} gwei`
1937
+ : ''}) cannot be higher than the fee cap (\`maxFeePerGas\`${maxFeePerGas ? ` = ${formatGwei(maxFeePerGas)} gwei` : ''}).`,
1938
+ ].join('\n'), {
1939
+ cause,
1940
+ name: 'TipAboveFeeCapError',
1941
+ });
1942
+ }
1943
+ }
1944
+ Object.defineProperty(TipAboveFeeCapError, "nodeMessage", {
1945
+ enumerable: true,
1946
+ configurable: true,
1947
+ writable: true,
1948
+ value: /max priority fee per gas higher than max fee per gas|tip higher than fee cap/
1949
+ });
1950
+
1951
+ /**
1952
+ * Map with a LRU (Least recently used) policy.
1953
+ *
1954
+ * @link https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU
1955
+ */
1956
+ class LruMap extends Map {
1957
+ constructor(size) {
1958
+ super();
1959
+ Object.defineProperty(this, "maxSize", {
1960
+ enumerable: true,
1961
+ configurable: true,
1962
+ writable: true,
1963
+ value: void 0
1964
+ });
1965
+ this.maxSize = size;
1966
+ }
1967
+ get(key) {
1968
+ const value = super.get(key);
1969
+ if (super.has(key)) {
1970
+ super.delete(key);
1971
+ super.set(key, value);
1972
+ }
1973
+ return value;
1974
+ }
1975
+ set(key, value) {
1976
+ if (super.has(key))
1977
+ super.delete(key);
1978
+ super.set(key, value);
1979
+ if (this.maxSize && this.size > this.maxSize) {
1980
+ const firstKey = super.keys().next().value;
1981
+ if (firstKey !== undefined)
1982
+ super.delete(firstKey);
1983
+ }
1984
+ return this;
1985
+ }
1986
+ }
1987
+
1988
+ /**
1989
+ * SHA3 (keccak) hash function, based on a new "Sponge function" design.
1990
+ * Different from older hashes, the internal state is bigger than output size.
1991
+ *
1992
+ * Check out [FIPS-202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf),
1993
+ * [Website](https://keccak.team/keccak.html),
1994
+ * [the differences between SHA-3 and Keccak](https://crypto.stackexchange.com/questions/15727/what-are-the-key-differences-between-the-draft-sha-3-standard-and-the-keccak-sub).
1995
+ *
1996
+ * Check out `sha3-addons` module for cSHAKE, k12, and others.
1997
+ * @module
1998
+ */
1999
+ // No __PURE__ annotations in sha3 header:
2000
+ // EVERYTHING is in fact used on every export.
2001
+ // Various per round constants calculations
2002
+ const _0n = BigInt(0);
2003
+ const _1n = BigInt(1);
2004
+ const _2n = BigInt(2);
2005
+ const _7n = BigInt(7);
2006
+ const _256n = BigInt(256);
2007
+ const _0x71n = BigInt(0x71);
2008
+ const SHA3_PI = [];
2009
+ const SHA3_ROTL = [];
2010
+ const _SHA3_IOTA = [];
2011
+ for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {
2012
+ // Pi
2013
+ [x, y] = [y, (2 * x + 3 * y) % 5];
2014
+ SHA3_PI.push(2 * (5 * y + x));
2015
+ // Rotational
2016
+ SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);
2017
+ // Iota
2018
+ let t = _0n;
2019
+ for (let j = 0; j < 7; j++) {
2020
+ R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n;
2021
+ if (R & _2n)
2022
+ t ^= _1n << ((_1n << /* @__PURE__ */ BigInt(j)) - _1n);
2023
+ }
2024
+ _SHA3_IOTA.push(t);
2025
+ }
2026
+ const IOTAS = split(_SHA3_IOTA, true);
2027
+ const SHA3_IOTA_H = IOTAS[0];
2028
+ const SHA3_IOTA_L = IOTAS[1];
2029
+ // Left rotation (without 0, 32, 64)
2030
+ const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));
2031
+ const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));
2032
+ /** `keccakf1600` internal function, additionally allows to adjust round count. */
2033
+ function keccakP(s, rounds = 24) {
2034
+ const B = new Uint32Array(5 * 2);
2035
+ // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)
2036
+ for (let round = 24 - rounds; round < 24; round++) {
2037
+ // Theta θ
2038
+ for (let x = 0; x < 10; x++)
2039
+ B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
2040
+ for (let x = 0; x < 10; x += 2) {
2041
+ const idx1 = (x + 8) % 10;
2042
+ const idx0 = (x + 2) % 10;
2043
+ const B0 = B[idx0];
2044
+ const B1 = B[idx0 + 1];
2045
+ const Th = rotlH(B0, B1, 1) ^ B[idx1];
2046
+ const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
2047
+ for (let y = 0; y < 50; y += 10) {
2048
+ s[x + y] ^= Th;
2049
+ s[x + y + 1] ^= Tl;
2050
+ }
2051
+ }
2052
+ // Rho (ρ) and Pi (π)
2053
+ let curH = s[2];
2054
+ let curL = s[3];
2055
+ for (let t = 0; t < 24; t++) {
2056
+ const shift = SHA3_ROTL[t];
2057
+ const Th = rotlH(curH, curL, shift);
2058
+ const Tl = rotlL(curH, curL, shift);
2059
+ const PI = SHA3_PI[t];
2060
+ curH = s[PI];
2061
+ curL = s[PI + 1];
2062
+ s[PI] = Th;
2063
+ s[PI + 1] = Tl;
2064
+ }
2065
+ // Chi (χ)
2066
+ for (let y = 0; y < 50; y += 10) {
2067
+ for (let x = 0; x < 10; x++)
2068
+ B[x] = s[y + x];
2069
+ for (let x = 0; x < 10; x++)
2070
+ s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
2071
+ }
2072
+ // Iota (ι)
2073
+ s[0] ^= SHA3_IOTA_H[round];
2074
+ s[1] ^= SHA3_IOTA_L[round];
2075
+ }
2076
+ clean(B);
2077
+ }
2078
+ /** Keccak sponge function. */
2079
+ class Keccak extends Hash {
2080
+ // NOTE: we accept arguments in bytes instead of bits here.
2081
+ constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
2082
+ super();
2083
+ this.pos = 0;
2084
+ this.posOut = 0;
2085
+ this.finished = false;
2086
+ this.destroyed = false;
2087
+ this.enableXOF = false;
2088
+ this.blockLen = blockLen;
2089
+ this.suffix = suffix;
2090
+ this.outputLen = outputLen;
2091
+ this.enableXOF = enableXOF;
2092
+ this.rounds = rounds;
2093
+ // Can be passed from user as dkLen
2094
+ anumber(outputLen);
2095
+ // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes
2096
+ // 0 < blockLen < 200
2097
+ if (!(0 < blockLen && blockLen < 200))
2098
+ throw new Error('only keccak-f1600 function is supported');
2099
+ this.state = new Uint8Array(200);
2100
+ this.state32 = u32(this.state);
2101
+ }
2102
+ clone() {
2103
+ return this._cloneInto();
2104
+ }
2105
+ keccak() {
2106
+ swap32IfBE(this.state32);
2107
+ keccakP(this.state32, this.rounds);
2108
+ swap32IfBE(this.state32);
2109
+ this.posOut = 0;
2110
+ this.pos = 0;
2111
+ }
2112
+ update(data) {
2113
+ aexists(this);
2114
+ data = toBytes(data);
2115
+ abytes(data);
2116
+ const { blockLen, state } = this;
2117
+ const len = data.length;
2118
+ for (let pos = 0; pos < len;) {
2119
+ const take = Math.min(blockLen - this.pos, len - pos);
2120
+ for (let i = 0; i < take; i++)
2121
+ state[this.pos++] ^= data[pos++];
2122
+ if (this.pos === blockLen)
2123
+ this.keccak();
2124
+ }
2125
+ return this;
2126
+ }
2127
+ finish() {
2128
+ if (this.finished)
2129
+ return;
2130
+ this.finished = true;
2131
+ const { state, suffix, pos, blockLen } = this;
2132
+ // Do the padding
2133
+ state[pos] ^= suffix;
2134
+ if ((suffix & 0x80) !== 0 && pos === blockLen - 1)
2135
+ this.keccak();
2136
+ state[blockLen - 1] ^= 0x80;
2137
+ this.keccak();
2138
+ }
2139
+ writeInto(out) {
2140
+ aexists(this, false);
2141
+ abytes(out);
2142
+ this.finish();
2143
+ const bufferOut = this.state;
2144
+ const { blockLen } = this;
2145
+ for (let pos = 0, len = out.length; pos < len;) {
2146
+ if (this.posOut >= blockLen)
2147
+ this.keccak();
2148
+ const take = Math.min(blockLen - this.posOut, len - pos);
2149
+ out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
2150
+ this.posOut += take;
2151
+ pos += take;
2152
+ }
2153
+ return out;
2154
+ }
2155
+ xofInto(out) {
2156
+ // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF
2157
+ if (!this.enableXOF)
2158
+ throw new Error('XOF is not possible for this instance');
2159
+ return this.writeInto(out);
2160
+ }
2161
+ xof(bytes) {
2162
+ anumber(bytes);
2163
+ return this.xofInto(new Uint8Array(bytes));
2164
+ }
2165
+ digestInto(out) {
2166
+ aoutput(out, this);
2167
+ if (this.finished)
2168
+ throw new Error('digest() was already called');
2169
+ this.writeInto(out);
2170
+ this.destroy();
2171
+ return out;
2172
+ }
2173
+ digest() {
2174
+ return this.digestInto(new Uint8Array(this.outputLen));
2175
+ }
2176
+ destroy() {
2177
+ this.destroyed = true;
2178
+ clean(this.state);
2179
+ }
2180
+ _cloneInto(to) {
2181
+ const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
2182
+ to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
2183
+ to.state32.set(this.state32);
2184
+ to.pos = this.pos;
2185
+ to.posOut = this.posOut;
2186
+ to.finished = this.finished;
2187
+ to.rounds = rounds;
2188
+ // Suffix can change in cSHAKE
2189
+ to.suffix = suffix;
2190
+ to.outputLen = outputLen;
2191
+ to.enableXOF = enableXOF;
2192
+ to.destroyed = this.destroyed;
2193
+ return to;
2194
+ }
2195
+ }
2196
+ const gen = (suffix, blockLen, outputLen) => createHasher(() => new Keccak(blockLen, suffix, outputLen));
2197
+ /** keccak-256 hash function. Different from SHA3-256. */
2198
+ const keccak_256 = /* @__PURE__ */ (() => gen(0x01, 136, 256 / 8))();
2199
+
2200
+ function keccak256(value, to_) {
2201
+ const bytes = keccak_256(isHex(value, { strict: false }) ? toBytes$1(value) : value);
2202
+ return bytes;
2203
+ }
2204
+
2205
+ const checksumAddressCache = /*#__PURE__*/ new LruMap(8192);
2206
+ function checksumAddress(address_,
2207
+ /**
2208
+ * Warning: EIP-1191 checksum addresses are generally not backwards compatible with the
2209
+ * wider Ethereum ecosystem, meaning it will break when validated against an application/tool
2210
+ * that relies on EIP-55 checksum encoding (checksum without chainId).
2211
+ *
2212
+ * It is highly recommended to not use this feature unless you
2213
+ * know what you are doing.
2214
+ *
2215
+ * See more: https://github.com/ethereum/EIPs/issues/1121
2216
+ */
2217
+ chainId) {
2218
+ if (checksumAddressCache.has(`${address_}.${chainId}`))
2219
+ return checksumAddressCache.get(`${address_}.${chainId}`);
2220
+ const hexAddress = address_.substring(2).toLowerCase();
2221
+ const hash = keccak256(stringToBytes(hexAddress));
2222
+ const address = (hexAddress).split('');
2223
+ for (let i = 0; i < 40; i += 2) {
2224
+ if (hash[i >> 1] >> 4 >= 8 && address[i]) {
2225
+ address[i] = address[i].toUpperCase();
2226
+ }
2227
+ if ((hash[i >> 1] & 0x0f) >= 8 && address[i + 1]) {
2228
+ address[i + 1] = address[i + 1].toUpperCase();
2229
+ }
2230
+ }
2231
+ const result = `0x${address.join('')}`;
2232
+ checksumAddressCache.set(`${address_}.${chainId}`, result);
2233
+ return result;
2234
+ }
2235
+
2236
+ const addressRegex = /^0x[a-fA-F0-9]{40}$/;
2237
+ /** @internal */
2238
+ const isAddressCache = /*#__PURE__*/ new LruMap(8192);
2239
+ function isAddress(address, options) {
2240
+ const { strict = true } = options ?? {};
2241
+ const cacheKey = `${address}.${strict}`;
2242
+ if (isAddressCache.has(cacheKey))
2243
+ return isAddressCache.get(cacheKey);
2244
+ const result = (() => {
2245
+ if (!addressRegex.test(address))
2246
+ return false;
2247
+ if (address.toLowerCase() === address)
2248
+ return true;
2249
+ if (strict)
2250
+ return checksumAddress(address) === address;
2251
+ return true;
2252
+ })();
2253
+ isAddressCache.set(cacheKey, result);
2254
+ return result;
2255
+ }
2256
+
2257
+ /**
2258
+ * @description Returns a section of the hex or byte array given a start/end bytes offset.
2259
+ *
2260
+ * @param value The hex or byte array to slice.
2261
+ * @param start The start offset (in bytes).
2262
+ * @param end The end offset (in bytes).
2263
+ */
2264
+ function slice(value, start, end, { strict } = {}) {
2265
+ if (isHex(value, { strict: false }))
2266
+ return sliceHex(value, start, end, {
2267
+ strict,
2268
+ });
2269
+ return sliceBytes(value, start, end, {
2270
+ strict,
2271
+ });
2272
+ }
2273
+ function assertEndOffset(value, start, end) {
2274
+ if (size(value) !== end - start) {
2275
+ throw new SliceOffsetOutOfBoundsError({
2276
+ offset: end,
2277
+ position: 'end',
2278
+ size: size(value),
2279
+ });
2280
+ }
2281
+ }
2282
+ /**
2283
+ * @description Returns a section of the byte array given a start/end bytes offset.
2284
+ *
2285
+ * @param value The byte array to slice.
2286
+ * @param start The start offset (in bytes).
2287
+ * @param end The end offset (in bytes).
2288
+ */
2289
+ function sliceBytes(value_, start, end, { strict } = {}) {
2290
+ const value = value_.slice(start, end);
2291
+ if (strict)
2292
+ assertEndOffset(value, start, end);
2293
+ return value;
2294
+ }
2295
+ /**
2296
+ * @description Returns a section of the hex value given a start/end bytes offset.
2297
+ *
2298
+ * @param value The hex value to slice.
2299
+ * @param start The start offset (in bytes).
2300
+ * @param end The end offset (in bytes).
2301
+ */
2302
+ function sliceHex(value_, start, end, { strict } = {}) {
2303
+ const value = `0x${value_
2304
+ .replace('0x', '')
2305
+ .slice((start) * 2, (end) * 2)}`;
2306
+ if (strict)
2307
+ assertEndOffset(value, start, end);
2308
+ return value;
2309
+ }
2310
+
2311
+ function assertTransactionEIP7702(transaction) {
2312
+ const { authorizationList } = transaction;
2313
+ if (authorizationList) {
2314
+ for (const authorization of authorizationList) {
2315
+ const { chainId } = authorization;
2316
+ const address = authorization.address;
2317
+ if (!isAddress(address))
2318
+ throw new InvalidAddressError({ address });
2319
+ if (chainId < 0)
2320
+ throw new InvalidChainIdError({ chainId });
2321
+ }
2322
+ }
2323
+ assertTransactionEIP1559(transaction);
2324
+ }
2325
+ function assertTransactionEIP4844(transaction) {
2326
+ const { blobVersionedHashes } = transaction;
2327
+ if (blobVersionedHashes) {
2328
+ if (blobVersionedHashes.length === 0)
2329
+ throw new EmptyBlobError();
2330
+ for (const hash of blobVersionedHashes) {
2331
+ const size_ = size(hash);
2332
+ const version = hexToNumber(slice(hash, 0, 1));
2333
+ if (size_ !== 32)
2334
+ throw new InvalidVersionedHashSizeError({ hash, size: size_ });
2335
+ if (version !== versionedHashVersionKzg)
2336
+ throw new InvalidVersionedHashVersionError({
2337
+ hash,
2338
+ version,
2339
+ });
2340
+ }
2341
+ }
2342
+ assertTransactionEIP1559(transaction);
2343
+ }
2344
+ function assertTransactionEIP1559(transaction) {
2345
+ const { chainId, maxPriorityFeePerGas, maxFeePerGas, to } = transaction;
2346
+ if (chainId <= 0)
2347
+ throw new InvalidChainIdError({ chainId });
2348
+ if (to && !isAddress(to))
2349
+ throw new InvalidAddressError({ address: to });
2350
+ if (maxFeePerGas && maxFeePerGas > maxUint256)
2351
+ throw new FeeCapTooHighError({ maxFeePerGas });
2352
+ if (maxPriorityFeePerGas &&
2353
+ maxFeePerGas &&
2354
+ maxPriorityFeePerGas > maxFeePerGas)
2355
+ throw new TipAboveFeeCapError({ maxFeePerGas, maxPriorityFeePerGas });
2356
+ }
2357
+ function assertTransactionEIP2930(transaction) {
2358
+ const { chainId, maxPriorityFeePerGas, gasPrice, maxFeePerGas, to } = transaction;
2359
+ if (chainId <= 0)
2360
+ throw new InvalidChainIdError({ chainId });
2361
+ if (to && !isAddress(to))
2362
+ throw new InvalidAddressError({ address: to });
2363
+ if (maxPriorityFeePerGas || maxFeePerGas)
2364
+ throw new BaseError('`maxFeePerGas`/`maxPriorityFeePerGas` is not a valid EIP-2930 Transaction attribute.');
2365
+ if (gasPrice && gasPrice > maxUint256)
2366
+ throw new FeeCapTooHighError({ maxFeePerGas: gasPrice });
2367
+ }
2368
+ function assertTransactionLegacy(transaction) {
2369
+ const { chainId, maxPriorityFeePerGas, gasPrice, maxFeePerGas, to } = transaction;
2370
+ if (to && !isAddress(to))
2371
+ throw new InvalidAddressError({ address: to });
2372
+ if (typeof chainId !== 'undefined' && chainId <= 0)
2373
+ throw new InvalidChainIdError({ chainId });
2374
+ if (maxPriorityFeePerGas || maxFeePerGas)
2375
+ throw new BaseError('`maxFeePerGas`/`maxPriorityFeePerGas` is not a valid Legacy Transaction attribute.');
2376
+ if (gasPrice && gasPrice > maxUint256)
2377
+ throw new FeeCapTooHighError({ maxFeePerGas: gasPrice });
2378
+ }
2379
+
2380
+ function getTransactionType(transaction) {
2381
+ if (transaction.type)
2382
+ return transaction.type;
2383
+ if (typeof transaction.authorizationList !== 'undefined')
2384
+ return 'eip7702';
2385
+ if (typeof transaction.blobs !== 'undefined' ||
2386
+ typeof transaction.blobVersionedHashes !== 'undefined' ||
2387
+ typeof transaction.maxFeePerBlobGas !== 'undefined' ||
2388
+ typeof transaction.sidecars !== 'undefined')
2389
+ return 'eip4844';
2390
+ if (typeof transaction.maxFeePerGas !== 'undefined' ||
2391
+ typeof transaction.maxPriorityFeePerGas !== 'undefined') {
2392
+ return 'eip1559';
2393
+ }
2394
+ if (typeof transaction.gasPrice !== 'undefined') {
2395
+ if (typeof transaction.accessList !== 'undefined')
2396
+ return 'eip2930';
2397
+ return 'legacy';
2398
+ }
2399
+ throw new InvalidSerializableTransactionError({ transaction });
2400
+ }
2401
+
2402
+ /*
2403
+ * Serialize an EIP-2930 access list
2404
+ * @remarks
2405
+ * Use to create a transaction serializer with support for EIP-2930 access lists
2406
+ *
2407
+ * @param accessList - Array of objects of address and arrays of Storage Keys
2408
+ * @throws InvalidAddressError, InvalidStorageKeySizeError
2409
+ * @returns Array of hex strings
2410
+ */
2411
+ function serializeAccessList(accessList) {
2412
+ if (!accessList || accessList.length === 0)
2413
+ return [];
2414
+ const serializedAccessList = [];
2415
+ for (let i = 0; i < accessList.length; i++) {
2416
+ const { address, storageKeys } = accessList[i];
2417
+ for (let j = 0; j < storageKeys.length; j++) {
2418
+ if (storageKeys[j].length - 2 !== 64) {
2419
+ throw new InvalidStorageKeySizeError({ storageKey: storageKeys[j] });
2420
+ }
2421
+ }
2422
+ if (!isAddress(address, { strict: false })) {
2423
+ throw new InvalidAddressError({ address });
2424
+ }
2425
+ serializedAccessList.push([address, storageKeys]);
2426
+ }
2427
+ return serializedAccessList;
2428
+ }
2429
+
2430
+ function serializeTransaction$1(transaction, signature) {
2431
+ const type = getTransactionType(transaction);
2432
+ if (type === 'eip1559')
2433
+ return serializeTransactionEIP1559(transaction, signature);
2434
+ if (type === 'eip2930')
2435
+ return serializeTransactionEIP2930(transaction, signature);
2436
+ if (type === 'eip4844')
2437
+ return serializeTransactionEIP4844(transaction, signature);
2438
+ if (type === 'eip7702')
2439
+ return serializeTransactionEIP7702(transaction, signature);
2440
+ return serializeTransactionLegacy(transaction, signature);
2441
+ }
2442
+ function serializeTransactionEIP7702(transaction, signature) {
2443
+ const { authorizationList, chainId, gas, nonce, to, value, maxFeePerGas, maxPriorityFeePerGas, accessList, data, } = transaction;
2444
+ assertTransactionEIP7702(transaction);
2445
+ const serializedAccessList = serializeAccessList(accessList);
2446
+ const serializedAuthorizationList = serializeAuthorizationList(authorizationList);
2447
+ return concatHex([
2448
+ '0x04',
2449
+ toRlp([
2450
+ numberToHex(chainId),
2451
+ nonce ? numberToHex(nonce) : '0x',
2452
+ maxPriorityFeePerGas ? numberToHex(maxPriorityFeePerGas) : '0x',
2453
+ maxFeePerGas ? numberToHex(maxFeePerGas) : '0x',
2454
+ gas ? numberToHex(gas) : '0x',
2455
+ to ?? '0x',
2456
+ value ? numberToHex(value) : '0x',
2457
+ data ?? '0x',
2458
+ serializedAccessList,
2459
+ serializedAuthorizationList,
2460
+ ...toYParitySignatureArray(transaction, signature),
2461
+ ]),
2462
+ ]);
2463
+ }
2464
+ function serializeTransactionEIP4844(transaction, signature) {
2465
+ const { chainId, gas, nonce, to, value, maxFeePerBlobGas, maxFeePerGas, maxPriorityFeePerGas, accessList, data, } = transaction;
2466
+ assertTransactionEIP4844(transaction);
2467
+ let blobVersionedHashes = transaction.blobVersionedHashes;
2468
+ let sidecars = transaction.sidecars;
2469
+ // If `blobs` are passed, we will need to compute the KZG commitments & proofs.
2470
+ if (transaction.blobs &&
2471
+ (typeof blobVersionedHashes === 'undefined' ||
2472
+ typeof sidecars === 'undefined')) {
2473
+ const blobs = (typeof transaction.blobs[0] === 'string'
2474
+ ? transaction.blobs
2475
+ : transaction.blobs.map((x) => bytesToHex(x)));
2476
+ const kzg = transaction.kzg;
2477
+ const commitments = blobsToCommitments({
2478
+ blobs,
2479
+ kzg,
2480
+ });
2481
+ if (typeof blobVersionedHashes === 'undefined')
2482
+ blobVersionedHashes = commitmentsToVersionedHashes({
2483
+ commitments,
2484
+ });
2485
+ if (typeof sidecars === 'undefined') {
2486
+ const proofs = blobsToProofs({ blobs, commitments, kzg });
2487
+ sidecars = toBlobSidecars({ blobs, commitments, proofs });
2488
+ }
2489
+ }
2490
+ const serializedAccessList = serializeAccessList(accessList);
2491
+ const serializedTransaction = [
2492
+ numberToHex(chainId),
2493
+ nonce ? numberToHex(nonce) : '0x',
2494
+ maxPriorityFeePerGas ? numberToHex(maxPriorityFeePerGas) : '0x',
2495
+ maxFeePerGas ? numberToHex(maxFeePerGas) : '0x',
2496
+ gas ? numberToHex(gas) : '0x',
2497
+ to ?? '0x',
2498
+ value ? numberToHex(value) : '0x',
2499
+ data ?? '0x',
2500
+ serializedAccessList,
2501
+ maxFeePerBlobGas ? numberToHex(maxFeePerBlobGas) : '0x',
2502
+ blobVersionedHashes ?? [],
2503
+ ...toYParitySignatureArray(transaction, signature),
2504
+ ];
2505
+ const blobs = [];
2506
+ const commitments = [];
2507
+ const proofs = [];
2508
+ if (sidecars)
2509
+ for (let i = 0; i < sidecars.length; i++) {
2510
+ const { blob, commitment, proof } = sidecars[i];
2511
+ blobs.push(blob);
2512
+ commitments.push(commitment);
2513
+ proofs.push(proof);
2514
+ }
2515
+ return concatHex([
2516
+ '0x03',
2517
+ sidecars
2518
+ ? // If sidecars are enabled, envelope turns into a "wrapper":
2519
+ toRlp([serializedTransaction, blobs, commitments, proofs])
2520
+ : // If sidecars are disabled, standard envelope is used:
2521
+ toRlp(serializedTransaction),
2522
+ ]);
2523
+ }
2524
+ function serializeTransactionEIP1559(transaction, signature) {
2525
+ const { chainId, gas, nonce, to, value, maxFeePerGas, maxPriorityFeePerGas, accessList, data, } = transaction;
2526
+ assertTransactionEIP1559(transaction);
2527
+ const serializedAccessList = serializeAccessList(accessList);
2528
+ const serializedTransaction = [
2529
+ numberToHex(chainId),
2530
+ nonce ? numberToHex(nonce) : '0x',
2531
+ maxPriorityFeePerGas ? numberToHex(maxPriorityFeePerGas) : '0x',
2532
+ maxFeePerGas ? numberToHex(maxFeePerGas) : '0x',
2533
+ gas ? numberToHex(gas) : '0x',
2534
+ to ?? '0x',
2535
+ value ? numberToHex(value) : '0x',
2536
+ data ?? '0x',
2537
+ serializedAccessList,
2538
+ ...toYParitySignatureArray(transaction, signature),
2539
+ ];
2540
+ return concatHex([
2541
+ '0x02',
2542
+ toRlp(serializedTransaction),
2543
+ ]);
2544
+ }
2545
+ function serializeTransactionEIP2930(transaction, signature) {
2546
+ const { chainId, gas, data, nonce, to, value, accessList, gasPrice } = transaction;
2547
+ assertTransactionEIP2930(transaction);
2548
+ const serializedAccessList = serializeAccessList(accessList);
2549
+ const serializedTransaction = [
2550
+ numberToHex(chainId),
2551
+ nonce ? numberToHex(nonce) : '0x',
2552
+ gasPrice ? numberToHex(gasPrice) : '0x',
2553
+ gas ? numberToHex(gas) : '0x',
2554
+ to ?? '0x',
2555
+ value ? numberToHex(value) : '0x',
2556
+ data ?? '0x',
2557
+ serializedAccessList,
2558
+ ...toYParitySignatureArray(transaction, signature),
2559
+ ];
2560
+ return concatHex([
2561
+ '0x01',
2562
+ toRlp(serializedTransaction),
2563
+ ]);
2564
+ }
2565
+ function serializeTransactionLegacy(transaction, signature) {
2566
+ const { chainId = 0, gas, data, nonce, to, value, gasPrice } = transaction;
2567
+ assertTransactionLegacy(transaction);
2568
+ let serializedTransaction = [
2569
+ nonce ? numberToHex(nonce) : '0x',
2570
+ gasPrice ? numberToHex(gasPrice) : '0x',
2571
+ gas ? numberToHex(gas) : '0x',
2572
+ to ?? '0x',
2573
+ value ? numberToHex(value) : '0x',
2574
+ data ?? '0x',
2575
+ ];
2576
+ if (signature) {
2577
+ const v = (() => {
2578
+ // EIP-155 (inferred chainId)
2579
+ if (signature.v >= 35n) {
2580
+ const inferredChainId = (signature.v - 35n) / 2n;
2581
+ if (inferredChainId > 0)
2582
+ return signature.v;
2583
+ return 27n + (signature.v === 35n ? 0n : 1n);
2584
+ }
2585
+ // EIP-155 (explicit chainId)
2586
+ if (chainId > 0)
2587
+ return BigInt(chainId * 2) + BigInt(35n + signature.v - 27n);
2588
+ // Pre-EIP-155 (no chainId)
2589
+ const v = 27n + (signature.v === 27n ? 0n : 1n);
2590
+ if (signature.v !== v)
2591
+ throw new InvalidLegacyVError({ v: signature.v });
2592
+ return v;
2593
+ })();
2594
+ const r = trim(signature.r);
2595
+ const s = trim(signature.s);
2596
+ serializedTransaction = [
2597
+ ...serializedTransaction,
2598
+ numberToHex(v),
2599
+ r === '0x00' ? '0x' : r,
2600
+ s === '0x00' ? '0x' : s,
2601
+ ];
2602
+ }
2603
+ else if (chainId > 0) {
2604
+ serializedTransaction = [
2605
+ ...serializedTransaction,
2606
+ numberToHex(chainId),
2607
+ '0x',
2608
+ '0x',
2609
+ ];
2610
+ }
2611
+ return toRlp(serializedTransaction);
2612
+ }
2613
+ function toYParitySignatureArray(transaction, signature_) {
2614
+ const signature = signature_ ?? transaction;
2615
+ const { v, yParity } = signature;
2616
+ if (typeof signature.r === 'undefined')
2617
+ return [];
2618
+ if (typeof signature.s === 'undefined')
2619
+ return [];
2620
+ if (typeof v === 'undefined' && typeof yParity === 'undefined')
2621
+ return [];
2622
+ const r = trim(signature.r);
2623
+ const s = trim(signature.s);
2624
+ const yParity_ = (() => {
2625
+ if (typeof yParity === 'number')
2626
+ return yParity ? numberToHex(1) : '0x';
2627
+ if (v === 0n)
2628
+ return '0x';
2629
+ if (v === 1n)
2630
+ return numberToHex(1);
2631
+ return v === 27n ? '0x' : numberToHex(1);
2632
+ })();
2633
+ return [yParity_, r === '0x00' ? '0x' : r, s === '0x00' ? '0x' : s];
2634
+ }
2635
+
2636
+ /**
2637
+ * Predeploy contracts for OP Stack.
2638
+ * @see https://github.com/ethereum-optimism/optimism/blob/develop/specs/predeploys.md
2639
+ */
2640
+ const contracts = {
2641
+ gasPriceOracle: { address: '0x420000000000000000000000000000000000000F' },
2642
+ l1Block: { address: '0x4200000000000000000000000000000000000015' },
2643
+ l2CrossDomainMessenger: {
2644
+ address: '0x4200000000000000000000000000000000000007',
2645
+ },
2646
+ l2Erc721Bridge: { address: '0x4200000000000000000000000000000000000014' },
2647
+ l2StandardBridge: { address: '0x4200000000000000000000000000000000000010' },
2648
+ l2ToL1MessagePasser: {
2649
+ address: '0x4200000000000000000000000000000000000016',
2650
+ },
2651
+ };
2652
+
2653
+ const formatters = {
2654
+ block: /*#__PURE__*/ defineBlock({
2655
+ format(args) {
2656
+ const transactions = args.transactions?.map((transaction) => {
2657
+ if (typeof transaction === 'string')
2658
+ return transaction;
2659
+ const formatted = formatTransaction(transaction);
2660
+ if (formatted.typeHex === '0x7e') {
2661
+ formatted.isSystemTx = transaction.isSystemTx;
2662
+ formatted.mint = transaction.mint
2663
+ ? hexToBigInt(transaction.mint)
2664
+ : undefined;
2665
+ formatted.sourceHash = transaction.sourceHash;
2666
+ formatted.type = 'deposit';
2667
+ }
2668
+ return formatted;
2669
+ });
2670
+ return {
2671
+ transactions,
2672
+ stateRoot: args.stateRoot,
2673
+ };
2674
+ },
2675
+ }),
2676
+ transaction: /*#__PURE__*/ defineTransaction({
2677
+ format(args) {
2678
+ const transaction = {};
2679
+ if (args.type === '0x7e') {
2680
+ transaction.isSystemTx = args.isSystemTx;
2681
+ transaction.mint = args.mint ? hexToBigInt(args.mint) : undefined;
2682
+ transaction.sourceHash = args.sourceHash;
2683
+ transaction.type = 'deposit';
2684
+ }
2685
+ return transaction;
2686
+ },
2687
+ }),
2688
+ transactionReceipt: /*#__PURE__*/ defineTransactionReceipt({
2689
+ format(args) {
2690
+ return {
2691
+ l1GasPrice: args.l1GasPrice ? hexToBigInt(args.l1GasPrice) : null,
2692
+ l1GasUsed: args.l1GasUsed ? hexToBigInt(args.l1GasUsed) : null,
2693
+ l1Fee: args.l1Fee ? hexToBigInt(args.l1Fee) : null,
2694
+ l1FeeScalar: args.l1FeeScalar ? Number(args.l1FeeScalar) : null,
2695
+ };
2696
+ },
2697
+ }),
2698
+ };
2699
+
2700
+ function serializeTransaction(transaction, signature) {
2701
+ if (isDeposit(transaction))
2702
+ return serializeTransactionDeposit(transaction);
2703
+ return serializeTransaction$1(transaction, signature);
2704
+ }
2705
+ const serializers = {
2706
+ transaction: serializeTransaction,
2707
+ };
2708
+ function serializeTransactionDeposit(transaction) {
2709
+ assertTransactionDeposit(transaction);
2710
+ const { sourceHash, data, from, gas, isSystemTx, mint, to, value } = transaction;
2711
+ const serializedTransaction = [
2712
+ sourceHash,
2713
+ from,
2714
+ to ?? '0x',
2715
+ mint ? toHex(mint) : '0x',
2716
+ value ? toHex(value) : '0x',
2717
+ gas ? toHex(gas) : '0x',
2718
+ isSystemTx ? '0x1' : '0x',
2719
+ data ?? '0x',
2720
+ ];
2721
+ return concatHex([
2722
+ '0x7e',
2723
+ toRlp(serializedTransaction),
2724
+ ]);
2725
+ }
2726
+ function isDeposit(transaction) {
2727
+ if (transaction.type === 'deposit')
2728
+ return true;
2729
+ if (typeof transaction.sourceHash !== 'undefined')
2730
+ return true;
2731
+ return false;
2732
+ }
2733
+ function assertTransactionDeposit(transaction) {
2734
+ const { from, to } = transaction;
2735
+ if (from && !isAddress(from))
2736
+ throw new InvalidAddressError({ address: from });
2737
+ if (to && !isAddress(to))
2738
+ throw new InvalidAddressError({ address: to });
2739
+ }
2740
+
2741
+ const chainConfig = {
2742
+ blockTime: 2_000,
2743
+ contracts,
2744
+ formatters,
2745
+ serializers,
2746
+ };
2747
+
2748
+ const sourceId$1 = 1; // mainnet
2749
+ const base = /*#__PURE__*/ defineChain({
2750
+ ...chainConfig,
2751
+ id: 8453,
2752
+ name: 'Base',
2753
+ nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
2754
+ rpcUrls: {
2755
+ default: {
2756
+ http: ['https://mainnet.base.org'],
2757
+ },
2758
+ },
2759
+ blockExplorers: {
2760
+ default: {
2761
+ name: 'Basescan',
2762
+ url: 'https://basescan.org',
2763
+ apiUrl: 'https://api.basescan.org/api',
2764
+ },
2765
+ },
2766
+ contracts: {
2767
+ ...chainConfig.contracts,
2768
+ disputeGameFactory: {
2769
+ [sourceId$1]: {
2770
+ address: '0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e',
2771
+ },
2772
+ },
2773
+ l2OutputOracle: {
2774
+ [sourceId$1]: {
2775
+ address: '0x56315b90c40730925ec5485cf004d835058518A0',
2776
+ },
2777
+ },
2778
+ multicall3: {
2779
+ address: '0xca11bde05977b3631167028862be2a173976ca11',
2780
+ blockCreated: 5022,
2781
+ },
2782
+ portal: {
2783
+ [sourceId$1]: {
2784
+ address: '0x49048044D57e1C92A77f79988d21Fa8fAF74E97e',
2785
+ blockCreated: 17482143,
2786
+ },
2787
+ },
2788
+ l1StandardBridge: {
2789
+ [sourceId$1]: {
2790
+ address: '0x3154Cf16ccdb4C6d922629664174b904d80F2C35',
2791
+ blockCreated: 17482143,
2792
+ },
2793
+ },
2794
+ },
2795
+ sourceId: sourceId$1,
2796
+ });
2797
+ /*#__PURE__*/ defineChain({
2798
+ ...base,
2799
+ experimental_preconfirmationTime: 200,
2800
+ rpcUrls: {
2801
+ default: {
2802
+ http: ['https://mainnet-preconf.base.org'],
2803
+ },
2804
+ },
2805
+ });
2806
+
2807
+ const sourceId = 11_155_111; // sepolia
2808
+ const baseSepolia = /*#__PURE__*/ defineChain({
2809
+ ...chainConfig,
2810
+ id: 84532,
2811
+ network: 'base-sepolia',
2812
+ name: 'Base Sepolia',
2813
+ nativeCurrency: { name: 'Sepolia Ether', symbol: 'ETH', decimals: 18 },
2814
+ rpcUrls: {
2815
+ default: {
2816
+ http: ['https://sepolia.base.org'],
2817
+ },
2818
+ },
2819
+ blockExplorers: {
2820
+ default: {
2821
+ name: 'Basescan',
2822
+ url: 'https://sepolia.basescan.org',
2823
+ apiUrl: 'https://api-sepolia.basescan.org/api',
2824
+ },
2825
+ },
2826
+ contracts: {
2827
+ ...chainConfig.contracts,
2828
+ disputeGameFactory: {
2829
+ [sourceId]: {
2830
+ address: '0xd6E6dBf4F7EA0ac412fD8b65ED297e64BB7a06E1',
2831
+ },
2832
+ },
2833
+ l2OutputOracle: {
2834
+ [sourceId]: {
2835
+ address: '0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254',
2836
+ },
2837
+ },
2838
+ portal: {
2839
+ [sourceId]: {
2840
+ address: '0x49f53e41452c74589e85ca1677426ba426459e85',
2841
+ blockCreated: 4446677,
2842
+ },
2843
+ },
2844
+ l1StandardBridge: {
2845
+ [sourceId]: {
2846
+ address: '0xfd0Bf71F60660E2f608ed56e1659C450eB113120',
2847
+ blockCreated: 4446677,
2848
+ },
2849
+ },
2850
+ multicall3: {
2851
+ address: '0xca11bde05977b3631167028862be2a173976ca11',
2852
+ blockCreated: 1059647,
2853
+ },
2854
+ },
2855
+ testnet: true,
2856
+ sourceId,
2857
+ });
2858
+ /*#__PURE__*/ defineChain({
2859
+ ...baseSepolia,
2860
+ experimental_preconfirmationTime: 200,
2861
+ rpcUrls: {
2862
+ default: {
2863
+ http: ['https://sepolia-preconf.base.org'],
2864
+ },
2865
+ },
2866
+ });
2867
+
2868
+ const mainnet = /*#__PURE__*/ defineChain({
2869
+ id: 1,
2870
+ name: 'Ethereum',
2871
+ nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
2872
+ blockTime: 12_000,
2873
+ rpcUrls: {
2874
+ default: {
2875
+ http: ['https://eth.merkle.io'],
2876
+ },
2877
+ },
2878
+ blockExplorers: {
2879
+ default: {
2880
+ name: 'Etherscan',
2881
+ url: 'https://etherscan.io',
2882
+ apiUrl: 'https://api.etherscan.io/api',
2883
+ },
2884
+ },
2885
+ contracts: {
2886
+ ensUniversalResolver: {
2887
+ address: '0xeeeeeeee14d718c2b47d9923deab1335e144eeee',
2888
+ blockCreated: 23_085_558,
2889
+ },
2890
+ multicall3: {
2891
+ address: '0xca11bde05977b3631167028862be2a173976ca11',
2892
+ blockCreated: 14_353_601,
2893
+ },
2894
+ },
2895
+ });
2896
+
2897
+ const sepolia = /*#__PURE__*/ defineChain({
2898
+ id: 11_155_111,
2899
+ name: 'Sepolia',
2900
+ nativeCurrency: { name: 'Sepolia Ether', symbol: 'ETH', decimals: 18 },
2901
+ rpcUrls: {
2902
+ default: {
2903
+ http: ['https://11155111.rpc.thirdweb.com'],
2904
+ },
2905
+ },
2906
+ blockExplorers: {
2907
+ default: {
2908
+ name: 'Etherscan',
2909
+ url: 'https://sepolia.etherscan.io',
2910
+ apiUrl: 'https://api-sepolia.etherscan.io/api',
2911
+ },
2912
+ },
2913
+ contracts: {
2914
+ multicall3: {
2915
+ address: '0xca11bde05977b3631167028862be2a173976ca11',
2916
+ blockCreated: 751532,
2917
+ },
2918
+ ensUniversalResolver: {
2919
+ address: '0xeeeeeeee14d718c2b47d9923deab1335e144eeee',
2920
+ blockCreated: 8_928_790,
2921
+ },
2922
+ },
2923
+ testnet: true,
2924
+ });
2925
+
2926
+ /**
2927
+ * Maps AgentKit network IDs to Lombard SDK ChainId values.
2928
+ *
2929
+ * Only includes networks where Lombard contracts are deployed.
2930
+ */ const NETWORK_ID_TO_LOMBARD_CHAIN = {
2931
+ "ethereum-mainnet": ChainId.ethereum,
2932
+ "ethereum-sepolia": ChainId.sepolia,
2933
+ "base-mainnet": ChainId.base,
2934
+ "base-sepolia": ChainId.baseSepoliaTestnet
2935
+ };
2936
+ /**
2937
+ * Maps AgentKit network IDs to Lombard SDK Env values.
2938
+ */ const NETWORK_ID_TO_ENV = {
2939
+ "ethereum-mainnet": Env.prod,
2940
+ "ethereum-sepolia": Env.testnet,
2941
+ "base-mainnet": Env.prod,
2942
+ "base-sepolia": Env.testnet
2943
+ };
2944
+ /**
2945
+ * Maps AgentKit network IDs to viem `Chain` objects, for callers that need
2946
+ * to construct a wallet/public client outside of the action provider.
2947
+ */ const NETWORK_ID_TO_VIEM_CHAIN = {
2948
+ "ethereum-mainnet": mainnet,
2949
+ "ethereum-sepolia": sepolia,
2950
+ "base-mainnet": base,
2951
+ "base-sepolia": baseSepolia
2952
+ };
2953
+ /**
2954
+ * Resolves an AgentKit Network to Lombard SDK chain parameters.
2955
+ *
2956
+ * @returns ResolvedNetwork or null if the network is not supported
2957
+ */ function resolveNetwork(network) {
2958
+ const networkId = network.networkId;
2959
+ if (!networkId) return null;
2960
+ const chainId = NETWORK_ID_TO_LOMBARD_CHAIN[networkId];
2961
+ const env = NETWORK_ID_TO_ENV[networkId];
2962
+ if (chainId === undefined || !env) return null;
2963
+ return {
2964
+ chainId,
2965
+ env,
2966
+ networkId
2967
+ };
2968
+ }
2969
+ /**
2970
+ * Resolves a user-supplied chain name string to Lombard SDK chain parameters.
2971
+ *
2972
+ * Accepts both AgentKit network IDs (e.g., "ethereum-mainnet") and
2973
+ * friendly names (e.g., "ethereum", "base-sepolia").
2974
+ */ function resolveChainName(chainName) {
2975
+ const normalized = chainName.toLowerCase().trim();
2976
+ // Try direct match on network ID
2977
+ if (NETWORK_ID_TO_LOMBARD_CHAIN[normalized] !== undefined) {
2978
+ return {
2979
+ chainId: NETWORK_ID_TO_LOMBARD_CHAIN[normalized],
2980
+ env: NETWORK_ID_TO_ENV[normalized],
2981
+ networkId: normalized
2982
+ };
2983
+ }
2984
+ // Friendly name aliases
2985
+ const aliases = {
2986
+ ethereum: "ethereum-mainnet",
2987
+ eth: "ethereum-mainnet",
2988
+ mainnet: "ethereum-mainnet",
2989
+ sepolia: "ethereum-sepolia",
2990
+ base: "base-mainnet",
2991
+ "base-sep": "base-sepolia"
2992
+ };
2993
+ const resolved = aliases[normalized];
2994
+ if (resolved && NETWORK_ID_TO_LOMBARD_CHAIN[resolved] !== undefined) {
2995
+ return {
2996
+ chainId: NETWORK_ID_TO_LOMBARD_CHAIN[resolved],
2997
+ env: NETWORK_ID_TO_ENV[resolved],
2998
+ networkId: resolved
2999
+ };
3000
+ }
3001
+ return null;
3002
+ }
3003
+ /**
3004
+ * Checks if a given AgentKit Network is supported by the Lombard provider.
3005
+ */ function isLombardSupportedNetwork(network) {
3006
+ return resolveNetwork(network) !== null;
3007
+ }
3008
+
3009
+ const StakeBtcbToLbtcSchema = z.object({
3010
+ amount: z.string().describe("Amount of BTC.b to stake in human-readable format (e.g. '0.1' for 0.1 BTC.b). Will be converted to LBTC.").refine((v)=>/^\d+(\.\d+)?$/.test(v), "Amount must be a numeric string").refine((v)=>parseFloat(v) > 0, "Amount must be positive").refine((v)=>parseFloat(v) < 1000, "Amount must be under 1000 BTC")
3011
+ });
3012
+ const UnstakeLbtcSchema = z.object({
3013
+ amount: z.string().describe("Amount of LBTC to unstake in human-readable format (e.g. '0.1')").refine((v)=>/^\d+(\.\d+)?$/.test(v), "Amount must be a numeric string").refine((v)=>parseFloat(v) > 0, "Amount must be positive").refine((v)=>parseFloat(v) < 1000, "Amount must be under 1000 BTC"),
3014
+ recipient: z.string().describe("Destination address. For BTC output, use a Bitcoin address (e.g. bc1q...). For BTCb output, use an EVM address (e.g. 0x...).").refine((v)=>/^0x[a-fA-F0-9]{40}$/.test(v) || /^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,62}$/.test(v), "Invalid address: must be an EVM address (0x...) or a Bitcoin address (bc1.../1.../3...)"),
3015
+ outputAsset: z.enum([
3016
+ "BTC",
3017
+ "BTCb"
3018
+ ]).describe("Output asset: 'BTC' for native Bitcoin (cross-chain, takes longer), 'BTCb' for wrapped BTC on the same EVM chain (faster)")
3019
+ });
3020
+ const RedeemLbtcToBtcbSchema = z.object({
3021
+ amount: z.string().describe("Amount of LBTC to redeem in human-readable format (e.g. '0.1'). Will be converted to BTC.b on the same chain.").refine((v)=>/^\d+(\.\d+)?$/.test(v), "Amount must be a numeric string").refine((v)=>parseFloat(v) > 0, "Amount must be positive").refine((v)=>parseFloat(v) < 1000, "Amount must be under 1000 BTC")
3022
+ });
3023
+ const DeployToDefiSchema = z.object({
3024
+ amount: z.string().describe("Amount to deploy in human-readable format (e.g. '0.1')").refine((v)=>/^\d+(\.\d+)?$/.test(v), "Amount must be a numeric string").refine((v)=>parseFloat(v) > 0, "Amount must be positive").refine((v)=>parseFloat(v) < 1000, "Amount must be under 1000 BTC")
3025
+ });
3026
+ const ClaimDepositSchema = z.object({
3027
+ depositTxHash: z.string().describe("Transaction hash of the original deposit to claim. Use get_deposit_status first to check if the deposit is claimable.")
3028
+ });
3029
+ const GetLbtcBalanceSchema = z.object({
3030
+ address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid EVM address").optional().describe("EVM address to check balance for. If omitted, uses the connected wallet address.")
3031
+ });
3032
+ const GetBtcbBalanceSchema = z.object({
3033
+ address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid EVM address").optional().describe("EVM address to check balance for. If omitted, uses the connected wallet address.")
3034
+ });
3035
+ const GetLbtcExchangeRateSchema = z.object({});
3036
+ const GetDepositStatusSchema = z.object({
3037
+ address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid EVM address").optional().describe("EVM address to check deposits for. If omitted, uses the connected wallet address.")
3038
+ });
3039
+ const GetUnstakeStatusSchema = z.object({
3040
+ address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid EVM address").optional().describe("EVM address to check unstakes for. If omitted, uses the connected wallet address.")
3041
+ });
3042
+
3043
+ /**
3044
+ * Adapts a Coinbase AgentKit EvmWalletProvider into a viem-compatible
3045
+ * EIP1193Provider that the Lombard SDK contract functions expect.
3046
+ *
3047
+ * The adapter implements the `request` method by delegating to the
3048
+ * appropriate EvmWalletProvider method for each JSON-RPC call.
3049
+ */ function toEIP1193Provider(walletProvider, chainId) {
3050
+ const chain = CHAIN_ID_TO_VIEM_CHAIN_MAP[chainId];
3051
+ // Use the SDK's makePublicClient for reliable RPC calls
3052
+ const publicClient = chain ? makePublicClient({
3053
+ chainId
3054
+ }) : null;
3055
+ // Use a Proxy to implement the EIP1193 request interface.
3056
+ // This avoids complex viem type gymnastics while correctly routing
3057
+ // wallet operations to the AgentKit provider and reads to a public client.
3058
+ const handler = async ({ method, params })=>{
3059
+ switch(method){
3060
+ case "eth_accounts":
3061
+ return [
3062
+ walletProvider.getAddress()
3063
+ ];
3064
+ case "eth_chainId":
3065
+ return `0x${chainId.toString(16)}`;
3066
+ case "eth_sendTransaction":
3067
+ {
3068
+ if (!params || params.length === 0) {
3069
+ throw new Error("eth_sendTransaction requires transaction parameter");
3070
+ }
3071
+ const tx = params[0];
3072
+ return walletProvider.sendTransaction({
3073
+ to: tx.to,
3074
+ value: tx.value ? BigInt(tx.value) : undefined,
3075
+ data: tx.data,
3076
+ gas: tx.gas ? BigInt(tx.gas) : undefined
3077
+ });
3078
+ }
3079
+ case "personal_sign":
3080
+ {
3081
+ const [message] = params;
3082
+ return walletProvider.signMessage(message);
3083
+ }
3084
+ case "eth_signTypedData_v4":
3085
+ {
3086
+ const [, typedDataJson] = params;
3087
+ const typedData = typeof typedDataJson === "string" ? JSON.parse(typedDataJson) : typedDataJson;
3088
+ return walletProvider.signTypedData(typedData);
3089
+ }
3090
+ default:
3091
+ {
3092
+ if (!publicClient) {
3093
+ throw new Error(`Unsupported RPC method: ${method}`);
3094
+ }
3095
+ return publicClient.request({
3096
+ method,
3097
+ params
3098
+ });
3099
+ }
3100
+ }
3101
+ };
3102
+ return {
3103
+ request: handler
3104
+ };
3105
+ }
3106
+ /**
3107
+ * Reads an ERC20 token balance using the AgentKit wallet provider's
3108
+ * readContract method directly (avoids needing EIP1193 adapter for reads).
3109
+ */ async function getTokenBalance(walletProvider, token, chainId, address, env) {
3110
+ const tokenInfo = await getTokenContractInfo(token, chainId, env);
3111
+ const tokenAddress = tokenInfo.address;
3112
+ const balance = await walletProvider.readContract({
3113
+ address: tokenAddress,
3114
+ abi: [
3115
+ {
3116
+ name: "balanceOf",
3117
+ type: "function",
3118
+ stateMutability: "view",
3119
+ inputs: [
3120
+ {
3121
+ name: "account",
3122
+ type: "address"
3123
+ }
3124
+ ],
3125
+ outputs: [
3126
+ {
3127
+ name: "",
3128
+ type: "uint256"
3129
+ }
3130
+ ]
3131
+ }
3132
+ ],
3133
+ functionName: "balanceOf",
3134
+ args: [
3135
+ address
3136
+ ]
3137
+ });
3138
+ // Use decimals from token info when available, default to 8 for BTC-like tokens
3139
+ const decimals = "decimals" in tokenInfo && typeof tokenInfo.decimals === "number" ? tokenInfo.decimals : 8;
3140
+ const formatted = formatUnits$1(balance, decimals);
3141
+ return {
3142
+ balance: balance,
3143
+ formatted,
3144
+ decimals
3145
+ };
3146
+ }
3147
+ /**
3148
+ * Format a result string for AgentKit action responses.
3149
+ */ function formatSuccess(action, details) {
3150
+ return JSON.stringify({
3151
+ success: true,
3152
+ action,
3153
+ ...details
3154
+ });
3155
+ }
3156
+ function formatError(action, error) {
3157
+ let message;
3158
+ if (error instanceof Error) {
3159
+ // Strip RPC URLs and internal details
3160
+ message = error.message.replace(/https?:\/\/[^\s]+/g, "[redacted-url]").replace(/0x[a-fA-F0-9]{64,}/g, "[redacted-data]");
3161
+ } else {
3162
+ message = String(error);
3163
+ }
3164
+ return JSON.stringify({
3165
+ success: false,
3166
+ action,
3167
+ error: message
3168
+ });
3169
+ }
3170
+
3171
+ function _ts_decorate(decorators, target, key, desc) {
3172
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3173
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3174
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3175
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
3176
+ }
3177
+ function _ts_metadata(k, v) {
3178
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3179
+ }
3180
+ /**
3181
+ * LombardActionProvider exposes Lombard protocol operations
3182
+ * (stake, unstake, redeem, deploy, claim) as Coinbase AgentKit actions.
3183
+ *
3184
+ * SECURITY: This provider executes real transactions. Configure your wallet
3185
+ * provider with appropriate spending limits. All amounts are validated to be
3186
+ * positive numeric strings under 1000 BTC equivalent.
3187
+ *
3188
+ * Usage:
3189
+ * ```ts
3190
+ * import { lombardActionProvider } from '@lombard.finance/sdk-agentkit';
3191
+ *
3192
+ * const agentkit = await AgentKit.from({
3193
+ * walletProvider,
3194
+ * actionProviders: [lombardActionProvider()],
3195
+ * });
3196
+ * ```
3197
+ */ class LombardActionProvider extends ActionProvider {
3198
+ constructor(){
3199
+ super("lombard", []);
3200
+ }
3201
+ supportsNetwork = (network)=>{
3202
+ return isLombardSupportedNetwork(network);
3203
+ };
3204
+ // ─── Write Actions ──────────────────────────────────────────────────
3205
+ async stakeBtcbToLbtc(walletProvider, args) {
3206
+ try {
3207
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3208
+ if (!resolved) {
3209
+ return formatError("stake_btcb_to_lbtc", "Current network is not supported by Lombard");
3210
+ }
3211
+ const { chainId, env } = resolved;
3212
+ const account = walletProvider.getAddress();
3213
+ const provider = toEIP1193Provider(walletProvider, chainId);
3214
+ // Handle fee authorization for chains that require it
3215
+ await this.ensureFeeAuthorization(walletProvider, chainId, env, account, provider);
3216
+ // Check allowance and approve if needed
3217
+ const routerAddress = await getAssetRouterAddress({
3218
+ tokenIn: Token.BTCb,
3219
+ chainId,
3220
+ env
3221
+ });
3222
+ const allowance = await getTokenAllowance({
3223
+ token: Token.BTCb,
3224
+ owner: account,
3225
+ spender: routerAddress,
3226
+ chainId,
3227
+ env
3228
+ });
3229
+ if (allowance.isLessThan(args.amount)) {
3230
+ await approveToken({
3231
+ token: Token.BTCb,
3232
+ spender: routerAddress,
3233
+ amount: args.amount,
3234
+ account,
3235
+ chainId,
3236
+ provider,
3237
+ env
3238
+ });
3239
+ }
3240
+ const txHash = await depositToken({
3241
+ amount: args.amount,
3242
+ tokenIn: Token.BTCb,
3243
+ tokenOut: Token.LBTC,
3244
+ account,
3245
+ chainId,
3246
+ provider,
3247
+ env
3248
+ });
3249
+ return formatSuccess("stake_btcb_to_lbtc", {
3250
+ txHash,
3251
+ amount: args.amount,
3252
+ from: "BTC.b",
3253
+ to: "LBTC"
3254
+ });
3255
+ } catch (error) {
3256
+ return formatError("stake_btcb_to_lbtc", error);
3257
+ }
3258
+ }
3259
+ async unstakeLbtc(walletProvider, args) {
3260
+ try {
3261
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3262
+ if (!resolved) {
3263
+ return formatError("unstake_lbtc", "Current network is not supported by Lombard");
3264
+ }
3265
+ const { chainId, env } = resolved;
3266
+ const account = walletProvider.getAddress();
3267
+ const provider = toEIP1193Provider(walletProvider, chainId);
3268
+ // Handle fee authorization for chains that require it
3269
+ await this.ensureFeeAuthorization(walletProvider, chainId, env, account, provider);
3270
+ if (args.outputAsset === "BTC") {
3271
+ const txHash = await unstakeLBTC({
3272
+ amount: args.amount,
3273
+ btcAddress: args.recipient,
3274
+ tokenIn: Token.LBTC,
3275
+ account,
3276
+ chainId,
3277
+ provider,
3278
+ env
3279
+ });
3280
+ return formatSuccess("unstake_lbtc", {
3281
+ txHash,
3282
+ amount: args.amount,
3283
+ to: "BTC",
3284
+ recipient: args.recipient,
3285
+ note: "Cross-chain unstake initiated. BTC will arrive after processing (may take hours)."
3286
+ });
3287
+ }
3288
+ // BTCb output - same chain redeem (always sends to caller's address)
3289
+ const txHash = await redeemToken({
3290
+ amount: args.amount,
3291
+ tokenIn: Token.LBTC,
3292
+ tokenOut: Token.BTCb,
3293
+ account,
3294
+ chainId,
3295
+ provider,
3296
+ env
3297
+ });
3298
+ const result = {
3299
+ txHash,
3300
+ amount: args.amount,
3301
+ to: "BTC.b"
3302
+ };
3303
+ if (args.recipient && args.recipient.toLowerCase() !== account.toLowerCase()) {
3304
+ result.warning = "BTC.b redemption always sends to the connected wallet. The recipient address was ignored.";
3305
+ }
3306
+ return formatSuccess("unstake_lbtc", result);
3307
+ } catch (error) {
3308
+ return formatError("unstake_lbtc", error);
3309
+ }
3310
+ }
3311
+ async redeemLbtcToBtcb(walletProvider, args) {
3312
+ try {
3313
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3314
+ if (!resolved) {
3315
+ return formatError("redeem_lbtc_to_btcb", "Current network is not supported by Lombard");
3316
+ }
3317
+ const { chainId, env } = resolved;
3318
+ const account = walletProvider.getAddress();
3319
+ const provider = toEIP1193Provider(walletProvider, chainId);
3320
+ await this.ensureFeeAuthorization(walletProvider, chainId, env, account, provider);
3321
+ const txHash = await redeemToken({
3322
+ amount: args.amount,
3323
+ tokenIn: Token.LBTC,
3324
+ tokenOut: Token.BTCb,
3325
+ account,
3326
+ chainId,
3327
+ provider,
3328
+ env
3329
+ });
3330
+ return formatSuccess("redeem_lbtc_to_btcb", {
3331
+ txHash,
3332
+ amount: args.amount,
3333
+ from: "LBTC",
3334
+ to: "BTC.b"
3335
+ });
3336
+ } catch (error) {
3337
+ return formatError("redeem_lbtc_to_btcb", error);
3338
+ }
3339
+ }
3340
+ async deployToDefi(walletProvider, args) {
3341
+ try {
3342
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3343
+ if (!resolved) {
3344
+ return formatError("deploy_to_defi", "Current network is not supported by Lombard");
3345
+ }
3346
+ const { chainId } = resolved;
3347
+ const account = walletProvider.getAddress();
3348
+ const provider = toEIP1193Provider(walletProvider, chainId);
3349
+ const txHash = await depositEarn({
3350
+ amount: args.amount,
3351
+ approve: true,
3352
+ token: Token.LBTC,
3353
+ account,
3354
+ chainId,
3355
+ provider,
3356
+ rpcUrl: undefined,
3357
+ env: resolved.env
3358
+ });
3359
+ return formatSuccess("deploy_to_defi", {
3360
+ txHash,
3361
+ amount: args.amount,
3362
+ asset: "LBTC"
3363
+ });
3364
+ } catch (error) {
3365
+ return formatError("deploy_to_defi", error);
3366
+ }
3367
+ }
3368
+ async claimDeposit(walletProvider, args) {
3369
+ try {
3370
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3371
+ if (!resolved) {
3372
+ return formatError("claim_deposit", "Current network is not supported by Lombard");
3373
+ }
3374
+ const { chainId, env } = resolved;
3375
+ const account = walletProvider.getAddress();
3376
+ const provider = toEIP1193Provider(walletProvider, chainId);
3377
+ // Find the claimable deposit by tx hash
3378
+ const deposits = await getDepositsByAddress({
3379
+ address: account,
3380
+ env
3381
+ });
3382
+ const deposit = deposits.find((d)=>d.txHash === args.depositTxHash);
3383
+ if (!deposit) {
3384
+ return formatError("claim_deposit", `No deposit found with txHash: ${args.depositTxHash}`);
3385
+ }
3386
+ const status = getDepositStatus(deposit);
3387
+ if (status !== "claimable") {
3388
+ const display = getDepositStatusDisplay(status);
3389
+ return formatError("claim_deposit", `Deposit is not claimable. Current status: ${display.label} - ${display.description}`);
3390
+ }
3391
+ if (!deposit.rawPayload || !deposit.proof) {
3392
+ return formatError("claim_deposit", "Deposit proof data is not yet available");
3393
+ }
3394
+ const txHash = await claimLBTC({
3395
+ data: deposit.rawPayload,
3396
+ proofSignature: deposit.proof,
3397
+ account,
3398
+ chainId,
3399
+ provider,
3400
+ env
3401
+ });
3402
+ return formatSuccess("claim_deposit", {
3403
+ txHash,
3404
+ depositTxHash: args.depositTxHash
3405
+ });
3406
+ } catch (error) {
3407
+ return formatError("claim_deposit", error);
3408
+ }
3409
+ }
3410
+ // ─── Read Actions ───────────────────────────────────────────────────
3411
+ async getLbtcBalance(walletProvider, args) {
3412
+ try {
3413
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3414
+ if (!resolved) {
3415
+ return formatError("get_lbtc_balance", "Current network is not supported by Lombard");
3416
+ }
3417
+ const { chainId, env } = resolved;
3418
+ const address = args.address || walletProvider.getAddress();
3419
+ const { formatted } = await getTokenBalance(walletProvider, Token.LBTC, chainId, address, env);
3420
+ return formatSuccess("get_lbtc_balance", {
3421
+ address,
3422
+ balance: formatted,
3423
+ token: "LBTC",
3424
+ chain: resolved.networkId
3425
+ });
3426
+ } catch (error) {
3427
+ return formatError("get_lbtc_balance", error);
3428
+ }
3429
+ }
3430
+ async getBtcbBalance(walletProvider, args) {
3431
+ try {
3432
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3433
+ if (!resolved) {
3434
+ return formatError("get_btcb_balance", "Current network is not supported by Lombard");
3435
+ }
3436
+ const { chainId, env } = resolved;
3437
+ const address = args.address || walletProvider.getAddress();
3438
+ const { formatted } = await getTokenBalance(walletProvider, Token.BTCb, chainId, address, env);
3439
+ return formatSuccess("get_btcb_balance", {
3440
+ address,
3441
+ balance: formatted,
3442
+ token: "BTC.b",
3443
+ chain: resolved.networkId
3444
+ });
3445
+ } catch (error) {
3446
+ return formatError("get_btcb_balance", error);
3447
+ }
3448
+ }
3449
+ async getLbtcExchangeRate(_walletProvider, _args) {
3450
+ try {
3451
+ const resolved = resolveNetwork(_walletProvider.getNetwork());
3452
+ if (!resolved) {
3453
+ return formatError("get_lbtc_exchange_rate", "Current network is not supported by Lombard");
3454
+ }
3455
+ const env = resolved.env;
3456
+ const rate = await getLBTCExchangeRate({
3457
+ env
3458
+ });
3459
+ return formatSuccess("get_lbtc_exchange_rate", {
3460
+ exchangeRate: rate.exchangeRate,
3461
+ minStakeAmountBtc: fromSatoshi(rate.minAmount).toString()
3462
+ });
3463
+ } catch (error) {
3464
+ return formatError("get_lbtc_exchange_rate", error);
3465
+ }
3466
+ }
3467
+ async getDepositStatusAction(walletProvider, args) {
3468
+ try {
3469
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3470
+ if (!resolved) {
3471
+ return formatError("get_deposit_status", "Current network is not supported by Lombard");
3472
+ }
3473
+ const { env } = resolved;
3474
+ const address = args.address || walletProvider.getAddress();
3475
+ const deposits = await getDepositsByAddress({
3476
+ address,
3477
+ env
3478
+ });
3479
+ if (deposits.length === 0) {
3480
+ return formatSuccess("get_deposit_status", {
3481
+ address,
3482
+ deposits: [],
3483
+ message: "No deposits found for this address"
3484
+ });
3485
+ }
3486
+ const summaries = deposits.map((d)=>{
3487
+ const status = getDepositStatus(d);
3488
+ const display = getDepositStatusDisplay(status);
3489
+ return {
3490
+ txHash: d.txHash,
3491
+ amount: d.amount?.toString(),
3492
+ status,
3493
+ statusLabel: display.label,
3494
+ description: display.description,
3495
+ requiresAction: display.requiresAction,
3496
+ isTerminal: display.isTerminal,
3497
+ claimTxHash: d.claimTxHash || null
3498
+ };
3499
+ });
3500
+ return formatSuccess("get_deposit_status", {
3501
+ address,
3502
+ totalDeposits: deposits.length,
3503
+ deposits: summaries
3504
+ });
3505
+ } catch (error) {
3506
+ return formatError("get_deposit_status", error);
3507
+ }
3508
+ }
3509
+ async getUnstakeStatus(walletProvider, args) {
3510
+ try {
3511
+ const resolved = resolveNetwork(walletProvider.getNetwork());
3512
+ if (!resolved) {
3513
+ return formatError("get_unstake_status", "Current network is not supported by Lombard");
3514
+ }
3515
+ const { env } = resolved;
3516
+ const address = args.address || walletProvider.getAddress();
3517
+ const unstakes = await getUnstakesByAddress({
3518
+ address,
3519
+ env
3520
+ });
3521
+ if (unstakes.length === 0) {
3522
+ return formatSuccess("get_unstake_status", {
3523
+ address,
3524
+ unstakes: [],
3525
+ message: "No unstakes found for this address"
3526
+ });
3527
+ }
3528
+ const summaries = unstakes.map((u)=>({
3529
+ txHash: u.txHash,
3530
+ amount: u.amount?.toString(),
3531
+ payoutStatus: u.payoutTxStatus,
3532
+ payoutTxHash: u.payoutTxHash || null,
3533
+ toAddress: u.toAddress || null
3534
+ }));
3535
+ return formatSuccess("get_unstake_status", {
3536
+ address,
3537
+ totalUnstakes: unstakes.length,
3538
+ unstakes: summaries
3539
+ });
3540
+ } catch (error) {
3541
+ return formatError("get_unstake_status", error);
3542
+ }
3543
+ }
3544
+ // ─── Private Helpers ────────────────────────────────────────────────
3545
+ /**
3546
+ * Ensures fee authorization is in place for chains that require it.
3547
+ * On Ethereum and Sepolia, staking/unstaking requires an EIP-712 fee
3548
+ * signature stored with the backend before the transaction can proceed.
3549
+ */ async ensureFeeAuthorization(_walletProvider, chainId, env, account, provider) {
3550
+ if (!requiresAutoMintFee(chainId)) {
3551
+ return;
3552
+ }
3553
+ // Check if a valid fee signature already exists
3554
+ const existing = await getNetworkFeeSignature({
3555
+ address: account,
3556
+ chainId,
3557
+ env
3558
+ });
3559
+ if (existing.hasSignature) {
3560
+ // Check expiration
3561
+ const expirationMs = new Date(existing.expirationDate).getTime();
3562
+ const bufferMs = 60 * 60 * 1000; // 1 hour buffer
3563
+ if (expirationMs > Date.now() + bufferMs) {
3564
+ return; // Existing signature is still valid
3565
+ }
3566
+ }
3567
+ // Need to sign a new fee authorization
3568
+ const mintingFee = await getLBTCMintingFee({
3569
+ chainId,
3570
+ env
3571
+ });
3572
+ const { signature, typedData } = await signNetworkFee({
3573
+ fee: mintingFee,
3574
+ account,
3575
+ chainId,
3576
+ provider,
3577
+ env
3578
+ });
3579
+ await storeNetworkFeeSignature({
3580
+ signature,
3581
+ typedData,
3582
+ address: account,
3583
+ env
3584
+ });
3585
+ }
3586
+ }
3587
+ _ts_decorate([
3588
+ CreateAction({
3589
+ name: "stake_btcb_to_lbtc",
3590
+ description: "Stake BTC.b (cross-chain Bitcoin) to receive LBTC (Lombard Staked Bitcoin). " + "This converts BTC.b into LBTC which earns staking yield. " + "Handles token approval and fee authorization automatically.",
3591
+ schema: StakeBtcbToLbtcSchema
3592
+ }),
3593
+ _ts_metadata("design:type", Function),
3594
+ _ts_metadata("design:paramtypes", [
3595
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3596
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3597
+ ]),
3598
+ _ts_metadata("design:returntype", Promise)
3599
+ ], LombardActionProvider.prototype, "stakeBtcbToLbtc", null);
3600
+ _ts_decorate([
3601
+ CreateAction({
3602
+ name: "unstake_lbtc",
3603
+ description: "Unstake LBTC (Lombard Staked Bitcoin). " + "Output can be native BTC (cross-chain, requires a Bitcoin address) or BTC.b (same EVM chain). " + "BTC unstaking takes longer as it crosses chains. BTC.b is faster, same-chain.",
3604
+ schema: UnstakeLbtcSchema
3605
+ }),
3606
+ _ts_metadata("design:type", Function),
3607
+ _ts_metadata("design:paramtypes", [
3608
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3609
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3610
+ ]),
3611
+ _ts_metadata("design:returntype", Promise)
3612
+ ], LombardActionProvider.prototype, "unstakeLbtc", null);
3613
+ _ts_decorate([
3614
+ CreateAction({
3615
+ name: "redeem_lbtc_to_btcb",
3616
+ description: "Use this for simple same-chain LBTC to BTC.b conversion. " + "For cross-chain unstaking to native BTC, use unstake_lbtc instead.",
3617
+ schema: RedeemLbtcToBtcbSchema
3618
+ }),
3619
+ _ts_metadata("design:type", Function),
3620
+ _ts_metadata("design:paramtypes", [
3621
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3622
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3623
+ ]),
3624
+ _ts_metadata("design:returntype", Promise)
3625
+ ], LombardActionProvider.prototype, "redeemLbtcToBtcb", null);
3626
+ _ts_decorate([
3627
+ CreateAction({
3628
+ name: "deploy_to_defi",
3629
+ description: "Deploy LBTC into a DeFi vault to earn additional yield. " + "Currently supports the Veda vault. " + "Handles approval automatically.",
3630
+ schema: DeployToDefiSchema
3631
+ }),
3632
+ _ts_metadata("design:type", Function),
3633
+ _ts_metadata("design:paramtypes", [
3634
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3635
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3636
+ ]),
3637
+ _ts_metadata("design:returntype", Promise)
3638
+ ], LombardActionProvider.prototype, "deployToDefi", null);
3639
+ _ts_decorate([
3640
+ CreateAction({
3641
+ name: "claim_deposit",
3642
+ description: "Claim a notarized deposit to mint LBTC. " + "Use get_deposit_status first to check if a deposit is claimable. " + 'Only deposits with status "claimable" can be claimed.',
3643
+ schema: ClaimDepositSchema
3644
+ }),
3645
+ _ts_metadata("design:type", Function),
3646
+ _ts_metadata("design:paramtypes", [
3647
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3648
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3649
+ ]),
3650
+ _ts_metadata("design:returntype", Promise)
3651
+ ], LombardActionProvider.prototype, "claimDeposit", null);
3652
+ _ts_decorate([
3653
+ CreateAction({
3654
+ name: "get_lbtc_balance",
3655
+ description: "Check the LBTC (Lombard Staked Bitcoin) balance for an address on the current chain.",
3656
+ schema: GetLbtcBalanceSchema
3657
+ }),
3658
+ _ts_metadata("design:type", Function),
3659
+ _ts_metadata("design:paramtypes", [
3660
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3661
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3662
+ ]),
3663
+ _ts_metadata("design:returntype", Promise)
3664
+ ], LombardActionProvider.prototype, "getLbtcBalance", null);
3665
+ _ts_decorate([
3666
+ CreateAction({
3667
+ name: "get_btcb_balance",
3668
+ description: "Check the BTC.b (cross-chain Bitcoin) balance for an address on the current chain.",
3669
+ schema: GetBtcbBalanceSchema
3670
+ }),
3671
+ _ts_metadata("design:type", Function),
3672
+ _ts_metadata("design:paramtypes", [
3673
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3674
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3675
+ ]),
3676
+ _ts_metadata("design:returntype", Promise)
3677
+ ], LombardActionProvider.prototype, "getBtcbBalance", null);
3678
+ _ts_decorate([
3679
+ CreateAction({
3680
+ name: "get_lbtc_exchange_rate",
3681
+ description: "Get the current LBTC/BTC exchange rate and minimum stake amount. " + "LBTC is a rebasing token, so the rate is typically close to 1:1.",
3682
+ schema: GetLbtcExchangeRateSchema
3683
+ }),
3684
+ _ts_metadata("design:type", Function),
3685
+ _ts_metadata("design:paramtypes", [
3686
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3687
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3688
+ ]),
3689
+ _ts_metadata("design:returntype", Promise)
3690
+ ], LombardActionProvider.prototype, "getLbtcExchangeRate", null);
3691
+ _ts_decorate([
3692
+ CreateAction({
3693
+ name: "get_deposit_status",
3694
+ description: "Check the status of all deposits for an address. " + "Shows pending, claimable, claimed, and failed deposits. " + "Use this to find claimable deposits before calling claim_deposit.",
3695
+ schema: GetDepositStatusSchema
3696
+ }),
3697
+ _ts_metadata("design:type", Function),
3698
+ _ts_metadata("design:paramtypes", [
3699
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3700
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3701
+ ]),
3702
+ _ts_metadata("design:returntype", Promise)
3703
+ ], LombardActionProvider.prototype, "getDepositStatusAction", null);
3704
+ _ts_decorate([
3705
+ CreateAction({
3706
+ name: "get_unstake_status",
3707
+ description: "Check the status of all unstake/redeem operations for an address. " + "Shows pending and completed unstakes with payout transaction details.",
3708
+ schema: GetUnstakeStatusSchema
3709
+ }),
3710
+ _ts_metadata("design:type", Function),
3711
+ _ts_metadata("design:paramtypes", [
3712
+ typeof EvmWalletProvider === "undefined" ? Object : EvmWalletProvider,
3713
+ typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
3714
+ ]),
3715
+ _ts_metadata("design:returntype", Promise)
3716
+ ], LombardActionProvider.prototype, "getUnstakeStatus", null);
3717
+ const lombardActionProvider = ()=>new LombardActionProvider();
3718
+
3719
+ export { ClaimDepositSchema, DeployToDefiSchema, GetBtcbBalanceSchema, GetDepositStatusSchema, GetLbtcBalanceSchema, GetLbtcExchangeRateSchema, GetUnstakeStatusSchema, LombardActionProvider, NETWORK_ID_TO_VIEM_CHAIN, RedeemLbtcToBtcbSchema, StakeBtcbToLbtcSchema, UnstakeLbtcSchema, isLombardSupportedNetwork, lombardActionProvider, resolveChainName, resolveNetwork };