viem 2.55.11 → 2.55.15

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 (105) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/_cjs/actions/index.js +4 -2
  3. package/_cjs/actions/index.js.map +1 -1
  4. package/_cjs/actions/public/watchBlockHeaders.js +61 -0
  5. package/_cjs/actions/public/watchBlockHeaders.js.map +1 -0
  6. package/_cjs/actions/wallet/prepareTransactionRequest.js +12 -12
  7. package/_cjs/actions/wallet/prepareTransactionRequest.js.map +1 -1
  8. package/_cjs/actions/wallet/sendTransaction.js +24 -12
  9. package/_cjs/actions/wallet/sendTransaction.js.map +1 -1
  10. package/_cjs/actions/wallet/sendTransactionSync.js +24 -12
  11. package/_cjs/actions/wallet/sendTransactionSync.js.map +1 -1
  12. package/_cjs/clients/createClient.js +1 -0
  13. package/_cjs/clients/createClient.js.map +1 -1
  14. package/_cjs/clients/decorators/public.js +2 -0
  15. package/_cjs/clients/decorators/public.js.map +1 -1
  16. package/_cjs/errors/version.js +1 -1
  17. package/_cjs/index.js.map +1 -1
  18. package/_cjs/tempo/Decorator.js +7 -0
  19. package/_cjs/tempo/Decorator.js.map +1 -1
  20. package/_cjs/tempo/actions/earn/deployment.js +654 -0
  21. package/_cjs/tempo/actions/earn/deployment.js.map +1 -0
  22. package/_cjs/tempo/actions/earn.js +17 -0
  23. package/_cjs/tempo/actions/earn.js.map +1 -1
  24. package/_cjs/tempo/actions/zone.js +29 -9
  25. package/_cjs/tempo/actions/zone.js.map +1 -1
  26. package/_cjs/tempo/chainConfig.js +24 -23
  27. package/_cjs/tempo/chainConfig.js.map +1 -1
  28. package/_cjs/tempo/internal/WithdrawalSenderTag.js +2 -2
  29. package/_cjs/tempo/internal/WithdrawalSenderTag.js.map +1 -1
  30. package/_cjs/tempo/zones/Abis.js +17 -0
  31. package/_cjs/tempo/zones/Abis.js.map +1 -1
  32. package/_esm/actions/index.js +1 -0
  33. package/_esm/actions/index.js.map +1 -1
  34. package/_esm/actions/public/watchBlockHeaders.js +81 -0
  35. package/_esm/actions/public/watchBlockHeaders.js.map +1 -0
  36. package/_esm/actions/wallet/prepareTransactionRequest.js +14 -13
  37. package/_esm/actions/wallet/prepareTransactionRequest.js.map +1 -1
  38. package/_esm/actions/wallet/sendTransaction.js +24 -12
  39. package/_esm/actions/wallet/sendTransaction.js.map +1 -1
  40. package/_esm/actions/wallet/sendTransactionSync.js +24 -12
  41. package/_esm/actions/wallet/sendTransactionSync.js.map +1 -1
  42. package/_esm/clients/createClient.js +4 -3
  43. package/_esm/clients/createClient.js.map +1 -1
  44. package/_esm/clients/decorators/public.js +2 -0
  45. package/_esm/clients/decorators/public.js.map +1 -1
  46. package/_esm/errors/version.js +1 -1
  47. package/_esm/index.js.map +1 -1
  48. package/_esm/tempo/Decorator.js +7 -0
  49. package/_esm/tempo/Decorator.js.map +1 -1
  50. package/_esm/tempo/actions/earn/deployment.js +967 -0
  51. package/_esm/tempo/actions/earn/deployment.js.map +1 -0
  52. package/_esm/tempo/actions/earn.js +4 -0
  53. package/_esm/tempo/actions/earn.js.map +1 -1
  54. package/_esm/tempo/actions/zone.js +31 -9
  55. package/_esm/tempo/actions/zone.js.map +1 -1
  56. package/_esm/tempo/chainConfig.js +26 -28
  57. package/_esm/tempo/chainConfig.js.map +1 -1
  58. package/_esm/tempo/internal/WithdrawalSenderTag.js +3 -3
  59. package/_esm/tempo/internal/WithdrawalSenderTag.js.map +1 -1
  60. package/_esm/tempo/zones/Abis.js +17 -0
  61. package/_esm/tempo/zones/Abis.js.map +1 -1
  62. package/_types/actions/index.d.ts +1 -0
  63. package/_types/actions/index.d.ts.map +1 -1
  64. package/_types/actions/public/watchBlockHeaders.d.ts +45 -0
  65. package/_types/actions/public/watchBlockHeaders.d.ts.map +1 -0
  66. package/_types/actions/wallet/prepareTransactionRequest.d.ts.map +1 -1
  67. package/_types/actions/wallet/sendTransaction.d.ts.map +1 -1
  68. package/_types/actions/wallet/sendTransactionSync.d.ts.map +1 -1
  69. package/_types/clients/createClient.d.ts +3 -3
  70. package/_types/clients/createClient.d.ts.map +1 -1
  71. package/_types/clients/decorators/public.d.ts +24 -0
  72. package/_types/clients/decorators/public.d.ts.map +1 -1
  73. package/_types/errors/version.d.ts +1 -1
  74. package/_types/index.d.ts +1 -0
  75. package/_types/index.d.ts.map +1 -1
  76. package/_types/tempo/Decorator.d.ts +18 -0
  77. package/_types/tempo/Decorator.d.ts.map +1 -1
  78. package/_types/tempo/actions/earn/deployment.d.ts +1710 -0
  79. package/_types/tempo/actions/earn/deployment.d.ts.map +1 -0
  80. package/_types/tempo/actions/earn.d.ts +1 -1
  81. package/_types/tempo/actions/earn.d.ts.map +1 -1
  82. package/_types/tempo/actions/zone.d.ts +21 -5
  83. package/_types/tempo/actions/zone.d.ts.map +1 -1
  84. package/_types/tempo/chainConfig.d.ts.map +1 -1
  85. package/_types/tempo/internal/WithdrawalSenderTag.d.ts +2 -1
  86. package/_types/tempo/internal/WithdrawalSenderTag.d.ts.map +1 -1
  87. package/_types/tempo/zones/Abis.d.ts +48 -0
  88. package/_types/tempo/zones/Abis.d.ts.map +1 -1
  89. package/actions/index.ts +9 -0
  90. package/actions/public/watchBlockHeaders.ts +131 -0
  91. package/actions/wallet/prepareTransactionRequest.ts +18 -17
  92. package/actions/wallet/sendTransaction.ts +25 -10
  93. package/actions/wallet/sendTransactionSync.ts +25 -10
  94. package/clients/createClient.ts +4 -3
  95. package/clients/decorators/public.ts +33 -0
  96. package/errors/version.ts +1 -1
  97. package/index.ts +8 -0
  98. package/package.json +1 -1
  99. package/tempo/Decorator.ts +41 -0
  100. package/tempo/actions/earn/deployment.ts +1427 -0
  101. package/tempo/actions/earn.ts +5 -0
  102. package/tempo/actions/zone.ts +66 -6
  103. package/tempo/chainConfig.ts +30 -27
  104. package/tempo/internal/WithdrawalSenderTag.ts +5 -4
  105. package/tempo/zones/Abis.ts +17 -0
@@ -67,6 +67,9 @@ import * as policyActions from './policy.js'
67
67
  import * as tokenActions from './token.js'
68
68
  import * as zoneActions from './zone.js'
69
69
 
70
+ // biome-ignore lint/performance/noBarrelFile: namespace module
71
+ export * from './earn/deployment.js'
72
+
70
73
  /** TIP-403 policy ID that allows every sender, recipient, and mint recipient. */
71
74
  export const alwaysAllowPolicyId = 1n
72
75
 
@@ -1048,6 +1051,7 @@ export namespace privateDeposit {
1048
1051
  memo: returnMemo,
1049
1052
  portalAddress: config.zonePortal,
1050
1053
  recipient,
1054
+ sender: gateway,
1051
1055
  zoneId: config.zoneId,
1052
1056
  })
1053
1057
  const shareAmountMin = resolveMinimumShareAmount(parameters)
@@ -2426,6 +2430,7 @@ export namespace privateRedeem {
2426
2430
  memo: returnMemo,
2427
2431
  portalAddress: config.zonePortal,
2428
2432
  recipient,
2433
+ sender: gateway,
2429
2434
  zoneId: config.zoneId,
2430
2435
  }),
2431
2436
  (async () => {
@@ -28,7 +28,13 @@ import type { Transport } from '../../clients/transports/createTransport.js'
28
28
  import { zeroHash } from '../../constants/bytes.js'
29
29
  import type { BaseErrorType } from '../../errors/base.js'
30
30
  import type { Chain, GetChainParameter } from '../../types/chain.js'
31
- import type { Compute, UnionOmit } from '../../types/utils.js'
31
+ import type {
32
+ Compute,
33
+ IsUndefined,
34
+ MaybeRequired,
35
+ UnionOmit,
36
+ } from '../../types/utils.js'
37
+ import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
32
38
  import type { RequestErrorType } from '../../utils/buildRequest.js'
33
39
  import { type ObserveErrorType, observe } from '../../utils/observe.js'
34
40
  import { type PollErrorType, poll } from '../../utils/poll.js'
@@ -80,6 +86,8 @@ export type PreparedEncryptedDeposit = {
80
86
  keyIndex: bigint
81
87
  /** Zone portal address on the parent chain. */
82
88
  portalAddress: Address
89
+ /** Address that will call the Zone portal. */
90
+ sender: Address
83
91
  /** Token address or ID to deposit. */
84
92
  token: TokenId.TokenIdOrAddress
85
93
  /** Zone ID (e.g. `7`). */
@@ -95,6 +103,8 @@ export type PreparedEncryptedDepositRecipient = {
95
103
  keyIndex: bigint
96
104
  /** Zone portal address on the parent chain. */
97
105
  portalAddress: Address
106
+ /** Address that will call the Zone portal. */
107
+ sender: Address
98
108
  /** Zone ID (e.g. `7`). */
99
109
  zoneId: number
100
110
  }
@@ -493,6 +503,7 @@ export async function encryptedDeposit<
493
503
  memo: parameters.memo,
494
504
  portalAddress: parameters.portalAddress,
495
505
  recipient,
506
+ sender: account_.address,
496
507
  token: parameters.token,
497
508
  zoneId: parameters.zoneId,
498
509
  })
@@ -572,6 +583,7 @@ export namespace encryptedDeposit {
572
583
  * amount: 1_000_000n,
573
584
  * bouncebackRecipient: '0x...',
574
585
  * recipient: '0x...',
586
+ * sender: '0x...',
575
587
  * zoneId: 7,
576
588
  * })
577
589
  * ```
@@ -585,7 +597,7 @@ export namespace encryptedDeposit {
585
597
  account extends Account | undefined,
586
598
  >(
587
599
  client: Client<Transport, chain, account>,
588
- parameters: prepare.Parameters,
600
+ parameters: prepare.Parameters<account>,
589
601
  ): Promise<prepare.ReturnValue> {
590
602
  const chainId = client.chain?.id
591
603
  if (!chainId) throw new Error('`chain` is required.')
@@ -596,10 +608,13 @@ export namespace encryptedDeposit {
596
608
  memo,
597
609
  portalAddress: portalAddress_,
598
610
  recipient,
611
+ sender: sender_ = client.account?.address,
599
612
  token,
600
613
  zoneId,
601
614
  ...rest
602
615
  } = parameters
616
+ if (!sender_) throw new Error('`sender` is required.')
617
+ const sender = sender_
603
618
  const portalAddress = portalAddress_ ?? getPortalAddress(chainId, zoneId)
604
619
 
605
620
  const { keyIndex, publicKey } = await getEncryptionKey(client, {
@@ -611,6 +626,7 @@ export namespace encryptedDeposit {
611
626
  const encrypted = await encryptDepositPayload(
612
627
  publicKey,
613
628
  recipient,
629
+ sender,
614
630
  portalAddress,
615
631
  keyIndex,
616
632
  memo,
@@ -623,13 +639,24 @@ export namespace encryptedDeposit {
623
639
  encrypted,
624
640
  keyIndex,
625
641
  portalAddress,
642
+ sender,
626
643
  token,
627
644
  zoneId,
628
645
  }
629
646
  }
630
647
 
631
648
  export namespace prepare {
632
- export type Parameters = ReadParameters & Args
649
+ export type Parameters<
650
+ account extends Account | undefined = Account | undefined,
651
+ > = ReadParameters &
652
+ Omit<Args, 'sender'> &
653
+ MaybeRequired<
654
+ {
655
+ /** Address that will call the Zone portal. @default `client.account.address` */
656
+ sender?: Address | undefined
657
+ },
658
+ IsUndefined<account>
659
+ >
633
660
 
634
661
  export type Args = {
635
662
  /** Amount of tokens to deposit. */
@@ -642,6 +669,8 @@ export namespace encryptedDeposit {
642
669
  portalAddress?: Address | undefined
643
670
  /** Recipient address in the zone. */
644
671
  recipient: Address
672
+ /** Address that will call the Zone portal. */
673
+ sender: Address
645
674
  /** Token address or ID to deposit. */
646
675
  token: TokenId.TokenIdOrAddress
647
676
  /** Zone ID (e.g. `7`). */
@@ -673,6 +702,7 @@ export namespace encryptedDeposit {
673
702
  *
674
703
  * const recipient = await Actions.zone.encryptedDeposit.prepareRecipient(client, {
675
704
  * recipient: '0x...',
705
+ * sender: '0x...',
676
706
  * zoneId: 7,
677
707
  * })
678
708
  * ```
@@ -686,7 +716,7 @@ export namespace encryptedDeposit {
686
716
  account extends Account | undefined,
687
717
  >(
688
718
  client: Client<Transport, chain, account>,
689
- parameters: prepareRecipient.Parameters,
719
+ parameters: prepareRecipient.Parameters<account>,
690
720
  ): Promise<prepareRecipient.ReturnValue> {
691
721
  const chainId = client.chain?.id
692
722
  if (!chainId) throw new Error('`chain` is required.')
@@ -695,9 +725,12 @@ export namespace encryptedDeposit {
695
725
  memo,
696
726
  portalAddress: portalAddress_,
697
727
  recipient,
728
+ sender: sender_ = client.account?.address,
698
729
  zoneId,
699
730
  ...rest
700
731
  } = parameters
732
+ if (!sender_) throw new Error('`sender` is required.')
733
+ const sender = sender_
701
734
  const portalAddress = portalAddress_ ?? getPortalAddress(chainId, zoneId)
702
735
  const { keyIndex, publicKey } = await getEncryptionKey(client, {
703
736
  ...rest,
@@ -707,6 +740,7 @@ export namespace encryptedDeposit {
707
740
  const encrypted = await encryptDepositPayload(
708
741
  publicKey,
709
742
  recipient,
743
+ sender,
710
744
  portalAddress,
711
745
  keyIndex,
712
746
  memo,
@@ -717,12 +751,23 @@ export namespace encryptedDeposit {
717
751
  encrypted,
718
752
  keyIndex,
719
753
  portalAddress,
754
+ sender,
720
755
  zoneId,
721
756
  }
722
757
  }
723
758
 
724
759
  export namespace prepareRecipient {
725
- export type Parameters = ReadParameters & Args
760
+ export type Parameters<
761
+ account extends Account | undefined = Account | undefined,
762
+ > = ReadParameters &
763
+ Omit<Args, 'sender'> &
764
+ MaybeRequired<
765
+ {
766
+ /** Address that will call the Zone portal. @default `client.account.address` */
767
+ sender?: Address | undefined
768
+ },
769
+ IsUndefined<account>
770
+ >
726
771
 
727
772
  export type Args = {
728
773
  /** Optional deposit memo. @default `0x00...00` */
@@ -731,6 +776,8 @@ export namespace encryptedDeposit {
731
776
  portalAddress?: Address | undefined
732
777
  /** Recipient address in the zone. */
733
778
  recipient: Address
779
+ /** Address that will call the Zone portal. */
780
+ sender: Address
734
781
  /** Zone ID (e.g. `7`). */
735
782
  zoneId: number
736
783
  }
@@ -863,6 +910,7 @@ export async function encryptedDepositSync<
863
910
  memo: parameters.memo,
864
911
  portalAddress: parameters.portalAddress,
865
912
  recipient,
913
+ sender: account_.address,
866
914
  token: parameters.token,
867
915
  zoneId: parameters.zoneId,
868
916
  })
@@ -1547,8 +1595,16 @@ export async function requestWithdrawalSync<
1547
1595
  gas: parameters.gas ?? defaultWithdrawalGas,
1548
1596
  throwOnReceiptRevert,
1549
1597
  } as never)
1598
+ const [event] = parseEventLogs({
1599
+ abi: ZoneAbis.zoneOutbox,
1600
+ logs: receipt.logs,
1601
+ eventName: 'WithdrawalRequested',
1602
+ strict: true,
1603
+ })
1604
+ if (!event) throw new Error('`WithdrawalRequested` event not found.')
1550
1605
  const senderTag = WithdrawalSenderTag.from({
1551
- sender: account_.address,
1606
+ fallbackNonce: event.args.fallbackNonce,
1607
+ sender: event.args.sender,
1552
1608
  transactionHash: receipt.transactionHash,
1553
1609
  })
1554
1610
  return { receipt, senderTag }
@@ -1874,6 +1930,7 @@ export namespace signAuthorizationToken {
1874
1930
  async function encryptDepositPayload(
1875
1931
  publicKey: { prefix: 2 | 3; x: Hex.Hex },
1876
1932
  recipient: Address,
1933
+ sender: Address,
1877
1934
  portalAddress: Address,
1878
1935
  keyIndex: bigint,
1879
1936
  memo: Hex.Hex = zeroHash,
@@ -1909,6 +1966,7 @@ async function encryptDepositPayload(
1909
1966
  portalAddress,
1910
1967
  keyIndex,
1911
1968
  Hex.fromNumber(compressedEphemeral.x, { size: 32 }),
1969
+ sender,
1912
1970
  ) as BufferSource,
1913
1971
  },
1914
1972
  hkdfKey,
@@ -1952,11 +2010,13 @@ function buildDepositHkdfInfo(
1952
2010
  portalAddress: Address,
1953
2011
  keyIndex: bigint,
1954
2012
  ephemeralPubkeyX: Hex.Hex,
2013
+ sender: Address,
1955
2014
  ): Bytes.Bytes {
1956
2015
  return Bytes.concat(
1957
2016
  Bytes.from(portalAddress),
1958
2017
  Bytes.fromNumber(keyIndex, { size: 32 }),
1959
2018
  Bytes.from(ephemeralPubkeyX),
2019
+ Bytes.from(sender),
1960
2020
  )
1961
2021
  }
1962
2022
 
@@ -116,6 +116,36 @@ export const chainConfig = {
116
116
  if (request.account?.source !== 'multisig') delete request.account
117
117
  }
118
118
 
119
+ // Register concurrency before account preparation performs storage or
120
+ // network I/O so overlapping requests cannot miss each other.
121
+ const useExpiringNonce = await (async () => {
122
+ if (request.nonceKey === 'expiring' || request.nonceKey === maxUint256)
123
+ return true
124
+ if (multisig) return false
125
+ if (request.feePayer && typeof request.nonceKey === 'undefined')
126
+ return true
127
+ const account = request.account as
128
+ | Account
129
+ | MultisigAccount
130
+ | Address
131
+ | undefined
132
+ const address = typeof account === 'string' ? account : account?.address
133
+ if (address && typeof request.nonceKey === 'undefined')
134
+ return await Concurrent.detect(address.toLowerCase())
135
+ return false
136
+ })()
137
+
138
+ if (useExpiringNonce) {
139
+ request.nonceKey = maxUint256
140
+ request.nonce = 0
141
+ if (typeof request.validAfter === 'undefined')
142
+ request.validAfter = randomValidAfter()
143
+ if (typeof request.validBefore === 'undefined')
144
+ request.validBefore = Math.floor(Date.now() / 1000) + maxExpirySecs
145
+ } else if (typeof request.nonceKey !== 'undefined') {
146
+ request.nonce = typeof request.nonce === 'number' ? request.nonce : 0
147
+ }
148
+
119
149
  if (
120
150
  !request.keyAuthorization &&
121
151
  request.account?.source === 'accessKey'
@@ -156,33 +186,6 @@ export const chainConfig = {
156
186
  }
157
187
  }
158
188
 
159
- // Use expiring nonces for concurrent transactions (TIP-1009).
160
- // When nonceKey is 'expiring', feePayer is specified, or concurrent requests
161
- // are detected, we use expiring nonces (nonceKey = uint256.max) with a
162
- // validBefore timestamp.
163
- const useExpiringNonce = await (async () => {
164
- if (request.nonceKey === 'expiring') return true
165
- if (multisig) return false
166
- if (request.feePayer && typeof request.nonceKey === 'undefined')
167
- return true
168
- const address = request.account?.address
169
- if (address && typeof request.nonceKey === 'undefined')
170
- return await Concurrent.detect(address)
171
- return false
172
- })()
173
-
174
- if (useExpiringNonce) {
175
- request.nonceKey = maxUint256
176
- request.nonce = 0
177
- if (typeof request.validAfter === 'undefined')
178
- request.validAfter = randomValidAfter()
179
- if (typeof request.validBefore === 'undefined')
180
- request.validBefore = Math.floor(Date.now() / 1000) + maxExpirySecs
181
- } else if (typeof request.nonceKey !== 'undefined') {
182
- // Explicit nonceKey provided (2D nonce mode)
183
- request.nonce = typeof request.nonce === 'number' ? request.nonce : 0
184
- }
185
-
186
189
  if (!request.feeToken && request.chain?.feeToken)
187
190
  request.feeToken = request.chain.feeToken
188
191
 
@@ -1,19 +1,20 @@
1
1
  import type { Address } from 'abitype'
2
2
  import { AbiParameters, Hash, type Hex } from 'ox'
3
3
 
4
- /** Derives a withdrawal sender tag from its sender and transaction hash. @internal */
4
+ /** Derives a user withdrawal sender tag. @internal */
5
5
  export function from(options: from.Options): Hex.Hex {
6
- const { sender, transactionHash } = options
6
+ const { fallbackNonce, sender, transactionHash } = options
7
7
  return Hash.keccak256(
8
8
  AbiParameters.encodePacked(
9
- ['address', 'bytes32'],
10
- [sender, transactionHash],
9
+ ['address', 'bytes32', 'uint64'],
10
+ [sender, transactionHash, fallbackNonce],
11
11
  ),
12
12
  )
13
13
  }
14
14
 
15
15
  export declare namespace from {
16
16
  type Options = {
17
+ fallbackNonce: bigint
17
18
  sender: Address
18
19
  transactionHash: Hex.Hex
19
20
  }
@@ -168,6 +168,23 @@ export const zonePortal = [
168
168
  ] as const
169
169
 
170
170
  export const zoneOutbox = [
171
+ {
172
+ name: 'WithdrawalRequested',
173
+ type: 'event',
174
+ inputs: [
175
+ { name: 'withdrawalIndex', type: 'uint64', indexed: true },
176
+ { name: 'sender', type: 'address', indexed: true },
177
+ { name: 'token', type: 'address', indexed: false },
178
+ { name: 'to', type: 'address', indexed: false },
179
+ { name: 'amount', type: 'uint128', indexed: false },
180
+ { name: 'fee', type: 'uint128', indexed: false },
181
+ { name: 'memo', type: 'bytes32', indexed: false },
182
+ { name: 'gasLimit', type: 'uint64', indexed: false },
183
+ { name: 'fallbackNonce', type: 'uint64', indexed: false },
184
+ { name: 'data', type: 'bytes', indexed: false },
185
+ { name: 'revealTo', type: 'bytes', indexed: false },
186
+ ],
187
+ },
171
188
  {
172
189
  name: 'requestWithdrawal',
173
190
  type: 'function',