@wagmi/core 3.4.2 → 3.4.4

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 (35) hide show
  1. package/dist/esm/exports/tempo.js +1 -2
  2. package/dist/esm/exports/tempo.js.map +1 -1
  3. package/dist/esm/tempo/Connectors.js +278 -570
  4. package/dist/esm/tempo/Connectors.js.map +1 -1
  5. package/dist/esm/tempo/actions/index.js +1 -0
  6. package/dist/esm/tempo/actions/index.js.map +1 -1
  7. package/dist/esm/tempo/actions/zone.js +894 -0
  8. package/dist/esm/tempo/actions/zone.js.map +1 -0
  9. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  10. package/dist/esm/version.js +1 -1
  11. package/dist/types/errors/config.d.ts +1 -1
  12. package/dist/types/errors/config.d.ts.map +1 -1
  13. package/dist/types/exports/tempo.d.ts +1 -2
  14. package/dist/types/exports/tempo.d.ts.map +1 -1
  15. package/dist/types/query/verifyMessage.d.ts +1 -0
  16. package/dist/types/query/verifyMessage.d.ts.map +1 -1
  17. package/dist/types/tempo/Connectors.d.ts +58 -86
  18. package/dist/types/tempo/Connectors.d.ts.map +1 -1
  19. package/dist/types/tempo/actions/index.d.ts +1 -0
  20. package/dist/types/tempo/actions/index.d.ts.map +1 -1
  21. package/dist/types/tempo/actions/zone.d.ts +536 -0
  22. package/dist/types/tempo/actions/zone.d.ts.map +1 -0
  23. package/dist/types/version.d.ts +1 -1
  24. package/package.json +5 -1
  25. package/src/errors/config.ts +1 -1
  26. package/src/exports/tempo.ts +2 -1
  27. package/src/tempo/Connectors.ts +406 -798
  28. package/src/tempo/actions/index.ts +1 -0
  29. package/src/tempo/actions/zone.ts +1419 -0
  30. package/src/version.ts +1 -1
  31. package/dist/esm/tempo/KeyManager.js +0 -154
  32. package/dist/esm/tempo/KeyManager.js.map +0 -1
  33. package/dist/types/tempo/KeyManager.d.ts +0 -71
  34. package/dist/types/tempo/KeyManager.d.ts.map +0 -1
  35. package/src/tempo/KeyManager.ts +0 -241
@@ -0,0 +1,1419 @@
1
+ import * as Bytes from 'ox/Bytes'
2
+ import * as PublicKey from 'ox/PublicKey'
3
+ import * as Secp256k1 from 'ox/Secp256k1'
4
+ import { TokenId } from 'ox/tempo'
5
+ import {
6
+ type Account,
7
+ type Address,
8
+ encodeAbiParameters,
9
+ encodeFunctionData,
10
+ type Hex,
11
+ zeroHash,
12
+ } from 'viem'
13
+ import {
14
+ readContract as viem_readContract,
15
+ sendTransaction as viem_sendTransaction,
16
+ sendTransactionSync as viem_sendTransactionSync,
17
+ } from 'viem/actions'
18
+ import { Abis, Actions } from 'viem/tempo'
19
+ import { Abis as ZoneAbis } from 'viem/tempo/zones'
20
+ import { parseAccount } from 'viem/utils'
21
+ import { getConnectorClient } from '../../actions/getConnectorClient.js'
22
+ import type { Config } from '../../createConfig.js'
23
+ import type {
24
+ ChainIdParameter,
25
+ ConnectorParameter,
26
+ } from '../../types/properties.js'
27
+ import type { PartialBy, UnionLooseOmit } from '../../types/utils.js'
28
+ import type { QueryOptions, QueryParameter } from './utils.js'
29
+ import { filterQueryOptions } from './utils.js'
30
+
31
+ /**
32
+ * Gets information about the currently stored zone authorization token.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { createConfig } from '@wagmi/core'
37
+ * import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
38
+ * import { Account } from 'viem/tempo'
39
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
40
+ *
41
+ * const zoneChain = zone(7)
42
+ * const account = Account.fromSecp256k1('0x...')
43
+ * const config = createConfig({
44
+ * chains: [zoneChain],
45
+ * connectors: [dangerous_secp256k1({ account })],
46
+ * transports: {
47
+ * [zoneChain.id]: zoneHttp(),
48
+ * },
49
+ * })
50
+ *
51
+ * await Actions.zone.signAuthorizationToken(config, {
52
+ * chainId: zoneChain.id,
53
+ * })
54
+ *
55
+ * const info = await Actions.zone.getAuthorizationTokenInfo(config, {
56
+ * chainId: zoneChain.id,
57
+ * })
58
+ *
59
+ * console.log(info.expiresAt)
60
+ * ```
61
+ *
62
+ * @param config - Config.
63
+ * @param parameters - Parameters.
64
+ * @returns The authorization token info.
65
+ */
66
+ export function getAuthorizationTokenInfo<config extends Config>(
67
+ config: config,
68
+ parameters: getAuthorizationTokenInfo.Parameters<config>,
69
+ ): Promise<getAuthorizationTokenInfo.ReturnValue> {
70
+ const client = config.getClient({ chainId: parameters.chainId })
71
+ return Actions.zone.getAuthorizationTokenInfo(client)
72
+ }
73
+
74
+ export namespace getAuthorizationTokenInfo {
75
+ export type Parameters<config extends Config> = ChainIdParameter<config>
76
+
77
+ export type ReturnValue = Actions.zone.getAuthorizationTokenInfo.ReturnType
78
+
79
+ export type ErrorType = Actions.zone.getAuthorizationTokenInfo.ErrorType
80
+
81
+ export function queryKey<config extends Config>(
82
+ parameters: Parameters<config>,
83
+ ) {
84
+ return [
85
+ 'getAuthorizationTokenInfo',
86
+ filterQueryOptions(parameters),
87
+ ] as const
88
+ }
89
+
90
+ export type QueryKey<config extends Config> = ReturnType<
91
+ typeof queryKey<config>
92
+ >
93
+
94
+ export function queryOptions<config extends Config, selectData = ReturnValue>(
95
+ config: Config,
96
+ parameters: queryOptions.Parameters<config, selectData>,
97
+ ): queryOptions.ReturnValue<config, selectData> {
98
+ const { query, ...rest } = parameters
99
+ return {
100
+ ...query,
101
+ enabled: Boolean(query?.enabled ?? true),
102
+ queryKey: queryKey(rest),
103
+ async queryFn(context) {
104
+ const [, parameters] = context.queryKey
105
+ return await getAuthorizationTokenInfo(config, parameters)
106
+ },
107
+ }
108
+ }
109
+
110
+ export declare namespace queryOptions {
111
+ export type Parameters<
112
+ config extends Config,
113
+ selectData = getAuthorizationTokenInfo.ReturnValue,
114
+ > = getAuthorizationTokenInfo.Parameters<config> &
115
+ QueryParameter<
116
+ getAuthorizationTokenInfo.ReturnValue,
117
+ getAuthorizationTokenInfo.ErrorType,
118
+ selectData,
119
+ getAuthorizationTokenInfo.QueryKey<config>
120
+ >
121
+
122
+ export type ReturnValue<
123
+ config extends Config,
124
+ selectData = getAuthorizationTokenInfo.ReturnValue,
125
+ > = QueryOptions<
126
+ getAuthorizationTokenInfo.ReturnValue,
127
+ getAuthorizationTokenInfo.ErrorType,
128
+ selectData,
129
+ getAuthorizationTokenInfo.QueryKey<config>
130
+ >
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Gets deposit processing status for a Tempo block number.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import { createConfig } from '@wagmi/core'
140
+ * import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
141
+ * import { Account } from 'viem/tempo'
142
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
143
+ *
144
+ * const zoneChain = zone(7)
145
+ * const account = Account.fromSecp256k1('0x...')
146
+ * const config = createConfig({
147
+ * chains: [zoneChain],
148
+ * connectors: [dangerous_secp256k1({ account })],
149
+ * transports: {
150
+ * [zoneChain.id]: zoneHttp(),
151
+ * },
152
+ * })
153
+ *
154
+ * await Actions.zone.signAuthorizationToken(config, {
155
+ * chainId: zoneChain.id,
156
+ * })
157
+ *
158
+ * const status = await Actions.zone.getDepositStatus(config, {
159
+ * chainId: zoneChain.id,
160
+ * tempoBlockNumber: 42n,
161
+ * })
162
+ *
163
+ * console.log(status.processed)
164
+ * ```
165
+ *
166
+ * @param config - Config.
167
+ * @param parameters - Parameters.
168
+ * @returns The deposit status.
169
+ */
170
+ export function getDepositStatus<config extends Config>(
171
+ config: config,
172
+ parameters: getDepositStatus.Parameters<config>,
173
+ ): Promise<getDepositStatus.ReturnValue> {
174
+ const { chainId, ...rest } = parameters
175
+ const client = config.getClient({ chainId })
176
+ return Actions.zone.getDepositStatus(client, rest)
177
+ }
178
+
179
+ export namespace getDepositStatus {
180
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
181
+ Actions.zone.getDepositStatus.Parameters
182
+
183
+ export type ReturnValue = Actions.zone.getDepositStatus.ReturnType
184
+
185
+ export type ErrorType = Actions.zone.getDepositStatus.ErrorType
186
+
187
+ export function queryKey<config extends Config>(
188
+ parameters: PartialBy<Parameters<config>, 'tempoBlockNumber'>,
189
+ ) {
190
+ return ['getDepositStatus', filterQueryOptions(parameters)] as const
191
+ }
192
+
193
+ export type QueryKey<config extends Config> = ReturnType<
194
+ typeof queryKey<config>
195
+ >
196
+
197
+ export function queryOptions<config extends Config, selectData = ReturnValue>(
198
+ config: Config,
199
+ parameters: queryOptions.Parameters<config, selectData>,
200
+ ): queryOptions.ReturnValue<config, selectData> {
201
+ const { query, ...rest } = parameters
202
+ return {
203
+ ...query,
204
+ enabled: Boolean(
205
+ rest.tempoBlockNumber !== undefined && (query?.enabled ?? true),
206
+ ),
207
+ queryKey: queryKey(rest),
208
+ async queryFn(context) {
209
+ const [, { tempoBlockNumber, ...parameters }] = context.queryKey
210
+ if (tempoBlockNumber === undefined)
211
+ throw new Error('tempoBlockNumber is required.')
212
+ return await getDepositStatus(config, {
213
+ ...parameters,
214
+ tempoBlockNumber,
215
+ })
216
+ },
217
+ }
218
+ }
219
+
220
+ export declare namespace queryOptions {
221
+ export type Parameters<
222
+ config extends Config,
223
+ selectData = getDepositStatus.ReturnValue,
224
+ > = PartialBy<getDepositStatus.Parameters<config>, 'tempoBlockNumber'> &
225
+ QueryParameter<
226
+ getDepositStatus.ReturnValue,
227
+ getDepositStatus.ErrorType,
228
+ selectData,
229
+ getDepositStatus.QueryKey<config>
230
+ >
231
+
232
+ export type ReturnValue<
233
+ config extends Config,
234
+ selectData = getDepositStatus.ReturnValue,
235
+ > = QueryOptions<
236
+ getDepositStatus.ReturnValue,
237
+ getDepositStatus.ErrorType,
238
+ selectData,
239
+ getDepositStatus.QueryKey<config>
240
+ >
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Gets the withdrawal fee for a given gas limit.
246
+ *
247
+ * @example
248
+ * ```ts
249
+ * import { createConfig } from '@wagmi/core'
250
+ * import { Actions } from '@wagmi/core/tempo'
251
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
252
+ *
253
+ * const zoneChain = zone(7)
254
+ * const config = createConfig({
255
+ * chains: [zoneChain],
256
+ * transports: {
257
+ * [zoneChain.id]: zoneHttp(),
258
+ * },
259
+ * })
260
+ *
261
+ * const fee = await Actions.zone.getWithdrawalFee(config, {
262
+ * chainId: zoneChain.id,
263
+ * gas: 21_000n,
264
+ * })
265
+ *
266
+ * console.log(fee)
267
+ * ```
268
+ *
269
+ * @param config - Config.
270
+ * @param parameters - Parameters.
271
+ * @returns The withdrawal fee.
272
+ */
273
+ export function getWithdrawalFee<config extends Config>(
274
+ config: config,
275
+ parameters: getWithdrawalFee.Parameters<config>,
276
+ ): Promise<getWithdrawalFee.ReturnValue> {
277
+ const { chainId, ...rest } = parameters
278
+ const client = config.getClient({ chainId })
279
+ return Actions.zone.getWithdrawalFee(client, rest)
280
+ }
281
+
282
+ export namespace getWithdrawalFee {
283
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
284
+ Actions.zone.getWithdrawalFee.Parameters
285
+
286
+ export type ReturnValue = Actions.zone.getWithdrawalFee.ReturnType
287
+
288
+ export type ErrorType = Actions.zone.getWithdrawalFee.ErrorType
289
+
290
+ export function queryKey<config extends Config>(
291
+ parameters: Parameters<config>,
292
+ ) {
293
+ return ['getWithdrawalFee', filterQueryOptions(parameters)] as const
294
+ }
295
+
296
+ export type QueryKey<config extends Config> = ReturnType<
297
+ typeof queryKey<config>
298
+ >
299
+
300
+ export function queryOptions<config extends Config, selectData = ReturnValue>(
301
+ config: Config,
302
+ parameters: queryOptions.Parameters<config, selectData>,
303
+ ): queryOptions.ReturnValue<config, selectData> {
304
+ const { query, ...rest } = parameters
305
+ return {
306
+ ...query,
307
+ enabled: Boolean(query?.enabled ?? true),
308
+ queryKey: queryKey(rest),
309
+ async queryFn(context) {
310
+ const [, parameters] = context.queryKey
311
+ return await getWithdrawalFee(config, parameters)
312
+ },
313
+ }
314
+ }
315
+
316
+ export declare namespace queryOptions {
317
+ export type Parameters<
318
+ config extends Config,
319
+ selectData = getWithdrawalFee.ReturnValue,
320
+ > = getWithdrawalFee.Parameters<config> &
321
+ QueryParameter<
322
+ getWithdrawalFee.ReturnValue,
323
+ getWithdrawalFee.ErrorType,
324
+ selectData,
325
+ getWithdrawalFee.QueryKey<config>
326
+ >
327
+
328
+ export type ReturnValue<
329
+ config extends Config,
330
+ selectData = getWithdrawalFee.ReturnValue,
331
+ > = QueryOptions<
332
+ getWithdrawalFee.ReturnValue,
333
+ getWithdrawalFee.ErrorType,
334
+ selectData,
335
+ getWithdrawalFee.QueryKey<config>
336
+ >
337
+ }
338
+ }
339
+
340
+ /**
341
+ * Gets the current zone metadata.
342
+ *
343
+ * @example
344
+ * ```ts
345
+ * import { createConfig } from '@wagmi/core'
346
+ * import { Actions } from '@wagmi/core/tempo'
347
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
348
+ *
349
+ * const zoneChain = zone(7)
350
+ * const config = createConfig({
351
+ * chains: [zoneChain],
352
+ * transports: {
353
+ * [zoneChain.id]: zoneHttp(),
354
+ * },
355
+ * })
356
+ *
357
+ * const info = await Actions.zone.getZoneInfo(config, {
358
+ * chainId: zoneChain.id,
359
+ * })
360
+ *
361
+ * console.log(info.zoneId)
362
+ * ```
363
+ *
364
+ * @param config - Config.
365
+ * @param parameters - Parameters.
366
+ * @returns The zone metadata.
367
+ */
368
+ export function getZoneInfo<config extends Config>(
369
+ config: config,
370
+ parameters: getZoneInfo.Parameters<config>,
371
+ ): Promise<getZoneInfo.ReturnValue> {
372
+ const client = config.getClient({ chainId: parameters.chainId })
373
+ return Actions.zone.getZoneInfo(client)
374
+ }
375
+
376
+ export namespace getZoneInfo {
377
+ export type Parameters<config extends Config> = ChainIdParameter<config>
378
+
379
+ export type ReturnValue = Actions.zone.getZoneInfo.ReturnType
380
+
381
+ export type ErrorType = Actions.zone.getZoneInfo.ErrorType
382
+
383
+ export function queryKey<config extends Config>(
384
+ parameters: Parameters<config>,
385
+ ) {
386
+ return ['getZoneInfo', filterQueryOptions(parameters)] as const
387
+ }
388
+
389
+ export type QueryKey<config extends Config> = ReturnType<
390
+ typeof queryKey<config>
391
+ >
392
+
393
+ export function queryOptions<config extends Config, selectData = ReturnValue>(
394
+ config: Config,
395
+ parameters: queryOptions.Parameters<config, selectData>,
396
+ ): queryOptions.ReturnValue<config, selectData> {
397
+ const { query, ...rest } = parameters
398
+ return {
399
+ ...query,
400
+ enabled: Boolean(query?.enabled ?? true),
401
+ queryKey: queryKey(rest),
402
+ async queryFn(context) {
403
+ const [, parameters] = context.queryKey
404
+ return await getZoneInfo(config, parameters)
405
+ },
406
+ }
407
+ }
408
+
409
+ export declare namespace queryOptions {
410
+ export type Parameters<
411
+ config extends Config,
412
+ selectData = getZoneInfo.ReturnValue,
413
+ > = getZoneInfo.Parameters<config> &
414
+ QueryParameter<
415
+ getZoneInfo.ReturnValue,
416
+ getZoneInfo.ErrorType,
417
+ selectData,
418
+ getZoneInfo.QueryKey<config>
419
+ >
420
+
421
+ export type ReturnValue<
422
+ config extends Config,
423
+ selectData = getZoneInfo.ReturnValue,
424
+ > = QueryOptions<
425
+ getZoneInfo.ReturnValue,
426
+ getZoneInfo.ErrorType,
427
+ selectData,
428
+ getZoneInfo.QueryKey<config>
429
+ >
430
+ }
431
+ }
432
+
433
+ /**
434
+ * Signs and stores a zone authorization token for the configured zone transport.
435
+ *
436
+ * @example
437
+ * ```ts
438
+ * import { createConfig } from '@wagmi/core'
439
+ * import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
440
+ * import { Account } from 'viem/tempo'
441
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
442
+ *
443
+ * const zoneChain = zone(7)
444
+ * const account = Account.fromSecp256k1('0x...')
445
+ * const config = createConfig({
446
+ * chains: [zoneChain],
447
+ * connectors: [dangerous_secp256k1({ account })],
448
+ * transports: {
449
+ * [zoneChain.id]: zoneHttp(),
450
+ * },
451
+ * })
452
+ *
453
+ * const result = await Actions.zone.signAuthorizationToken(config, {
454
+ * chainId: zoneChain.id,
455
+ * })
456
+ *
457
+ * console.log(result.token)
458
+ * ```
459
+ *
460
+ * @param config - Config.
461
+ * @param parameters - Parameters.
462
+ * @returns The authentication payload and serialized token.
463
+ */
464
+ export async function signAuthorizationToken<config extends Config>(
465
+ config: config,
466
+ parameters: signAuthorizationToken.Parameters<config>,
467
+ ): Promise<signAuthorizationToken.ReturnValue> {
468
+ const { account, chainId, connector, ...rest } = parameters
469
+ const client = await getZoneWalletClient(config, {
470
+ account,
471
+ chainId,
472
+ connector,
473
+ })
474
+ return Actions.zone.signAuthorizationToken(client, rest as never)
475
+ }
476
+
477
+ export declare namespace signAuthorizationToken {
478
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
479
+ ConnectorParameter & {
480
+ account?: Address | Account | undefined
481
+ } & UnionLooseOmit<
482
+ Actions.zone.signAuthorizationToken.Parameters<Account>,
483
+ 'account' | 'chain'
484
+ >
485
+
486
+ export type ReturnValue = Actions.zone.signAuthorizationToken.ReturnType
487
+
488
+ export type ErrorType = Actions.zone.signAuthorizationToken.ErrorType
489
+ }
490
+
491
+ /**
492
+ * Deposits tokens into a zone on the parent Tempo chain.
493
+ *
494
+ * @example
495
+ * ```ts
496
+ * import { createConfig, http } from '@wagmi/core'
497
+ * import { tempoModerato } from '@wagmi/core/chains'
498
+ * import { Actions } from '@wagmi/core/tempo'
499
+ *
500
+ * const config = createConfig({
501
+ * chains: [tempoModerato],
502
+ * transports: {
503
+ * [tempoModerato.id]: http(),
504
+ * },
505
+ * })
506
+ *
507
+ * const hash = await Actions.zone.deposit(config, {
508
+ * amount: 1_000_000n,
509
+ * token: '0x20c0000000000000000000000000000000000001',
510
+ * zoneId: 7,
511
+ * })
512
+ * ```
513
+ *
514
+ * @param config - Config.
515
+ * @param parameters - Parameters.
516
+ * @returns Transaction hash.
517
+ */
518
+ export async function deposit<config extends Config>(
519
+ config: config,
520
+ parameters: deposit.Parameters<config>,
521
+ ): Promise<deposit.ReturnValue> {
522
+ const { account, chainId, connector, ...rest } = parameters
523
+ const client = await getConnectorClient(config, {
524
+ account,
525
+ assertChainId: false,
526
+ chainId,
527
+ connector,
528
+ })
529
+
530
+ const resolvedChainId = chainId ?? client.chain?.id
531
+ if (!resolvedChainId) throw new Error('`chainId` is required.')
532
+
533
+ const account_ = account ?? client.account
534
+ if (!account_) throw new Error('`account` is required.')
535
+
536
+ const accountAddress = parseAccount(account_).address
537
+ const {
538
+ amount,
539
+ memo = zeroHash,
540
+ recipient = accountAddress,
541
+ token,
542
+ zoneId,
543
+ ...tx
544
+ } = rest
545
+ const { address: portalAddress } = resolvePortal(
546
+ config,
547
+ resolvedChainId,
548
+ zoneId,
549
+ )
550
+ const tokenAddress = TokenId.toAddress(token)
551
+
552
+ return viem_sendTransaction(client, {
553
+ ...tx,
554
+ calls: [
555
+ {
556
+ data: encodeFunctionData({
557
+ abi: Abis.tip20,
558
+ functionName: 'approve',
559
+ args: [portalAddress, amount],
560
+ }),
561
+ to: tokenAddress,
562
+ },
563
+ {
564
+ data: encodeFunctionData({
565
+ abi: ZoneAbis.zonePortal,
566
+ functionName: 'deposit',
567
+ args: [tokenAddress, recipient, amount, memo],
568
+ }),
569
+ to: portalAddress,
570
+ },
571
+ ],
572
+ } as never) as never
573
+ }
574
+
575
+ export declare namespace deposit {
576
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
577
+ ConnectorParameter &
578
+ UnionLooseOmit<
579
+ Actions.zone.deposit.Parameters<config['chains'][number], Account>,
580
+ 'chain'
581
+ >
582
+
583
+ export type ReturnValue = Actions.zone.deposit.ReturnValue
584
+
585
+ export type ErrorType = Actions.zone.deposit.ErrorType
586
+ }
587
+
588
+ /**
589
+ * Deposits tokens into a zone on the parent Tempo chain.
590
+ *
591
+ * Note: This is a synchronous action that waits for the transaction to
592
+ * be included on a block before returning a response.
593
+ *
594
+ * @example
595
+ * ```ts
596
+ * import { createConfig, http } from '@wagmi/core'
597
+ * import { tempoModerato } from '@wagmi/core/chains'
598
+ * import { Actions } from '@wagmi/core/tempo'
599
+ *
600
+ * const config = createConfig({
601
+ * chains: [tempoModerato],
602
+ * transports: {
603
+ * [tempoModerato.id]: http(),
604
+ * },
605
+ * })
606
+ *
607
+ * const result = await Actions.zone.depositSync(config, {
608
+ * amount: 1_000_000n,
609
+ * token: '0x20c0000000000000000000000000000000000001',
610
+ * zoneId: 7,
611
+ * })
612
+ *
613
+ * console.log(result.receipt.transactionHash)
614
+ * ```
615
+ *
616
+ * @param config - Config.
617
+ * @param parameters - Parameters.
618
+ * @returns The transaction receipt.
619
+ */
620
+ export async function depositSync<config extends Config>(
621
+ config: config,
622
+ parameters: depositSync.Parameters<config>,
623
+ ): Promise<depositSync.ReturnValue> {
624
+ const {
625
+ account,
626
+ chainId,
627
+ connector,
628
+ throwOnReceiptRevert = true,
629
+ ...rest
630
+ } = parameters
631
+ const client = await getConnectorClient(config, {
632
+ account,
633
+ assertChainId: false,
634
+ chainId,
635
+ connector,
636
+ })
637
+
638
+ const resolvedChainId = chainId ?? client.chain?.id
639
+ if (!resolvedChainId) throw new Error('`chainId` is required.')
640
+
641
+ const account_ = account ?? client.account
642
+ if (!account_) throw new Error('`account` is required.')
643
+
644
+ const accountAddress = parseAccount(account_).address
645
+ const {
646
+ amount,
647
+ memo = zeroHash,
648
+ recipient = accountAddress,
649
+ token,
650
+ zoneId,
651
+ ...tx
652
+ } = rest
653
+ const { address: portalAddress } = resolvePortal(
654
+ config,
655
+ resolvedChainId,
656
+ zoneId,
657
+ )
658
+ const tokenAddress = TokenId.toAddress(token)
659
+
660
+ const receipt = await viem_sendTransactionSync(client, {
661
+ ...tx,
662
+ calls: [
663
+ {
664
+ data: encodeFunctionData({
665
+ abi: Abis.tip20,
666
+ functionName: 'approve',
667
+ args: [portalAddress, amount],
668
+ }),
669
+ to: tokenAddress,
670
+ },
671
+ {
672
+ data: encodeFunctionData({
673
+ abi: ZoneAbis.zonePortal,
674
+ functionName: 'deposit',
675
+ args: [tokenAddress, recipient, amount, memo],
676
+ }),
677
+ to: portalAddress,
678
+ },
679
+ ],
680
+ throwOnReceiptRevert,
681
+ } as never)
682
+
683
+ return { receipt }
684
+ }
685
+
686
+ export declare namespace depositSync {
687
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
688
+ ConnectorParameter &
689
+ UnionLooseOmit<
690
+ Actions.zone.depositSync.Parameters<config['chains'][number], Account>,
691
+ 'chain'
692
+ >
693
+
694
+ export type ReturnValue = Actions.zone.depositSync.ReturnValue
695
+
696
+ export type ErrorType = Actions.zone.depositSync.ErrorType
697
+ }
698
+
699
+ /**
700
+ * Deposits tokens into a zone on the parent Tempo chain with an encrypted
701
+ * recipient and memo.
702
+ *
703
+ * @example
704
+ * ```ts
705
+ * import { createConfig, http } from '@wagmi/core'
706
+ * import { tempoModerato } from '@wagmi/core/chains'
707
+ * import { Actions } from '@wagmi/core/tempo'
708
+ *
709
+ * const config = createConfig({
710
+ * chains: [tempoModerato],
711
+ * transports: {
712
+ * [tempoModerato.id]: http(),
713
+ * },
714
+ * })
715
+ *
716
+ * const hash = await Actions.zone.encryptedDeposit(config, {
717
+ * amount: 1_000_000n,
718
+ * token: '0x20c0000000000000000000000000000000000001',
719
+ * zoneId: 7,
720
+ * })
721
+ * ```
722
+ *
723
+ * @param config - Config.
724
+ * @param parameters - Parameters.
725
+ * @returns Transaction hash.
726
+ */
727
+ export async function encryptedDeposit<config extends Config>(
728
+ config: config,
729
+ parameters: encryptedDeposit.Parameters<config>,
730
+ ): Promise<encryptedDeposit.ReturnValue> {
731
+ const { account, chainId, connector, ...rest } = parameters
732
+ const client = await getConnectorClient(config, {
733
+ account,
734
+ assertChainId: false,
735
+ chainId,
736
+ connector,
737
+ })
738
+
739
+ const resolvedChainId = chainId ?? client.chain?.id
740
+ if (!resolvedChainId) throw new Error('`chainId` is required.')
741
+
742
+ const account_ = account ?? client.account
743
+ if (!account_) throw new Error('`account` is required.')
744
+
745
+ const accountAddress = parseAccount(account_).address
746
+ const {
747
+ amount,
748
+ memo,
749
+ recipient = accountAddress,
750
+ token,
751
+ zoneId,
752
+ ...tx
753
+ } = rest
754
+ const portal = resolvePortal(config, resolvedChainId, zoneId)
755
+ const portalAddress = portal.address
756
+ const tokenAddress = TokenId.toAddress(token)
757
+ const [publicKey, keyIndex] =
758
+ portal.sequencerEncryptionKey && portal.encryptionKeyCount !== undefined
759
+ ? [portal.sequencerEncryptionKey, portal.encryptionKeyCount]
760
+ : await Promise.all([
761
+ viem_readContract(client, {
762
+ address: portalAddress,
763
+ abi: ZoneAbis.zonePortal,
764
+ functionName: 'sequencerEncryptionKey',
765
+ }).then(([x, yParity]) => ({ x, yParity: Number(yParity) })),
766
+ viem_readContract(client, {
767
+ address: portalAddress,
768
+ abi: ZoneAbis.zonePortal,
769
+ functionName: 'encryptionKeyCount',
770
+ }),
771
+ ])
772
+ if (keyIndex === 0n)
773
+ throw new Error('No sequencer encryption key configured.')
774
+ const encrypted = await encryptDepositPayload(publicKey, recipient, memo)
775
+
776
+ return viem_sendTransaction(client, {
777
+ ...tx,
778
+ calls: [
779
+ {
780
+ data: encodeFunctionData({
781
+ abi: Abis.tip20,
782
+ functionName: 'approve',
783
+ args: [portalAddress, amount],
784
+ }),
785
+ to: tokenAddress,
786
+ },
787
+ {
788
+ data: encodeFunctionData({
789
+ abi: ZoneAbis.zonePortal,
790
+ functionName: 'depositEncrypted',
791
+ args: [tokenAddress, amount, keyIndex - 1n, encrypted],
792
+ }),
793
+ to: portalAddress,
794
+ },
795
+ ],
796
+ } as never) as never
797
+ }
798
+
799
+ export declare namespace encryptedDeposit {
800
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
801
+ ConnectorParameter &
802
+ UnionLooseOmit<
803
+ Actions.zone.encryptedDeposit.Parameters<
804
+ config['chains'][number],
805
+ Account
806
+ >,
807
+ 'chain'
808
+ >
809
+
810
+ export type ReturnValue = Actions.zone.encryptedDeposit.ReturnValue
811
+
812
+ export type ErrorType = Actions.zone.encryptedDeposit.ErrorType
813
+ }
814
+
815
+ /**
816
+ * Deposits tokens into a zone on the parent Tempo chain with an encrypted
817
+ * recipient and memo.
818
+ *
819
+ * Note: This is a synchronous action that waits for the transaction to
820
+ * be included on a block before returning a response.
821
+ *
822
+ * @example
823
+ * ```ts
824
+ * import { createConfig, http } from '@wagmi/core'
825
+ * import { tempoModerato } from '@wagmi/core/chains'
826
+ * import { Actions } from '@wagmi/core/tempo'
827
+ *
828
+ * const config = createConfig({
829
+ * chains: [tempoModerato],
830
+ * transports: {
831
+ * [tempoModerato.id]: http(),
832
+ * },
833
+ * })
834
+ *
835
+ * const result = await Actions.zone.encryptedDepositSync(config, {
836
+ * amount: 1_000_000n,
837
+ * token: '0x20c0000000000000000000000000000000000001',
838
+ * zoneId: 7,
839
+ * })
840
+ *
841
+ * console.log(result.receipt.transactionHash)
842
+ * ```
843
+ *
844
+ * @param config - Config.
845
+ * @param parameters - Parameters.
846
+ * @returns The transaction receipt.
847
+ */
848
+ export async function encryptedDepositSync<config extends Config>(
849
+ config: config,
850
+ parameters: encryptedDepositSync.Parameters<config>,
851
+ ): Promise<encryptedDepositSync.ReturnValue> {
852
+ const {
853
+ account,
854
+ chainId,
855
+ connector,
856
+ throwOnReceiptRevert = true,
857
+ ...rest
858
+ } = parameters
859
+ const client = await getConnectorClient(config, {
860
+ account,
861
+ assertChainId: false,
862
+ chainId,
863
+ connector,
864
+ })
865
+
866
+ const resolvedChainId = chainId ?? client.chain?.id
867
+ if (!resolvedChainId) throw new Error('`chainId` is required.')
868
+
869
+ const account_ = account ?? client.account
870
+ if (!account_) throw new Error('`account` is required.')
871
+
872
+ const accountAddress = parseAccount(account_).address
873
+ const {
874
+ amount,
875
+ memo,
876
+ recipient = accountAddress,
877
+ token,
878
+ zoneId,
879
+ ...tx
880
+ } = rest
881
+ const portal = resolvePortal(config, resolvedChainId, zoneId)
882
+ const portalAddress = portal.address
883
+ const tokenAddress = TokenId.toAddress(token)
884
+ const [publicKey, keyIndex] =
885
+ portal.sequencerEncryptionKey && portal.encryptionKeyCount !== undefined
886
+ ? [portal.sequencerEncryptionKey, portal.encryptionKeyCount]
887
+ : await Promise.all([
888
+ viem_readContract(client, {
889
+ address: portalAddress,
890
+ abi: ZoneAbis.zonePortal,
891
+ functionName: 'sequencerEncryptionKey',
892
+ }).then(([x, yParity]) => ({ x, yParity: Number(yParity) })),
893
+ viem_readContract(client, {
894
+ address: portalAddress,
895
+ abi: ZoneAbis.zonePortal,
896
+ functionName: 'encryptionKeyCount',
897
+ }),
898
+ ])
899
+ if (keyIndex === 0n)
900
+ throw new Error('No sequencer encryption key configured.')
901
+ const encrypted = await encryptDepositPayload(publicKey, recipient, memo)
902
+
903
+ const receipt = await viem_sendTransactionSync(client, {
904
+ ...tx,
905
+ calls: [
906
+ {
907
+ data: encodeFunctionData({
908
+ abi: Abis.tip20,
909
+ functionName: 'approve',
910
+ args: [portalAddress, amount],
911
+ }),
912
+ to: tokenAddress,
913
+ },
914
+ {
915
+ data: encodeFunctionData({
916
+ abi: ZoneAbis.zonePortal,
917
+ functionName: 'depositEncrypted',
918
+ args: [tokenAddress, amount, keyIndex - 1n, encrypted],
919
+ }),
920
+ to: portalAddress,
921
+ },
922
+ ],
923
+ throwOnReceiptRevert,
924
+ } as never)
925
+
926
+ return { receipt }
927
+ }
928
+
929
+ export declare namespace encryptedDepositSync {
930
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
931
+ ConnectorParameter &
932
+ UnionLooseOmit<
933
+ Actions.zone.encryptedDepositSync.Parameters<
934
+ config['chains'][number],
935
+ Account
936
+ >,
937
+ 'chain'
938
+ >
939
+
940
+ export type ReturnValue = Actions.zone.encryptedDepositSync.ReturnValue
941
+
942
+ export type ErrorType = Actions.zone.encryptedDepositSync.ErrorType
943
+ }
944
+
945
+ /**
946
+ * Requests a withdrawal from a zone to the parent Tempo chain.
947
+ *
948
+ * @example
949
+ * ```ts
950
+ * import { createConfig } from '@wagmi/core'
951
+ * import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
952
+ * import { Account } from 'viem/tempo'
953
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
954
+ *
955
+ * const zoneChain = zone(7)
956
+ * const account = Account.fromSecp256k1('0x...')
957
+ * const config = createConfig({
958
+ * chains: [zoneChain],
959
+ * connectors: [dangerous_secp256k1({ account })],
960
+ * transports: {
961
+ * [zoneChain.id]: zoneHttp(),
962
+ * },
963
+ * })
964
+ *
965
+ * const hash = await Actions.zone.requestWithdrawal(config, {
966
+ * amount: 1_000_000n,
967
+ * chainId: zoneChain.id,
968
+ * token: '0x20c0000000000000000000000000000000000001',
969
+ * })
970
+ *
971
+ * console.log(hash)
972
+ * ```
973
+ *
974
+ * @param config - Config.
975
+ * @param parameters - Parameters.
976
+ * @returns Transaction hash.
977
+ */
978
+ export async function requestWithdrawal<config extends Config>(
979
+ config: config,
980
+ parameters: requestWithdrawal.Parameters<config>,
981
+ ): Promise<requestWithdrawal.ReturnValue> {
982
+ const { account, chainId, connector } = parameters
983
+ const client = await getZoneWalletClient(config, {
984
+ account,
985
+ chainId,
986
+ connector,
987
+ })
988
+ return Actions.zone.requestWithdrawal(client, parameters as never)
989
+ }
990
+
991
+ export declare namespace requestWithdrawal {
992
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
993
+ ConnectorParameter &
994
+ UnionLooseOmit<
995
+ Actions.zone.requestWithdrawal.Parameters<
996
+ config['chains'][number],
997
+ Account
998
+ >,
999
+ 'chain'
1000
+ >
1001
+
1002
+ export type ReturnValue = Actions.zone.requestWithdrawal.ReturnValue
1003
+
1004
+ export type ErrorType = Actions.zone.requestWithdrawal.ErrorType
1005
+ }
1006
+
1007
+ /**
1008
+ * Requests a withdrawal from a zone to the parent Tempo chain.
1009
+ *
1010
+ * Note: This is a synchronous action that waits for the transaction to
1011
+ * be included on a block before returning a response.
1012
+ *
1013
+ * @example
1014
+ * ```ts
1015
+ * import { createConfig } from '@wagmi/core'
1016
+ * import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
1017
+ * import { Account } from 'viem/tempo'
1018
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
1019
+ *
1020
+ * const zoneChain = zone(7)
1021
+ * const account = Account.fromSecp256k1('0x...')
1022
+ * const config = createConfig({
1023
+ * chains: [zoneChain],
1024
+ * connectors: [dangerous_secp256k1({ account })],
1025
+ * transports: {
1026
+ * [zoneChain.id]: zoneHttp(),
1027
+ * },
1028
+ * })
1029
+ *
1030
+ * const result = await Actions.zone.requestWithdrawalSync(config, {
1031
+ * amount: 1_000_000n,
1032
+ * chainId: zoneChain.id,
1033
+ * token: '0x20c0000000000000000000000000000000000001',
1034
+ * })
1035
+ *
1036
+ * console.log(result.receipt.transactionHash)
1037
+ * ```
1038
+ *
1039
+ * @param config - Config.
1040
+ * @param parameters - Parameters.
1041
+ * @returns The transaction receipt.
1042
+ */
1043
+ export async function requestWithdrawalSync<config extends Config>(
1044
+ config: config,
1045
+ parameters: requestWithdrawalSync.Parameters<config>,
1046
+ ): Promise<requestWithdrawalSync.ReturnValue> {
1047
+ const { account, chainId, connector } = parameters
1048
+ const client = await getZoneWalletClient(config, {
1049
+ account,
1050
+ chainId,
1051
+ connector,
1052
+ })
1053
+ return Actions.zone.requestWithdrawalSync(client, parameters as never)
1054
+ }
1055
+
1056
+ export declare namespace requestWithdrawalSync {
1057
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
1058
+ ConnectorParameter &
1059
+ UnionLooseOmit<
1060
+ Actions.zone.requestWithdrawalSync.Parameters<
1061
+ config['chains'][number],
1062
+ Account
1063
+ >,
1064
+ 'chain'
1065
+ >
1066
+
1067
+ export type ReturnValue = Actions.zone.requestWithdrawalSync.ReturnValue
1068
+
1069
+ export type ErrorType = Actions.zone.requestWithdrawalSync.ErrorType
1070
+ }
1071
+
1072
+ /**
1073
+ * Requests a verifiable withdrawal from a zone to the parent Tempo chain.
1074
+ *
1075
+ * @example
1076
+ * ```ts
1077
+ * import { createConfig } from '@wagmi/core'
1078
+ * import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
1079
+ * import { Account } from 'viem/tempo'
1080
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
1081
+ *
1082
+ * const zoneChain = zone(7)
1083
+ * const account = Account.fromSecp256k1('0x...')
1084
+ * const config = createConfig({
1085
+ * chains: [zoneChain],
1086
+ * connectors: [dangerous_secp256k1({ account })],
1087
+ * transports: {
1088
+ * [zoneChain.id]: zoneHttp(),
1089
+ * },
1090
+ * })
1091
+ *
1092
+ * const hash = await Actions.zone.requestVerifiableWithdrawal(config, {
1093
+ * amount: 1_000_000n,
1094
+ * chainId: zoneChain.id,
1095
+ * revealTo:
1096
+ * '0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
1097
+ * token: '0x20c0000000000000000000000000000000000001',
1098
+ * })
1099
+ *
1100
+ * console.log(hash)
1101
+ * ```
1102
+ *
1103
+ * @param config - Config.
1104
+ * @param parameters - Parameters.
1105
+ * @returns Transaction hash.
1106
+ */
1107
+ export async function requestVerifiableWithdrawal<config extends Config>(
1108
+ config: config,
1109
+ parameters: requestVerifiableWithdrawal.Parameters<config>,
1110
+ ): Promise<requestVerifiableWithdrawal.ReturnValue> {
1111
+ const { account, chainId, connector } = parameters
1112
+ const client = await getZoneWalletClient(config, {
1113
+ account,
1114
+ chainId,
1115
+ connector,
1116
+ })
1117
+ return Actions.zone.requestVerifiableWithdrawal(client, parameters as never)
1118
+ }
1119
+
1120
+ export declare namespace requestVerifiableWithdrawal {
1121
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
1122
+ ConnectorParameter &
1123
+ UnionLooseOmit<
1124
+ Actions.zone.requestVerifiableWithdrawal.Parameters<
1125
+ config['chains'][number],
1126
+ Account
1127
+ >,
1128
+ 'chain'
1129
+ >
1130
+
1131
+ export type ReturnValue = Actions.zone.requestVerifiableWithdrawal.ReturnValue
1132
+
1133
+ export type ErrorType = Actions.zone.requestVerifiableWithdrawal.ErrorType
1134
+ }
1135
+
1136
+ /**
1137
+ * Requests a verifiable withdrawal from a zone to the parent Tempo chain.
1138
+ *
1139
+ * Note: This is a synchronous action that waits for the transaction to
1140
+ * be included on a block before returning a response.
1141
+ *
1142
+ * @example
1143
+ * ```ts
1144
+ * import { createConfig } from '@wagmi/core'
1145
+ * import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
1146
+ * import { Account } from 'viem/tempo'
1147
+ * import { http as zoneHttp, zone } from 'viem/tempo/zones'
1148
+ *
1149
+ * const zoneChain = zone(7)
1150
+ * const account = Account.fromSecp256k1('0x...')
1151
+ * const config = createConfig({
1152
+ * chains: [zoneChain],
1153
+ * connectors: [dangerous_secp256k1({ account })],
1154
+ * transports: {
1155
+ * [zoneChain.id]: zoneHttp(),
1156
+ * },
1157
+ * })
1158
+ *
1159
+ * const result = await Actions.zone.requestVerifiableWithdrawalSync(config, {
1160
+ * amount: 1_000_000n,
1161
+ * chainId: zoneChain.id,
1162
+ * revealTo:
1163
+ * '0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
1164
+ * token: '0x20c0000000000000000000000000000000000001',
1165
+ * })
1166
+ *
1167
+ * console.log(result.receipt.transactionHash)
1168
+ * ```
1169
+ *
1170
+ * @param config - Config.
1171
+ * @param parameters - Parameters.
1172
+ * @returns The transaction receipt.
1173
+ */
1174
+ export async function requestVerifiableWithdrawalSync<config extends Config>(
1175
+ config: config,
1176
+ parameters: requestVerifiableWithdrawalSync.Parameters<config>,
1177
+ ): Promise<requestVerifiableWithdrawalSync.ReturnValue> {
1178
+ const { account, chainId, connector } = parameters
1179
+ const client = await getZoneWalletClient(config, {
1180
+ account,
1181
+ chainId,
1182
+ connector,
1183
+ })
1184
+ return Actions.zone.requestVerifiableWithdrawalSync(
1185
+ client,
1186
+ parameters as never,
1187
+ )
1188
+ }
1189
+
1190
+ export declare namespace requestVerifiableWithdrawalSync {
1191
+ export type Parameters<config extends Config> = ChainIdParameter<config> &
1192
+ ConnectorParameter &
1193
+ UnionLooseOmit<
1194
+ Actions.zone.requestVerifiableWithdrawalSync.Parameters<
1195
+ config['chains'][number],
1196
+ Account
1197
+ >,
1198
+ 'chain'
1199
+ >
1200
+
1201
+ export type ReturnValue =
1202
+ Actions.zone.requestVerifiableWithdrawalSync.ReturnValue
1203
+
1204
+ export type ErrorType = Actions.zone.requestVerifiableWithdrawalSync.ErrorType
1205
+ }
1206
+
1207
+ const portalAddresses = {
1208
+ 42431: {
1209
+ 6: '0x7069DeC4E64Fd07334A0933eDe836C17259c9B23',
1210
+ 7: '0x3F5296303400B56271b476F5A0B9cBF74350D6Ac',
1211
+ },
1212
+ } as const satisfies Record<number, Record<number, Address>>
1213
+
1214
+ async function getZoneWalletClient<config extends Config>(
1215
+ config: config,
1216
+ parameters: {
1217
+ account?: Address | Account | null | undefined
1218
+ chainId?: number | undefined
1219
+ connector?: ConnectorParameter['connector']
1220
+ },
1221
+ ) {
1222
+ const client = await getConnectorClient(config, {
1223
+ ...parameters,
1224
+ assertChainId: false,
1225
+ })
1226
+ const resolvedChainId = parameters.chainId ?? client.chain?.id
1227
+ const account =
1228
+ resolveSignableAccount(parameters.account) ??
1229
+ (await getSignableConnectorAccount(config, {
1230
+ account: parameters.account ?? client.account,
1231
+ chainId: resolvedChainId,
1232
+ connector: parameters.connector,
1233
+ }))
1234
+ if (!account || resolvedChainId === undefined) return client
1235
+
1236
+ // Local accounts can sign against the zone transport directly without
1237
+ // depending on the connector provider's currently selected chain.
1238
+ return Object.assign(config.getClient({ chainId: resolvedChainId }), {
1239
+ account,
1240
+ }) as typeof client
1241
+ }
1242
+
1243
+ async function getSignableConnectorAccount<config extends Config>(
1244
+ config: config,
1245
+ parameters: {
1246
+ account?: Address | Account | null | undefined
1247
+ chainId?: number | undefined
1248
+ connector?: ConnectorParameter['connector']
1249
+ },
1250
+ ) {
1251
+ const connector =
1252
+ parameters.connector ??
1253
+ config.state.connections.get(config.state.current!)?.connector
1254
+ const provider = (await connector?.getProvider?.({
1255
+ chainId: parameters.chainId,
1256
+ })) as
1257
+ | {
1258
+ getAccount?:
1259
+ | ((parameters?: {
1260
+ address?: Address | undefined
1261
+ signable?: boolean | undefined
1262
+ }) => Account | undefined)
1263
+ | undefined
1264
+ }
1265
+ | undefined
1266
+ if (typeof provider?.getAccount !== 'function') return
1267
+
1268
+ try {
1269
+ return provider.getAccount({
1270
+ address: parameters.account
1271
+ ? parseAccount(parameters.account).address
1272
+ : undefined,
1273
+ signable: true,
1274
+ })
1275
+ } catch {
1276
+ return
1277
+ }
1278
+ }
1279
+
1280
+ function resolveSignableAccount(
1281
+ account?: Address | Account | null | undefined,
1282
+ ) {
1283
+ if (typeof account !== 'object' || account === null) return
1284
+ return 'sign' in account ? account : undefined
1285
+ }
1286
+
1287
+ function resolvePortal<config extends Config>(
1288
+ config: config,
1289
+ chainId: number,
1290
+ zoneId: number,
1291
+ ): {
1292
+ address: Address
1293
+ encryptionKeyCount?: bigint | undefined
1294
+ sequencerEncryptionKey?: { x: Hex; yParity: number } | undefined
1295
+ } {
1296
+ const chain = config.chains.find((chain) => chain.id === chainId)
1297
+ const zonePortal = chain?.contracts?.zonePortal as
1298
+ | Address
1299
+ | {
1300
+ [key: number]:
1301
+ | Address
1302
+ | {
1303
+ address?: Address | undefined
1304
+ encryptionKeyCount?: bigint | undefined
1305
+ sequencerEncryptionKey?: { x: Hex; yParity: number } | undefined
1306
+ }
1307
+ | undefined
1308
+ address?: Address | undefined
1309
+ encryptionKeyCount?: bigint | undefined
1310
+ sequencerEncryptionKey?: { x: Hex; yParity: number } | undefined
1311
+ }
1312
+ | undefined
1313
+
1314
+ // Allow custom chains to supply portal addresses until viem exposes a
1315
+ // generic resolver for non-hardcoded Tempo networks.
1316
+ if (typeof zonePortal === 'string') return { address: zonePortal }
1317
+ if (zonePortal && typeof zonePortal === 'object') {
1318
+ const portal =
1319
+ 'address' in zonePortal && typeof zonePortal.address === 'string'
1320
+ ? zonePortal
1321
+ : zonePortal[zoneId]
1322
+
1323
+ if (typeof portal === 'string') return { address: portal as Address }
1324
+ if (
1325
+ portal &&
1326
+ typeof portal === 'object' &&
1327
+ typeof portal.address === 'string'
1328
+ ) {
1329
+ return {
1330
+ address: portal.address,
1331
+ encryptionKeyCount: portal.encryptionKeyCount,
1332
+ sequencerEncryptionKey: portal.sequencerEncryptionKey,
1333
+ }
1334
+ }
1335
+ }
1336
+
1337
+ const address = (portalAddresses as Record<number, Record<number, Address>>)[
1338
+ chainId
1339
+ ]?.[zoneId]
1340
+ if (address) return { address }
1341
+
1342
+ throw new Error(
1343
+ `No portal address configured for zone ${zoneId} on chain ${chainId}.`,
1344
+ )
1345
+ }
1346
+
1347
+ async function encryptDepositPayload(
1348
+ publicKey: { x: Hex; yParity: number },
1349
+ recipient: Address,
1350
+ memo: Hex = zeroHash,
1351
+ ): Promise<{
1352
+ ciphertext: Hex
1353
+ ephemeralPubkeyX: Hex
1354
+ ephemeralPubkeyYParity: number
1355
+ nonce: Hex
1356
+ tag: Hex
1357
+ }> {
1358
+ const sequencerPublicKey = PublicKey.from({
1359
+ prefix: publicKey.yParity,
1360
+ x: BigInt(publicKey.x),
1361
+ })
1362
+
1363
+ const { privateKey: ephemeralPrivateKey, publicKey: ephemeralPublicKey } =
1364
+ Secp256k1.createKeyPair()
1365
+
1366
+ const sharedSecret = Secp256k1.getSharedSecret({
1367
+ privateKey: ephemeralPrivateKey,
1368
+ publicKey: sequencerPublicKey,
1369
+ as: 'Bytes',
1370
+ })
1371
+
1372
+ const hkdfKey = await globalThis.crypto.subtle.importKey(
1373
+ 'raw',
1374
+ sharedSecret.buffer as ArrayBuffer,
1375
+ 'HKDF',
1376
+ false,
1377
+ ['deriveKey'],
1378
+ )
1379
+ const aesKey = await globalThis.crypto.subtle.deriveKey(
1380
+ {
1381
+ name: 'HKDF',
1382
+ hash: 'SHA-256',
1383
+ salt: new Uint8Array(12),
1384
+ info: new TextEncoder().encode('ecies-aes-key'),
1385
+ },
1386
+ hkdfKey,
1387
+ { name: 'AES-GCM', length: 256 },
1388
+ false,
1389
+ ['encrypt'],
1390
+ )
1391
+
1392
+ const nonce = Bytes.random(12)
1393
+ const plaintext = encodeAbiParameters(
1394
+ [{ type: 'address' }, { type: 'bytes32' }],
1395
+ [recipient, memo],
1396
+ )
1397
+ const ciphertextWithTag = new Uint8Array(
1398
+ await globalThis.crypto.subtle.encrypt(
1399
+ { name: 'AES-GCM', iv: nonce as BufferSource, tagLength: 128 },
1400
+ aesKey,
1401
+ Bytes.from(plaintext) as BufferSource,
1402
+ ),
1403
+ )
1404
+ const ciphertext = ciphertextWithTag.slice(0, -16)
1405
+ const tag = ciphertextWithTag.slice(-16)
1406
+ const compressedEphemeral = PublicKey.compress(ephemeralPublicKey)
1407
+
1408
+ return {
1409
+ ciphertext: bytesToHex(ciphertext),
1410
+ ephemeralPubkeyX: `0x${compressedEphemeral.x.toString(16).padStart(64, '0')}`,
1411
+ ephemeralPubkeyYParity: compressedEphemeral.prefix,
1412
+ nonce: bytesToHex(nonce),
1413
+ tag: bytesToHex(tag),
1414
+ }
1415
+ }
1416
+
1417
+ function bytesToHex(bytes: Uint8Array): Hex {
1418
+ return `0x${Array.from(bytes, (value) => value.toString(16).padStart(2, '0')).join('')}` as Hex
1419
+ }