viem 2.47.18 → 2.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/chains/definitions/tempo.js +2 -2
  3. package/_cjs/chains/definitions/tempo.js.map +1 -1
  4. package/_cjs/errors/version.js +1 -1
  5. package/_cjs/errors/version.js.map +1 -1
  6. package/_cjs/tempo/Addresses.js +2 -1
  7. package/_cjs/tempo/Addresses.js.map +1 -1
  8. package/_cjs/tempo/Decorator.js +16 -0
  9. package/_cjs/tempo/Decorator.js.map +1 -1
  10. package/_cjs/tempo/Storage.js +77 -0
  11. package/_cjs/tempo/Storage.js.map +1 -0
  12. package/_cjs/tempo/actions/index.js +2 -1
  13. package/_cjs/tempo/actions/index.js.map +1 -1
  14. package/_cjs/tempo/actions/zone.js +432 -0
  15. package/_cjs/tempo/actions/zone.js.map +1 -0
  16. package/_cjs/tempo/index.js +2 -1
  17. package/_cjs/tempo/index.js.map +1 -1
  18. package/_cjs/tempo/zones/Abis.js +82 -0
  19. package/_cjs/tempo/zones/Abis.js.map +1 -0
  20. package/_cjs/tempo/zones/index.js +13 -0
  21. package/_cjs/tempo/zones/index.js.map +1 -0
  22. package/_cjs/tempo/zones/transport.js +24 -0
  23. package/_cjs/tempo/zones/transport.js.map +1 -0
  24. package/_cjs/tempo/zones/zone.js +53 -0
  25. package/_cjs/tempo/zones/zone.js.map +1 -0
  26. package/_esm/chains/definitions/tempo.js +2 -2
  27. package/_esm/chains/definitions/tempo.js.map +1 -1
  28. package/_esm/errors/version.js +1 -1
  29. package/_esm/errors/version.js.map +1 -1
  30. package/_esm/tempo/Addresses.js +1 -0
  31. package/_esm/tempo/Addresses.js.map +1 -1
  32. package/_esm/tempo/Decorator.js +16 -0
  33. package/_esm/tempo/Decorator.js.map +1 -1
  34. package/_esm/tempo/Storage.js +96 -0
  35. package/_esm/tempo/Storage.js.map +1 -0
  36. package/_esm/tempo/actions/index.js +1 -0
  37. package/_esm/tempo/actions/index.js.map +1 -1
  38. package/_esm/tempo/actions/zone.js +786 -0
  39. package/_esm/tempo/actions/zone.js.map +1 -0
  40. package/_esm/tempo/index.js +1 -0
  41. package/_esm/tempo/index.js.map +1 -1
  42. package/_esm/tempo/zones/Abis.js +79 -0
  43. package/_esm/tempo/zones/Abis.js.map +1 -0
  44. package/_esm/tempo/zones/index.js +5 -0
  45. package/_esm/tempo/zones/index.js.map +1 -0
  46. package/_esm/tempo/zones/transport.js +39 -0
  47. package/_esm/tempo/zones/transport.js.map +1 -0
  48. package/_esm/tempo/zones/zone.js +49 -0
  49. package/_esm/tempo/zones/zone.js.map +1 -0
  50. package/_types/chains/definitions/tempo.d.ts +4 -4
  51. package/_types/errors/version.d.ts +1 -1
  52. package/_types/errors/version.d.ts.map +1 -1
  53. package/_types/tempo/Addresses.d.ts +1 -0
  54. package/_types/tempo/Addresses.d.ts.map +1 -1
  55. package/_types/tempo/Decorator.d.ts +283 -0
  56. package/_types/tempo/Decorator.d.ts.map +1 -1
  57. package/_types/tempo/Storage.d.ts +42 -0
  58. package/_types/tempo/Storage.d.ts.map +1 -0
  59. package/_types/tempo/actions/index.d.ts +1 -0
  60. package/_types/tempo/actions/index.d.ts.map +1 -1
  61. package/_types/tempo/actions/zone.d.ts +874 -0
  62. package/_types/tempo/actions/zone.d.ts.map +1 -0
  63. package/_types/tempo/index.d.ts +1 -0
  64. package/_types/tempo/index.d.ts.map +1 -1
  65. package/_types/tempo/zones/Abis.d.ts +124 -0
  66. package/_types/tempo/zones/Abis.d.ts.map +1 -0
  67. package/_types/tempo/zones/index.d.ts +4 -0
  68. package/_types/tempo/zones/index.d.ts.map +1 -0
  69. package/_types/tempo/zones/transport.d.ts +26 -0
  70. package/_types/tempo/zones/transport.d.ts.map +1 -0
  71. package/_types/tempo/zones/zone.d.ts +2775 -0
  72. package/_types/tempo/zones/zone.d.ts.map +1 -0
  73. package/chains/definitions/tempo.ts +2 -2
  74. package/errors/version.ts +1 -1
  75. package/package.json +7 -2
  76. package/tempo/Addresses.ts +1 -0
  77. package/tempo/Decorator.ts +337 -0
  78. package/tempo/Storage.ts +118 -0
  79. package/tempo/actions/index.ts +1 -0
  80. package/tempo/actions/zone.ts +1317 -0
  81. package/tempo/index.ts +1 -0
  82. package/tempo/zones/Abis.ts +79 -0
  83. package/tempo/zones/index.ts +10 -0
  84. package/tempo/zones/package.json +6 -0
  85. package/tempo/zones/transport.ts +58 -0
  86. package/tempo/zones/zone.ts +70 -0
@@ -0,0 +1,786 @@
1
+ import * as Bytes from 'ox/Bytes';
2
+ import * as Hex from 'ox/Hex';
3
+ import * as PublicKey from 'ox/PublicKey';
4
+ import * as Secp256k1 from 'ox/Secp256k1';
5
+ import { TokenId, ZoneId, ZoneRpcAuthentication } from 'ox/tempo';
6
+ import { parseAccount } from '../../accounts/utils/parseAccount.js';
7
+ import { readContract } from '../../actions/public/readContract.js';
8
+ import { sendTransaction, } from '../../actions/wallet/sendTransaction.js';
9
+ import { sendTransactionSync } from '../../actions/wallet/sendTransactionSync.js';
10
+ import { zeroHash } from '../../constants/bytes.js';
11
+ import { encodeAbiParameters } from '../../utils/abi/encodeAbiParameters.js';
12
+ import * as Abis from '../Abis.js';
13
+ import * as Addresses from '../Addresses.js';
14
+ import { defineCall } from '../internal/utils.js';
15
+ import * as Storage from '../Storage.js';
16
+ import * as ZoneAbis from '../zones/Abis.js';
17
+ import { getPortalAddress } from '../zones/zone.js';
18
+ /**
19
+ * Deposits tokens into a zone on the parent Tempo chain.
20
+ * Batches approve and deposit into a single transaction.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { createClient, http } from 'viem'
25
+ * import { privateKeyToAccount } from 'viem/accounts'
26
+ * import { tempoModerato } from 'viem/chains'
27
+ * import { Actions } from 'viem/tempo'
28
+ *
29
+ * const client = createClient({
30
+ * account: privateKeyToAccount('0x...'),
31
+ * chain: tempoModerato,
32
+ * transport: http(),
33
+ * })
34
+ *
35
+ * const hash = await Actions.zone.deposit(client, {
36
+ * token: '0x20c0...0001',
37
+ * amount: 1_000_000n,
38
+ * zoneId: 7,
39
+ * })
40
+ * ```
41
+ *
42
+ * @param client - Wallet client connected to the parent Tempo chain.
43
+ * @param parameters - Deposit parameters.
44
+ * @returns The transaction hash.
45
+ */
46
+ export async function deposit(client, parameters) {
47
+ const chainId = client.chain?.id;
48
+ if (!chainId)
49
+ throw new Error('`chain` is required.');
50
+ const { account = client.account, ...rest } = parameters;
51
+ const account_ = account ? parseAccount(account) : undefined;
52
+ if (!account)
53
+ throw new Error('`account` is required.');
54
+ const recipient = parameters.recipient ?? account_?.address;
55
+ if (!recipient)
56
+ throw new Error('`recipient` is required.');
57
+ const args = { ...parameters, chainId, recipient };
58
+ return sendTransaction(client, {
59
+ ...rest,
60
+ calls: deposit.calls(args),
61
+ });
62
+ }
63
+ (function (deposit) {
64
+ /**
65
+ * Defines the calls to approve and deposit tokens into a zone.
66
+ *
67
+ * @param args - Arguments.
68
+ * @returns The calls.
69
+ */
70
+ function calls(args) {
71
+ const { amount, chainId, memo = zeroHash, recipient, token, zoneId } = args;
72
+ const portalAddress = getPortalAddress(chainId, zoneId);
73
+ return [
74
+ defineCall({
75
+ address: TokenId.toAddress(token),
76
+ abi: Abis.tip20,
77
+ functionName: 'approve',
78
+ args: [portalAddress, amount],
79
+ }),
80
+ defineCall({
81
+ address: portalAddress,
82
+ abi: ZoneAbis.zonePortal,
83
+ functionName: 'deposit',
84
+ args: [TokenId.toAddress(token), recipient, amount, memo],
85
+ }),
86
+ ];
87
+ }
88
+ deposit.calls = calls;
89
+ })(deposit || (deposit = {}));
90
+ /**
91
+ * Deposits tokens into a zone on the parent Tempo chain and waits for the
92
+ * transaction receipt.
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * import { createClient, http } from 'viem'
97
+ * import { privateKeyToAccount } from 'viem/accounts'
98
+ * import { tempoModerato } from 'viem/chains'
99
+ * import { Actions } from 'viem/tempo'
100
+ *
101
+ * const client = createClient({
102
+ * account: privateKeyToAccount('0x...'),
103
+ * chain: tempoModerato,
104
+ * transport: http(),
105
+ * })
106
+ *
107
+ * const result = await Actions.zone.depositSync(client, {
108
+ * token: '0x20c0...0001',
109
+ * amount: 1_000_000n,
110
+ * zoneId: 7,
111
+ * })
112
+ * ```
113
+ *
114
+ * @param client - Wallet client connected to the parent Tempo chain.
115
+ * @param parameters - Deposit parameters.
116
+ * @returns The transaction receipt.
117
+ */
118
+ export async function depositSync(client, parameters) {
119
+ const chainId = client.chain?.id;
120
+ if (!chainId)
121
+ throw new Error('`chain` is required.');
122
+ const { account = client.account, throwOnReceiptRevert = true, ...rest } = parameters;
123
+ const account_ = account ? parseAccount(account) : undefined;
124
+ if (!account)
125
+ throw new Error('`account` is required.');
126
+ const recipient = parameters.recipient ?? account_?.address;
127
+ if (!recipient)
128
+ throw new Error('`recipient` is required.');
129
+ const args = { ...parameters, chainId, recipient };
130
+ const receipt = await sendTransactionSync(client, {
131
+ ...rest,
132
+ throwOnReceiptRevert,
133
+ calls: deposit.calls(args),
134
+ });
135
+ return { receipt };
136
+ }
137
+ /**
138
+ * Deposits tokens into a zone on the parent Tempo chain with encrypted
139
+ * recipient and memo. Batches approve and depositEncrypted into a single
140
+ * transaction.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * import { createClient, http } from 'viem'
145
+ * import { privateKeyToAccount } from 'viem/accounts'
146
+ * import { tempoModerato } from 'viem/chains'
147
+ * import { Actions } from 'viem/tempo'
148
+ *
149
+ * const client = createClient({
150
+ * account: privateKeyToAccount('0x...'),
151
+ * chain: tempoModerato,
152
+ * transport: http(),
153
+ * })
154
+ *
155
+ * const hash = await Actions.zone.encryptedDeposit(client, {
156
+ * token: '0x20c0...0001',
157
+ * amount: 1_000_000n,
158
+ * zoneId: 7,
159
+ * })
160
+ * ```
161
+ *
162
+ * @param client - Wallet client connected to the parent Tempo chain.
163
+ * @param parameters - Encrypted deposit parameters.
164
+ * @returns The transaction hash.
165
+ */
166
+ export async function encryptedDeposit(client, parameters) {
167
+ const chainId = client.chain?.id;
168
+ if (!chainId)
169
+ throw new Error('`chain` is required.');
170
+ const { account = client.account, ...rest } = parameters;
171
+ const account_ = account ? parseAccount(account) : undefined;
172
+ if (!account)
173
+ throw new Error('`account` is required.');
174
+ const recipient = parameters.recipient ?? account_?.address;
175
+ if (!recipient)
176
+ throw new Error('`recipient` is required.');
177
+ const portalAddress = getPortalAddress(chainId, parameters.zoneId);
178
+ const [publicKey, keyIndex] = await Promise.all([
179
+ readContract(client, {
180
+ address: portalAddress,
181
+ abi: ZoneAbis.zonePortal,
182
+ functionName: 'sequencerEncryptionKey',
183
+ }),
184
+ readContract(client, {
185
+ address: portalAddress,
186
+ abi: ZoneAbis.zonePortal,
187
+ functionName: 'encryptionKeyCount',
188
+ }),
189
+ ]);
190
+ if (keyIndex === 0n) {
191
+ throw new Error('No sequencer encryption key configured.');
192
+ }
193
+ const encrypted = await encryptDepositPayload({ x: publicKey[0], yParity: publicKey[1] }, recipient, parameters.memo);
194
+ const args = {
195
+ ...parameters,
196
+ chainId,
197
+ encrypted,
198
+ keyIndex: keyIndex - 1n,
199
+ recipient,
200
+ };
201
+ return sendTransaction(client, {
202
+ ...rest,
203
+ calls: encryptedDeposit.calls(args),
204
+ });
205
+ }
206
+ (function (encryptedDeposit) {
207
+ /**
208
+ * Defines the calls to approve and deposit tokens into a zone (encrypted).
209
+ *
210
+ * @param args - Arguments.
211
+ * @returns The calls.
212
+ */
213
+ function calls(args) {
214
+ const { amount, chainId, encrypted, keyIndex, token, zoneId } = args;
215
+ const portalAddress = getPortalAddress(chainId, zoneId);
216
+ return [
217
+ defineCall({
218
+ address: TokenId.toAddress(token),
219
+ abi: Abis.tip20,
220
+ functionName: 'approve',
221
+ args: [portalAddress, amount],
222
+ }),
223
+ defineCall({
224
+ address: portalAddress,
225
+ abi: ZoneAbis.zonePortal,
226
+ functionName: 'depositEncrypted',
227
+ args: [
228
+ TokenId.toAddress(token),
229
+ amount,
230
+ keyIndex,
231
+ {
232
+ ephemeralPubkeyX: encrypted.ephemeralPubkeyX,
233
+ ephemeralPubkeyYParity: encrypted.ephemeralPubkeyYParity,
234
+ ciphertext: encrypted.ciphertext,
235
+ nonce: encrypted.nonce,
236
+ tag: encrypted.tag,
237
+ },
238
+ ],
239
+ }),
240
+ ];
241
+ }
242
+ encryptedDeposit.calls = calls;
243
+ })(encryptedDeposit || (encryptedDeposit = {}));
244
+ /**
245
+ * Deposits tokens into a zone on the parent Tempo chain with encrypted
246
+ * recipient and memo, and waits for the transaction receipt.
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * import { createClient, http } from 'viem'
251
+ * import { privateKeyToAccount } from 'viem/accounts'
252
+ * import { tempoModerato } from 'viem/chains'
253
+ * import { Actions } from 'viem/tempo'
254
+ *
255
+ * const client = createClient({
256
+ * account: privateKeyToAccount('0x...'),
257
+ * chain: tempoModerato,
258
+ * transport: http(),
259
+ * })
260
+ *
261
+ * const result = await Actions.zone.encryptedDepositSync(client, {
262
+ * token: '0x20c0...0001',
263
+ * amount: 1_000_000n,
264
+ * zoneId: 7,
265
+ * })
266
+ * ```
267
+ *
268
+ * @param client - Wallet client connected to the parent Tempo chain.
269
+ * @param parameters - Encrypted deposit parameters.
270
+ * @returns The transaction receipt.
271
+ */
272
+ export async function encryptedDepositSync(client, parameters) {
273
+ const chainId = client.chain?.id;
274
+ if (!chainId)
275
+ throw new Error('`chain` is required.');
276
+ const { account = client.account, throwOnReceiptRevert = true, ...rest } = parameters;
277
+ const account_ = account ? parseAccount(account) : undefined;
278
+ if (!account)
279
+ throw new Error('`account` is required.');
280
+ const recipient = parameters.recipient ?? account_?.address;
281
+ if (!recipient)
282
+ throw new Error('`recipient` is required.');
283
+ const portalAddress = getPortalAddress(chainId, parameters.zoneId);
284
+ const [publicKey, keyIndex] = await Promise.all([
285
+ readContract(client, {
286
+ address: portalAddress,
287
+ abi: ZoneAbis.zonePortal,
288
+ functionName: 'sequencerEncryptionKey',
289
+ }),
290
+ readContract(client, {
291
+ address: portalAddress,
292
+ abi: ZoneAbis.zonePortal,
293
+ functionName: 'encryptionKeyCount',
294
+ }),
295
+ ]);
296
+ if (keyIndex === 0n) {
297
+ throw new Error('No sequencer encryption key configured.');
298
+ }
299
+ const encrypted = await encryptDepositPayload({ x: publicKey[0], yParity: publicKey[1] }, recipient, parameters.memo);
300
+ const args = {
301
+ ...parameters,
302
+ chainId,
303
+ encrypted,
304
+ keyIndex: keyIndex - 1n,
305
+ recipient,
306
+ };
307
+ const receipt = await sendTransactionSync(client, {
308
+ ...rest,
309
+ throwOnReceiptRevert,
310
+ calls: encryptedDeposit.calls(args),
311
+ });
312
+ return { receipt };
313
+ }
314
+ /**
315
+ * Returns the authenticated account address and authorization token expiry.
316
+ *
317
+ * @example
318
+ * ```ts
319
+ * import { createClient } from 'viem'
320
+ * import { http, zoneModerato } from 'viem/tempo/zones'
321
+ * import { Actions } from 'viem/tempo'
322
+ *
323
+ * const client = createClient({
324
+ * chain: zoneModerato(7),
325
+ * transport: http(),
326
+ * })
327
+ *
328
+ * const info = await Actions.zone.getAuthorizationTokenInfo(client)
329
+ * ```
330
+ *
331
+ * @param client - Zone client.
332
+ * @returns Authorization token info.
333
+ */
334
+ export async function getAuthorizationTokenInfo(client) {
335
+ const info = await client.request({
336
+ method: 'zone_getAuthorizationTokenInfo',
337
+ params: [],
338
+ });
339
+ return {
340
+ account: info.account,
341
+ expiresAt: Hex.toBigInt(info.expiresAt),
342
+ };
343
+ }
344
+ /**
345
+ * Returns deposit processing status for a given Tempo block number.
346
+ *
347
+ * @example
348
+ * ```ts
349
+ * import { createClient } from 'viem'
350
+ * import { http, zoneModerato } from 'viem/tempo/zones'
351
+ * import { Actions } from 'viem/tempo'
352
+ *
353
+ * const client = createClient({
354
+ * chain: zoneModerato(7),
355
+ * transport: http(),
356
+ * })
357
+ *
358
+ * const status = await Actions.zone.getDepositStatus(client, {
359
+ * tempoBlockNumber: 42n,
360
+ * })
361
+ * ```
362
+ *
363
+ * @param client - Zone client.
364
+ * @param parameters - Parameters including the Tempo block number.
365
+ * @returns Deposit status.
366
+ */
367
+ export async function getDepositStatus(client, parameters) {
368
+ const { tempoBlockNumber } = parameters;
369
+ const status = await client.request({
370
+ method: 'zone_getDepositStatus',
371
+ params: [Hex.fromNumber(tempoBlockNumber)],
372
+ });
373
+ return {
374
+ deposits: status.deposits.map((deposit) => ({
375
+ amount: Hex.toBigInt(deposit.amount),
376
+ depositHash: deposit.depositHash,
377
+ kind: deposit.kind,
378
+ memo: deposit.memo,
379
+ recipient: deposit.recipient,
380
+ sender: deposit.sender,
381
+ status: deposit.status,
382
+ token: deposit.token,
383
+ })),
384
+ processed: status.processed,
385
+ tempoBlockNumber: Hex.toBigInt(status.tempoBlockNumber),
386
+ zoneProcessedThrough: Hex.toBigInt(status.zoneProcessedThrough),
387
+ };
388
+ }
389
+ /**
390
+ * Returns the fee required for a withdrawal from a zone, given a gas limit.
391
+ *
392
+ * The client must be connected to the **zone chain**.
393
+ *
394
+ * @example
395
+ * ```ts
396
+ * import { createClient } from 'viem'
397
+ * import { http, zoneModerato } from 'viem/tempo/zones'
398
+ * import { Actions } from 'viem/tempo'
399
+ *
400
+ * const client = createClient({
401
+ * chain: zoneModerato(7),
402
+ * transport: http(),
403
+ * })
404
+ *
405
+ * const fee = await Actions.zone.getWithdrawalFee(client)
406
+ * ```
407
+ *
408
+ * @param client - Zone client.
409
+ * @param parameters - Optional gas limit parameter.
410
+ * @returns The withdrawal fee as a bigint.
411
+ */
412
+ export async function getWithdrawalFee(client, parameters = {}) {
413
+ const { gas = 0n, ...rest } = parameters;
414
+ return readContract(client, {
415
+ ...rest,
416
+ address: Addresses.zoneOutbox,
417
+ abi: ZoneAbis.zoneOutbox,
418
+ functionName: 'calculateWithdrawalFee',
419
+ args: [gas],
420
+ });
421
+ }
422
+ /**
423
+ * Returns the current zone metadata.
424
+ *
425
+ * @example
426
+ * ```ts
427
+ * import { createClient } from 'viem'
428
+ * import { http, zoneModerato } from 'viem/tempo/zones'
429
+ * import { Actions } from 'viem/tempo'
430
+ *
431
+ * const client = createClient({
432
+ * chain: zoneModerato(7),
433
+ * transport: http(),
434
+ * })
435
+ *
436
+ * const info = await Actions.zone.getZoneInfo(client)
437
+ * ```
438
+ *
439
+ * @param client - Zone client.
440
+ * @returns Zone metadata.
441
+ */
442
+ export async function getZoneInfo(client) {
443
+ const info = await client.request({
444
+ method: 'zone_getZoneInfo',
445
+ params: [],
446
+ });
447
+ return {
448
+ chainId: Hex.toNumber(info.chainId),
449
+ sequencer: info.sequencer,
450
+ zoneId: Hex.toNumber(info.zoneId),
451
+ zoneTokens: info.zoneTokens,
452
+ };
453
+ }
454
+ /**
455
+ * Requests a withdrawal from a zone to the parent Tempo chain via the
456
+ * ZoneOutbox contract.
457
+ *
458
+ * The client must be connected to the **zone chain**.
459
+ *
460
+ * @example
461
+ * ```ts
462
+ * import { createClient } from 'viem'
463
+ * import { privateKeyToAccount } from 'viem/accounts'
464
+ * import { http, zoneModerato } from 'viem/tempo/zones'
465
+ * import { Actions } from 'viem/tempo'
466
+ *
467
+ * const client = createClient({
468
+ * account: privateKeyToAccount('0x...'),
469
+ * chain: zoneModerato(7),
470
+ * transport: http(),
471
+ * })
472
+ *
473
+ * const hash = await Actions.zone.requestWithdrawal(client, {
474
+ * token: '0x20c0...0001',
475
+ * amount: 1_000_000n,
476
+ * })
477
+ * ```
478
+ *
479
+ * @param client - Wallet client connected to the zone chain.
480
+ * @param parameters - Withdrawal parameters.
481
+ * @returns The transaction hash.
482
+ */
483
+ export async function requestWithdrawal(client, parameters) {
484
+ const { account = client.account, ...rest } = parameters;
485
+ const account_ = account ? parseAccount(account) : undefined;
486
+ if (!account)
487
+ throw new Error('`account` is required.');
488
+ const to = parameters.to ?? account_?.address;
489
+ if (!to)
490
+ throw new Error('`to` is required.');
491
+ const args = { ...parameters, to };
492
+ return sendTransaction(client, {
493
+ ...rest,
494
+ calls: requestWithdrawal.calls(args),
495
+ });
496
+ }
497
+ (function (requestWithdrawal) {
498
+ /**
499
+ * Defines the calls to approve and request a withdrawal from a zone.
500
+ *
501
+ * @param args - Arguments.
502
+ * @returns The calls.
503
+ */
504
+ function calls(args) {
505
+ const { amount, data = '0x', fallbackRecipient = args.to, gas = 0n, memo = zeroHash, to, token, } = args;
506
+ return [
507
+ defineCall({
508
+ address: TokenId.toAddress(token),
509
+ abi: Abis.tip20,
510
+ functionName: 'approve',
511
+ args: [Addresses.zoneOutbox, amount],
512
+ }),
513
+ defineCall({
514
+ address: Addresses.zoneOutbox,
515
+ abi: ZoneAbis.zoneOutbox,
516
+ functionName: 'requestWithdrawal',
517
+ args: [
518
+ TokenId.toAddress(token),
519
+ to,
520
+ amount,
521
+ memo,
522
+ gas,
523
+ fallbackRecipient,
524
+ data,
525
+ '0x',
526
+ ],
527
+ }),
528
+ ];
529
+ }
530
+ requestWithdrawal.calls = calls;
531
+ })(requestWithdrawal || (requestWithdrawal = {}));
532
+ /**
533
+ * Requests a withdrawal from a zone to the parent Tempo chain and waits for
534
+ * the transaction receipt.
535
+ *
536
+ * @example
537
+ * ```ts
538
+ * import { createClient } from 'viem'
539
+ * import { privateKeyToAccount } from 'viem/accounts'
540
+ * import { http, zoneModerato } from 'viem/tempo/zones'
541
+ * import { Actions } from 'viem/tempo'
542
+ *
543
+ * const client = createClient({
544
+ * account: privateKeyToAccount('0x...'),
545
+ * chain: zoneModerato(7),
546
+ * transport: http(),
547
+ * })
548
+ *
549
+ * const result = await Actions.zone.requestWithdrawalSync(client, {
550
+ * token: '0x20c0...0001',
551
+ * amount: 1_000_000n,
552
+ * })
553
+ * ```
554
+ *
555
+ * @param client - Wallet client connected to the zone chain.
556
+ * @param parameters - Withdrawal parameters.
557
+ * @returns The transaction receipt.
558
+ */
559
+ export async function requestWithdrawalSync(client, parameters) {
560
+ const { account = client.account, throwOnReceiptRevert = true, ...rest } = parameters;
561
+ const account_ = account ? parseAccount(account) : undefined;
562
+ if (!account)
563
+ throw new Error('`account` is required.');
564
+ const to = parameters.to ?? account_?.address;
565
+ if (!to)
566
+ throw new Error('`to` is required.');
567
+ const args = { ...parameters, to };
568
+ const receipt = await sendTransactionSync(client, {
569
+ ...rest,
570
+ calls: requestWithdrawal.calls(args),
571
+ throwOnReceiptRevert,
572
+ });
573
+ return { receipt };
574
+ }
575
+ /**
576
+ * Requests a verifiable withdrawal from a zone to the parent Tempo chain via
577
+ * the ZoneOutbox contract. Includes a `revealTo` public key so the sequencer
578
+ * can encrypt the withdrawal details.
579
+ *
580
+ * The client must be connected to the **zone chain**.
581
+ *
582
+ * @example
583
+ * ```ts
584
+ * import { createClient } from 'viem'
585
+ * import { privateKeyToAccount } from 'viem/accounts'
586
+ * import { http, zoneModerato } from 'viem/tempo/zones'
587
+ * import { Actions } from 'viem/tempo'
588
+ *
589
+ * const client = createClient({
590
+ * account: privateKeyToAccount('0x...'),
591
+ * chain: zoneModerato(7),
592
+ * transport: http(),
593
+ * })
594
+ *
595
+ * const hash = await Actions.zone.requestVerifiableWithdrawal(client, {
596
+ * token: '0x20c0...0001',
597
+ * amount: 1_000_000n,
598
+ * revealTo: '0x02abc...def',
599
+ * })
600
+ * ```
601
+ *
602
+ * @param client - Wallet client connected to the zone chain.
603
+ * @param parameters - Verifiable withdrawal parameters.
604
+ * @returns The transaction hash.
605
+ */
606
+ export async function requestVerifiableWithdrawal(client, parameters) {
607
+ const { account = client.account, ...rest } = parameters;
608
+ const account_ = account ? parseAccount(account) : undefined;
609
+ if (!account)
610
+ throw new Error('`account` is required.');
611
+ const to = parameters.to ?? account_?.address;
612
+ if (!to)
613
+ throw new Error('`to` is required.');
614
+ const args = { ...parameters, to };
615
+ return sendTransaction(client, {
616
+ ...rest,
617
+ calls: requestVerifiableWithdrawal.calls(args),
618
+ });
619
+ }
620
+ (function (requestVerifiableWithdrawal) {
621
+ /**
622
+ * Defines the calls to approve and request a verifiable withdrawal from a zone.
623
+ *
624
+ * @param args - Arguments.
625
+ * @returns The calls.
626
+ */
627
+ function calls(args) {
628
+ const { amount, data = '0x', fallbackRecipient = args.to, gas = 0n, memo = zeroHash, revealTo, to, token, } = args;
629
+ return [
630
+ defineCall({
631
+ address: TokenId.toAddress(token),
632
+ abi: Abis.tip20,
633
+ functionName: 'approve',
634
+ args: [Addresses.zoneOutbox, amount],
635
+ }),
636
+ defineCall({
637
+ address: Addresses.zoneOutbox,
638
+ abi: ZoneAbis.zoneOutbox,
639
+ functionName: 'requestWithdrawal',
640
+ args: [
641
+ TokenId.toAddress(token),
642
+ to,
643
+ amount,
644
+ memo,
645
+ gas,
646
+ fallbackRecipient,
647
+ data,
648
+ revealTo,
649
+ ],
650
+ }),
651
+ ];
652
+ }
653
+ requestVerifiableWithdrawal.calls = calls;
654
+ })(requestVerifiableWithdrawal || (requestVerifiableWithdrawal = {}));
655
+ /**
656
+ * Requests a verifiable withdrawal from a zone to the parent Tempo chain and
657
+ * waits for the transaction receipt.
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * import { createClient } from 'viem'
662
+ * import { privateKeyToAccount } from 'viem/accounts'
663
+ * import { http, zoneModerato } from 'viem/tempo/zones'
664
+ * import { Actions } from 'viem/tempo'
665
+ *
666
+ * const client = createClient({
667
+ * account: privateKeyToAccount('0x...'),
668
+ * chain: zoneModerato(7),
669
+ * transport: http(),
670
+ * })
671
+ *
672
+ * const result = await Actions.zone.requestVerifiableWithdrawalSync(client, {
673
+ * token: '0x20c0...0001',
674
+ * amount: 1_000_000n,
675
+ * revealTo: '0x02abc...def',
676
+ * })
677
+ * ```
678
+ *
679
+ * @param client - Wallet client connected to the zone chain.
680
+ * @param parameters - Verifiable withdrawal parameters.
681
+ * @returns The transaction receipt.
682
+ */
683
+ export async function requestVerifiableWithdrawalSync(client, parameters) {
684
+ const { account = client.account, throwOnReceiptRevert = true, ...rest } = parameters;
685
+ const account_ = account ? parseAccount(account) : undefined;
686
+ if (!account)
687
+ throw new Error('`account` is required.');
688
+ const to = parameters.to ?? account_?.address;
689
+ if (!to)
690
+ throw new Error('`to` is required.');
691
+ const args = { ...parameters, to };
692
+ const receipt = await sendTransactionSync(client, {
693
+ ...rest,
694
+ calls: requestVerifiableWithdrawal.calls(args),
695
+ throwOnReceiptRevert,
696
+ });
697
+ return { receipt };
698
+ }
699
+ /**
700
+ * Signs a zone authorization token and stores it for the zone HTTP transport.
701
+ *
702
+ * Zone chains should define `contracts.zonePortal` with the portal address.
703
+ * The `zoneId` is derived from `ZoneId.fromChainId(chain.id)` and can be overridden.
704
+ *
705
+ * @example
706
+ * ```ts
707
+ * import { createClient } from 'viem'
708
+ * import { privateKeyToAccount } from 'viem/accounts'
709
+ * import { http, zoneModerato } from 'viem/tempo/zones'
710
+ * import { Actions } from 'viem/tempo'
711
+ *
712
+ * const client = createClient({
713
+ * account: privateKeyToAccount('0x...'),
714
+ * chain: zoneModerato(7),
715
+ * transport: http(),
716
+ * })
717
+ *
718
+ * const result = await Actions.zone.signAuthorizationToken(client)
719
+ * ```
720
+ *
721
+ * @param client - Zone wallet client.
722
+ * @param parameters - Options including optional storage override.
723
+ * @returns The authentication object and serialized token.
724
+ */
725
+ export async function signAuthorizationToken(client, parameters = {}) {
726
+ const { account = client.account, issuedAt = Math.floor(Date.now() / 1000), expiresAt = issuedAt + 86_400, storage = Storage.defaultStorage(), } = parameters;
727
+ const chain = parameters.chain ?? client.chain;
728
+ if (!chain)
729
+ throw new Error('`signAuthorizationToken` requires a chain.');
730
+ const account_ = account ? parseAccount(account) : undefined;
731
+ if (!account_ || !account_.sign)
732
+ throw new Error('`account` with `sign` is required.');
733
+ const storageKey = `auth:${account_.address.toLowerCase()}:${chain.id}`;
734
+ const authentication = ZoneRpcAuthentication.from({
735
+ chainId: chain.id,
736
+ expiresAt,
737
+ issuedAt,
738
+ zoneId: ZoneId.fromChainId(chain.id),
739
+ });
740
+ const payload = ZoneRpcAuthentication.getSignPayload(authentication);
741
+ const signature = await account_.sign({ hash: payload });
742
+ const token = ZoneRpcAuthentication.serialize(authentication, {
743
+ signature,
744
+ });
745
+ await storage.setItem(storageKey, token);
746
+ await storage.setItem(`auth:token:${chain.id}`, token);
747
+ return { authentication, token };
748
+ }
749
+ /**
750
+ * Encrypts a deposit payload (recipient + memo) using ECIES with AES-256-GCM.
751
+ *
752
+ * @internal
753
+ */
754
+ async function encryptDepositPayload(publicKey, recipient, memo = zeroHash) {
755
+ const sequencerPublicKey = PublicKey.from({
756
+ prefix: publicKey.yParity,
757
+ x: Hex.toBigInt(publicKey.x),
758
+ });
759
+ const { privateKey: ephemeralPrivateKey, publicKey: ephemeralPublicKey } = Secp256k1.createKeyPair();
760
+ const sharedSecret = Secp256k1.getSharedSecret({
761
+ privateKey: ephemeralPrivateKey,
762
+ publicKey: sequencerPublicKey,
763
+ as: 'Bytes',
764
+ });
765
+ const hkdfKey = await globalThis.crypto.subtle.importKey('raw', sharedSecret.buffer, 'HKDF', false, ['deriveKey']);
766
+ const aesKey = await globalThis.crypto.subtle.deriveKey({
767
+ name: 'HKDF',
768
+ hash: 'SHA-256',
769
+ salt: new Uint8Array(12),
770
+ info: new TextEncoder().encode('ecies-aes-key'),
771
+ }, hkdfKey, { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
772
+ const nonce = Bytes.random(12);
773
+ const plaintext = encodeAbiParameters([{ type: 'address' }, { type: 'bytes32' }], [recipient, memo]);
774
+ const ciphertextWithTag = new Uint8Array(await globalThis.crypto.subtle.encrypt({ name: 'AES-GCM', iv: nonce, tagLength: 128 }, aesKey, Bytes.from(plaintext)));
775
+ const ciphertext = ciphertextWithTag.slice(0, -16);
776
+ const tag = ciphertextWithTag.slice(-16);
777
+ const compressedEphemeral = PublicKey.compress(ephemeralPublicKey);
778
+ return {
779
+ ciphertext: Hex.fromBytes(ciphertext),
780
+ ephemeralPubkeyX: Hex.fromNumber(compressedEphemeral.x, { size: 32 }),
781
+ ephemeralPubkeyYParity: compressedEphemeral.prefix,
782
+ nonce: Hex.fromBytes(nonce),
783
+ tag: Hex.fromBytes(tag),
784
+ };
785
+ }
786
+ //# sourceMappingURL=zone.js.map