viem 2.49.3 → 2.50.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/_cjs/actions/ens/getEnsAddress.js +21 -6
  3. package/_cjs/actions/ens/getEnsAddress.js.map +1 -1
  4. package/_cjs/actions/public/call.js +76 -41
  5. package/_cjs/actions/public/call.js.map +1 -1
  6. package/_cjs/actions/public/getBalance.js +11 -4
  7. package/_cjs/actions/public/getBalance.js.map +1 -1
  8. package/_cjs/actions/public/getCode.js +12 -5
  9. package/_cjs/actions/public/getCode.js.map +1 -1
  10. package/_cjs/actions/public/getProof.js +9 -5
  11. package/_cjs/actions/public/getProof.js.map +1 -1
  12. package/_cjs/actions/public/getStorageAt.js +9 -4
  13. package/_cjs/actions/public/getStorageAt.js.map +1 -1
  14. package/_cjs/actions/public/getTransactionCount.js +10 -7
  15. package/_cjs/actions/public/getTransactionCount.js.map +1 -1
  16. package/_cjs/actions/public/multicall.js +3 -1
  17. package/_cjs/actions/public/multicall.js.map +1 -1
  18. package/_cjs/actions/public/readContract.js.map +1 -1
  19. package/_cjs/actions/wallet/prepareTransactionRequest.js.map +1 -1
  20. package/_cjs/actions/wallet/sendTransaction.js +14 -0
  21. package/_cjs/actions/wallet/sendTransaction.js.map +1 -1
  22. package/_cjs/actions/wallet/sendTransactionSync.js +15 -0
  23. package/_cjs/actions/wallet/sendTransactionSync.js.map +1 -1
  24. package/_cjs/chains/definitions/mizuhikiTestnetAwaji.js +29 -0
  25. package/_cjs/chains/definitions/mizuhikiTestnetAwaji.js.map +1 -0
  26. package/_cjs/chains/definitions/morphHolesky.js +1 -1
  27. package/_cjs/chains/definitions/morphHolesky.js.map +1 -1
  28. package/_cjs/chains/definitions/sentrix.js +29 -0
  29. package/_cjs/chains/definitions/sentrix.js.map +1 -0
  30. package/_cjs/chains/definitions/sentrixTestnet.js +30 -0
  31. package/_cjs/chains/definitions/sentrixTestnet.js.map +1 -0
  32. package/_cjs/chains/definitions/sova.js +1 -1
  33. package/_cjs/chains/definitions/sova.js.map +1 -1
  34. package/_cjs/chains/index.js +13 -7
  35. package/_cjs/chains/index.js.map +1 -1
  36. package/_cjs/constants/solidity.js.map +1 -1
  37. package/_cjs/errors/version.js +1 -1
  38. package/_cjs/index.js +5 -3
  39. package/_cjs/index.js.map +1 -1
  40. package/_cjs/tempo/Chain.js +19 -0
  41. package/_cjs/tempo/Chain.js.map +1 -0
  42. package/_cjs/tempo/Decorator.js +1 -0
  43. package/_cjs/tempo/Decorator.js.map +1 -1
  44. package/_cjs/tempo/actions/fee.js +61 -0
  45. package/_cjs/tempo/actions/fee.js.map +1 -1
  46. package/_cjs/tempo/chainConfig.js +16 -6
  47. package/_cjs/tempo/chainConfig.js.map +1 -1
  48. package/_cjs/tempo/chains/index.js +11 -0
  49. package/_cjs/tempo/chains/index.js.map +1 -0
  50. package/_cjs/tempo/errors.js +58 -0
  51. package/_cjs/tempo/errors.js.map +1 -0
  52. package/_cjs/tempo/index.js +17 -1
  53. package/_cjs/tempo/index.js.map +1 -1
  54. package/_cjs/utils/abi/encodeEventTopics.js +4 -2
  55. package/_cjs/utils/abi/encodeEventTopics.js.map +1 -1
  56. package/_cjs/utils/block/formatBlockParameter.js +16 -0
  57. package/_cjs/utils/block/formatBlockParameter.js.map +1 -0
  58. package/_cjs/utils/ccipTunnel.js +65 -0
  59. package/_cjs/utils/ccipTunnel.js.map +1 -0
  60. package/_cjs/utils/index.js +6 -4
  61. package/_cjs/utils/index.js.map +1 -1
  62. package/_cjs/utils/nonceManager.js +7 -3
  63. package/_cjs/utils/nonceManager.js.map +1 -1
  64. package/_cjs/utils/observe.js +7 -1
  65. package/_cjs/utils/observe.js.map +1 -1
  66. package/_cjs/utils/rpc/socket.js +19 -2
  67. package/_cjs/utils/rpc/socket.js.map +1 -1
  68. package/_esm/actions/ens/getEnsAddress.js +21 -6
  69. package/_esm/actions/ens/getEnsAddress.js.map +1 -1
  70. package/_esm/actions/public/call.js +76 -41
  71. package/_esm/actions/public/call.js.map +1 -1
  72. package/_esm/actions/public/getBalance.js +11 -4
  73. package/_esm/actions/public/getBalance.js.map +1 -1
  74. package/_esm/actions/public/getCode.js +12 -5
  75. package/_esm/actions/public/getCode.js.map +1 -1
  76. package/_esm/actions/public/getProof.js +9 -5
  77. package/_esm/actions/public/getProof.js.map +1 -1
  78. package/_esm/actions/public/getStorageAt.js +9 -4
  79. package/_esm/actions/public/getStorageAt.js.map +1 -1
  80. package/_esm/actions/public/getTransactionCount.js +10 -7
  81. package/_esm/actions/public/getTransactionCount.js.map +1 -1
  82. package/_esm/actions/public/multicall.js +3 -1
  83. package/_esm/actions/public/multicall.js.map +1 -1
  84. package/_esm/actions/public/readContract.js.map +1 -1
  85. package/_esm/actions/wallet/prepareTransactionRequest.js.map +1 -1
  86. package/_esm/actions/wallet/sendTransaction.js +14 -0
  87. package/_esm/actions/wallet/sendTransaction.js.map +1 -1
  88. package/_esm/actions/wallet/sendTransactionSync.js +15 -0
  89. package/_esm/actions/wallet/sendTransactionSync.js.map +1 -1
  90. package/_esm/chains/definitions/mizuhikiTestnetAwaji.js +26 -0
  91. package/_esm/chains/definitions/mizuhikiTestnetAwaji.js.map +1 -0
  92. package/_esm/chains/definitions/morphHolesky.js +1 -1
  93. package/_esm/chains/definitions/morphHolesky.js.map +1 -1
  94. package/_esm/chains/definitions/sentrix.js +26 -0
  95. package/_esm/chains/definitions/sentrix.js.map +1 -0
  96. package/_esm/chains/definitions/sentrixTestnet.js +27 -0
  97. package/_esm/chains/definitions/sentrixTestnet.js.map +1 -0
  98. package/_esm/chains/definitions/sova.js +1 -1
  99. package/_esm/chains/definitions/sova.js.map +1 -1
  100. package/_esm/chains/index.js +3 -0
  101. package/_esm/chains/index.js.map +1 -1
  102. package/_esm/constants/solidity.js.map +1 -1
  103. package/_esm/errors/version.js +1 -1
  104. package/_esm/index.js +1 -0
  105. package/_esm/index.js.map +1 -1
  106. package/_esm/tempo/Chain.js +6 -0
  107. package/_esm/tempo/Chain.js.map +1 -0
  108. package/_esm/tempo/Decorator.js +1 -0
  109. package/_esm/tempo/Decorator.js.map +1 -1
  110. package/_esm/tempo/actions/fee.js +83 -0
  111. package/_esm/tempo/actions/fee.js.map +1 -1
  112. package/_esm/tempo/actions/wallet.js +2 -2
  113. package/_esm/tempo/chainConfig.js +18 -8
  114. package/_esm/tempo/chainConfig.js.map +1 -1
  115. package/_esm/tempo/chains/index.js +3 -0
  116. package/_esm/tempo/chains/index.js.map +1 -0
  117. package/_esm/tempo/errors.js +51 -0
  118. package/_esm/tempo/errors.js.map +1 -0
  119. package/_esm/tempo/index.js +2 -0
  120. package/_esm/tempo/index.js.map +1 -1
  121. package/_esm/utils/abi/encodeEventTopics.js +6 -2
  122. package/_esm/utils/abi/encodeEventTopics.js.map +1 -1
  123. package/_esm/utils/block/formatBlockParameter.js +39 -0
  124. package/_esm/utils/block/formatBlockParameter.js.map +1 -0
  125. package/_esm/utils/ccipTunnel.js +62 -0
  126. package/_esm/utils/ccipTunnel.js.map +1 -0
  127. package/_esm/utils/index.js +1 -0
  128. package/_esm/utils/index.js.map +1 -1
  129. package/_esm/utils/nonceManager.js +7 -3
  130. package/_esm/utils/nonceManager.js.map +1 -1
  131. package/_esm/utils/observe.js +7 -1
  132. package/_esm/utils/observe.js.map +1 -1
  133. package/_esm/utils/rpc/socket.js +20 -2
  134. package/_esm/utils/rpc/socket.js.map +1 -1
  135. package/_types/actions/ens/getEnsAddress.d.ts +3 -1
  136. package/_types/actions/ens/getEnsAddress.d.ts.map +1 -1
  137. package/_types/actions/public/call.d.ts +17 -6
  138. package/_types/actions/public/call.d.ts.map +1 -1
  139. package/_types/actions/public/getBalance.d.ts +15 -3
  140. package/_types/actions/public/getBalance.d.ts.map +1 -1
  141. package/_types/actions/public/getCode.d.ts +15 -4
  142. package/_types/actions/public/getCode.d.ts.map +1 -1
  143. package/_types/actions/public/getProof.d.ts +14 -3
  144. package/_types/actions/public/getProof.d.ts.map +1 -1
  145. package/_types/actions/public/getStorageAt.d.ts +15 -4
  146. package/_types/actions/public/getStorageAt.d.ts.map +1 -1
  147. package/_types/actions/public/getTransactionCount.d.ts +15 -3
  148. package/_types/actions/public/getTransactionCount.d.ts.map +1 -1
  149. package/_types/actions/public/multicall.d.ts +1 -1
  150. package/_types/actions/public/multicall.d.ts.map +1 -1
  151. package/_types/actions/public/readContract.d.ts +1 -1
  152. package/_types/actions/public/readContract.d.ts.map +1 -1
  153. package/_types/actions/wallet/prepareTransactionRequest.d.ts +4 -2
  154. package/_types/actions/wallet/prepareTransactionRequest.d.ts.map +1 -1
  155. package/_types/actions/wallet/sendTransaction.d.ts.map +1 -1
  156. package/_types/actions/wallet/sendTransactionSync.d.ts.map +1 -1
  157. package/_types/chains/definitions/mizuhikiTestnetAwaji.d.ts +46 -0
  158. package/_types/chains/definitions/mizuhikiTestnetAwaji.d.ts.map +1 -0
  159. package/_types/chains/definitions/morphHolesky.d.ts +1 -1
  160. package/_types/chains/definitions/sentrix.d.ts +46 -0
  161. package/_types/chains/definitions/sentrix.d.ts.map +1 -0
  162. package/_types/chains/definitions/sentrixTestnet.d.ts +46 -0
  163. package/_types/chains/definitions/sentrixTestnet.d.ts.map +1 -0
  164. package/_types/chains/definitions/sova.d.ts +1 -1
  165. package/_types/chains/index.d.ts +3 -0
  166. package/_types/chains/index.d.ts.map +1 -1
  167. package/_types/constants/solidity.d.ts +16 -3
  168. package/_types/constants/solidity.d.ts.map +1 -1
  169. package/_types/errors/version.d.ts +1 -1
  170. package/_types/index.d.ts +1 -0
  171. package/_types/index.d.ts.map +1 -1
  172. package/_types/tempo/Chain.d.ts +5 -0
  173. package/_types/tempo/Chain.d.ts.map +1 -0
  174. package/_types/tempo/Decorator.d.ts +23 -0
  175. package/_types/tempo/Decorator.d.ts.map +1 -1
  176. package/_types/tempo/actions/fee.d.ts +38 -0
  177. package/_types/tempo/actions/fee.d.ts.map +1 -1
  178. package/_types/tempo/actions/wallet.d.ts +9 -6
  179. package/_types/tempo/actions/wallet.d.ts.map +1 -1
  180. package/_types/tempo/chainConfig.d.ts.map +1 -1
  181. package/_types/tempo/chains/index.d.ts +2 -0
  182. package/_types/tempo/chains/index.d.ts.map +1 -0
  183. package/_types/tempo/errors.d.ts +36 -0
  184. package/_types/tempo/errors.d.ts.map +1 -0
  185. package/_types/tempo/index.d.ts +2 -0
  186. package/_types/tempo/index.d.ts.map +1 -1
  187. package/_types/types/block.d.ts +3 -4
  188. package/_types/types/block.d.ts.map +1 -1
  189. package/_types/types/eip1193.d.ts +1 -1
  190. package/_types/types/eip1193.d.ts.map +1 -1
  191. package/_types/utils/abi/encodeEventTopics.d.ts +6 -2
  192. package/_types/utils/abi/encodeEventTopics.d.ts.map +1 -1
  193. package/_types/utils/block/formatBlockParameter.d.ts +45 -0
  194. package/_types/utils/block/formatBlockParameter.d.ts.map +1 -0
  195. package/_types/utils/ccipTunnel.d.ts +9 -0
  196. package/_types/utils/ccipTunnel.d.ts.map +1 -0
  197. package/_types/utils/index.d.ts +1 -0
  198. package/_types/utils/index.d.ts.map +1 -1
  199. package/_types/utils/nonceManager.d.ts.map +1 -1
  200. package/_types/utils/observe.d.ts.map +1 -1
  201. package/_types/utils/rpc/socket.d.ts.map +1 -1
  202. package/actions/ens/getEnsAddress.ts +34 -6
  203. package/actions/public/call.ts +125 -51
  204. package/actions/public/getBalance.ts +30 -9
  205. package/actions/public/getCode.ts +35 -11
  206. package/actions/public/getProof.ts +27 -11
  207. package/actions/public/getStorageAt.ts +33 -10
  208. package/actions/public/getTransactionCount.ts +33 -11
  209. package/actions/public/multicall.ts +6 -0
  210. package/actions/public/readContract.ts +2 -0
  211. package/actions/wallet/prepareTransactionRequest.ts +11 -15
  212. package/actions/wallet/sendTransaction.ts +13 -0
  213. package/actions/wallet/sendTransactionSync.ts +16 -0
  214. package/chains/definitions/mizuhikiTestnetAwaji.ts +26 -0
  215. package/chains/definitions/morphHolesky.ts +1 -1
  216. package/chains/definitions/sentrix.ts +26 -0
  217. package/chains/definitions/sentrixTestnet.ts +27 -0
  218. package/chains/definitions/sova.ts +1 -1
  219. package/chains/index.ts +3 -0
  220. package/constants/solidity.ts +4 -4
  221. package/errors/version.ts +1 -1
  222. package/index.ts +4 -0
  223. package/package.json +11 -3
  224. package/tempo/Chain.ts +20 -0
  225. package/tempo/Decorator.ts +27 -0
  226. package/tempo/actions/fee.ts +117 -1
  227. package/tempo/actions/wallet.ts +9 -6
  228. package/tempo/chainConfig.ts +18 -12
  229. package/tempo/chains/index.ts +9 -0
  230. package/tempo/chains/package.json +6 -0
  231. package/tempo/errors.ts +78 -0
  232. package/tempo/index.ts +2 -0
  233. package/types/block.ts +3 -5
  234. package/types/eip1193.ts +1 -1
  235. package/utils/abi/encodeEventTopics.ts +25 -6
  236. package/utils/block/formatBlockParameter.ts +63 -0
  237. package/utils/ccipTunnel.ts +67 -0
  238. package/utils/index.ts +4 -0
  239. package/utils/nonceManager.ts +7 -3
  240. package/utils/observe.ts +7 -4
  241. package/utils/rpc/socket.ts +21 -2
@@ -213,8 +213,8 @@ export declare namespace swap {
213
213
  * })
214
214
  *
215
215
  * const result = await Actions.wallet.deposit(client, {
216
- * token: '0x...',
217
- * value: '1.5',
216
+ * amount: '1.5',
217
+ * token: 'pathUsd',
218
218
  * })
219
219
  * ```
220
220
  *
@@ -243,14 +243,17 @@ export declare namespace deposit {
243
243
  export type Parameters = {
244
244
  /** Deposit address to pre-fill. */
245
245
  address?: Address | undefined
246
+ /** Human-readable amount to pre-fill (for example, "1.5"). */
247
+ amount?: string | undefined
246
248
  /** Source chain ID to pre-fill. */
247
249
  chainId?: number | undefined
248
250
  /** Human-readable account display name. */
249
251
  displayName?: string | undefined
250
- /** Token contract address to pre-fill. Omit to let the user choose. */
251
- token?: Address | undefined
252
- /** Human-readable amount to pre-fill (for example, "1.5"). */
253
- value?: string | undefined
252
+ /**
253
+ * Token to pre-fill, accepted as either a contract address or a supported
254
+ * deposit token symbol. Omit to let the user choose.
255
+ */
256
+ token?: Address | string | undefined
254
257
  }
255
258
 
256
259
  export type ReturnValue =
@@ -1,6 +1,4 @@
1
- import * as Address from 'ox/Address'
2
1
  import * as Hex from 'ox/Hex'
3
- import * as PublicKey from 'ox/PublicKey'
4
2
  import { SignatureEnvelope, type TokenId } from 'ox/tempo'
5
3
  import { getCode } from '../actions/public/getCode.js'
6
4
  import { verifyHash } from '../actions/public/verifyHash.js'
@@ -115,9 +113,24 @@ export const chainConfig = {
115
113
  // Access key (keychain) signature verification: check the key is
116
114
  // authorized, not expired, and not revoked on the AccountKeychain.
117
115
  if (envelope?.type === 'keychain' && mode === 'allowAccessKey') {
118
- const accessKeyAddress = Address.fromPublicKey(
119
- PublicKey.from(envelope.inner.publicKey as PublicKey.PublicKey),
120
- )
116
+ // For v2 keychain envelopes, the inner signature signs
117
+ // keccak256(0x04 || hash || userAddress).
118
+ const innerPayload =
119
+ envelope.version === 'v2'
120
+ ? keccak256(Hex.concat('0x04', hash, address))
121
+ : hash
122
+
123
+ const accessKeyAddress = (() => {
124
+ try {
125
+ return SignatureEnvelope.extractAddress({
126
+ payload: innerPayload,
127
+ signature: envelope.inner,
128
+ })
129
+ } catch {
130
+ return undefined
131
+ }
132
+ })()
133
+ if (!accessKeyAddress) return false
121
134
 
122
135
  const keyInfo = await getMetadata(client, {
123
136
  account: address,
@@ -129,13 +142,6 @@ export const chainConfig = {
129
142
  if (keyInfo.isRevoked) return false
130
143
  if (keyInfo.expiry <= BigInt(Math.floor(Date.now() / 1000)))
131
144
  return false
132
-
133
- // For v2 keychain envelopes, the inner signature signs
134
- // keccak256(0x04 || hash || userAddress).
135
- const innerPayload =
136
- envelope.version === 'v2'
137
- ? keccak256(Hex.concat('0x04', hash, address))
138
- : hash
139
145
  return SignatureEnvelope.verify(envelope.inner, {
140
146
  address: accessKeyAddress,
141
147
  payload: innerPayload,
@@ -0,0 +1,9 @@
1
+ // biome-ignore lint/performance/noBarrelFile: entrypoint module
2
+ export {
3
+ tempo,
4
+ tempoDevnet,
5
+ tempoLocalnet,
6
+ tempoMainnet,
7
+ tempoModerato,
8
+ tempoTestnet,
9
+ } from '../Chain.js'
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "types": "../../_types/tempo/chains/index.d.ts",
4
+ "module": "../../_esm/tempo/chains/index.js",
5
+ "main": "../../_cjs/tempo/chains/index.js"
6
+ }
@@ -0,0 +1,78 @@
1
+ import { BaseError } from '../errors/base.js'
2
+
3
+ export type InvalidFeeTokenErrorType = InvalidFeeTokenError & {
4
+ name: 'InvalidFeeTokenError'
5
+ }
6
+ export class InvalidFeeTokenError extends BaseError {
7
+ constructor({
8
+ cause,
9
+ token,
10
+ }: {
11
+ cause?: BaseError | Error | undefined
12
+ token: string
13
+ }) {
14
+ super(`Fee token "${token}" is invalid.`, {
15
+ cause,
16
+ docsPath: '/tempo/transactions',
17
+ docsSlug: 'pay-fees-with-stablecoins',
18
+ metaMessages: [
19
+ 'Fee tokens must be unpaused USD-denominated TIP-20 tokens.',
20
+ 'Use `client.fee.validateToken({ token })` before sending transactions or setting fee preferences.',
21
+ ],
22
+ name: 'InvalidFeeTokenError',
23
+ })
24
+ }
25
+ }
26
+
27
+ export type FeeTokenNotTip20ErrorType = FeeTokenNotTip20Error & {
28
+ name: 'FeeTokenNotTip20Error'
29
+ }
30
+ export class FeeTokenNotTip20Error extends BaseError {
31
+ constructor({ token }: { token: string }) {
32
+ super(`Fee token "${token}" is not a TIP-20 token.`, {
33
+ docsPath: '/tempo/transactions',
34
+ docsSlug: 'pay-fees-with-stablecoins',
35
+ metaMessages: [
36
+ 'Fee tokens must be TIP-20 token addresses or token IDs.',
37
+ 'TIP-20 token addresses use the `0x20c0...` address prefix.',
38
+ ],
39
+ name: 'FeeTokenNotTip20Error',
40
+ })
41
+ }
42
+ }
43
+
44
+ export type FeeTokenNotUsdErrorType = FeeTokenNotUsdError & {
45
+ name: 'FeeTokenNotUsdError'
46
+ }
47
+ export class FeeTokenNotUsdError extends BaseError {
48
+ constructor({
49
+ currency,
50
+ token,
51
+ }: {
52
+ currency: string
53
+ token: string
54
+ }) {
55
+ super(`Fee token "${token}" is denominated in "${currency}", not "USD".`, {
56
+ docsPath: '/tempo/transactions',
57
+ docsSlug: 'pay-fees-with-stablecoins',
58
+ metaMessages: [
59
+ 'Only USD-denominated TIP-20 tokens can be used as fee tokens.',
60
+ ],
61
+ name: 'FeeTokenNotUsdError',
62
+ })
63
+ }
64
+ }
65
+
66
+ export type FeeTokenPausedErrorType = FeeTokenPausedError & {
67
+ name: 'FeeTokenPausedError'
68
+ }
69
+ export class FeeTokenPausedError extends BaseError {
70
+ constructor({ token }: { token: string }) {
71
+ super(`Fee token "${token}" is paused.`, {
72
+ docsPath: '/tempo/transactions',
73
+ docsSlug: 'pay-fees-with-stablecoins',
74
+ metaMessages: ['Paused TIP-20 tokens cannot be used as fee tokens.'],
75
+ name: 'FeeTokenPausedError',
76
+ })
77
+ }
78
+ }
package/tempo/index.ts CHANGED
@@ -24,11 +24,13 @@ export * as Account from './Account.js'
24
24
  export * as Addresses from './Addresses.js'
25
25
  export * as Actions from './actions/index.js'
26
26
  export * as Capabilities from './Capabilities.js'
27
+ export * as Chain from './Chain.js'
27
28
  export {
28
29
  type Decorator as TempoActions,
29
30
  decorator as tempoActions,
30
31
  } from './Decorator.js'
31
32
  export * as Expiry from './Expiry.js'
33
+ export * from './errors.js'
32
34
  export * as Formatters from './Formatters.js'
33
35
  export * as Hardfork from './Hardfork.js'
34
36
  export * as P256 from './P256.js'
package/types/block.ts CHANGED
@@ -69,10 +69,7 @@ export type Block<
69
69
  withdrawalsRoot?: Hex | undefined
70
70
  }
71
71
 
72
- export type BlockIdentifier<quantity = bigint> = {
73
- /** Whether or not to throw an error if the block is not in the canonical chain as described below. Only allowed in conjunction with the blockHash tag. Defaults to false. */
74
- requireCanonical?: boolean | undefined
75
- } & (
72
+ export type BlockIdentifier<quantity = bigint> =
76
73
  | {
77
74
  /** The block in the canonical chain with this number */
78
75
  blockNumber: BlockNumber<quantity>
@@ -80,8 +77,9 @@ export type BlockIdentifier<quantity = bigint> = {
80
77
  | {
81
78
  /** The block uniquely identified by this hash. The `blockNumber` and `blockHash` properties are mutually exclusive; exactly one of them must be set. */
82
79
  blockHash: Hash
80
+ /** Whether or not to throw an error if the block is not in the canonical chain as described below. Only allowed in conjunction with the blockHash tag. Defaults to false. */
81
+ requireCanonical?: boolean | undefined
83
82
  }
84
- )
85
83
 
86
84
  /** Represents a block number in the blockchain. */
87
85
  export type BlockNumber<quantity = bigint> = quantity
package/types/eip1193.ts CHANGED
@@ -974,7 +974,7 @@ export type PublicRpcSchema = [
974
974
  address: Address,
975
975
  /** An array of storage-keys that should be proofed and included. */
976
976
  storageKeys: Hash[],
977
- block: BlockNumber | BlockTag,
977
+ block: BlockNumber | BlockTag | BlockIdentifier,
978
978
  ]
979
979
  ReturnType: Proof
980
980
  },
@@ -66,7 +66,22 @@ export type EncodeEventTopicsParameters<
66
66
  > &
67
67
  (hasEvents extends true ? unknown : never)
68
68
 
69
- export type EncodeEventTopicsReturnType = [Hex, ...(Hex | Hex[] | null)[]]
69
+ export type EncodeEventTopicsReturnType<
70
+ abi extends Abi | readonly unknown[] = Abi,
71
+ eventName extends ContractEventName<abi> | undefined = undefined,
72
+ ///
73
+ resolvedEvent = abi extends Abi
74
+ ? eventName extends string
75
+ ? Extract<ExtractAbiEvents<abi>, { name: eventName }>
76
+ : abi['length'] extends 1
77
+ ? abi[0]
78
+ : ExtractAbiEvents<abi>
79
+ : unknown,
80
+ > = IsNarrowable<abi, Abi> extends true
81
+ ? [resolvedEvent] extends [{ anonymous: true }]
82
+ ? (Hex | Hex[] | null)[]
83
+ : [Hex, ...(Hex | Hex[] | null)[]]
84
+ : (Hex | Hex[] | null)[]
70
85
 
71
86
  export type EncodeEventTopicsErrorType =
72
87
  | AbiEventNotFoundErrorType
@@ -81,7 +96,7 @@ export function encodeEventTopics<
81
96
  eventName extends ContractEventName<abi> | undefined = undefined,
82
97
  >(
83
98
  parameters: EncodeEventTopicsParameters<abi, eventName>,
84
- ): EncodeEventTopicsReturnType {
99
+ ): EncodeEventTopicsReturnType<abi, eventName> {
85
100
  const { abi, eventName, args } = parameters as EncodeEventTopicsParameters
86
101
 
87
102
  let abiItem = abi[0]
@@ -94,9 +109,6 @@ export function encodeEventTopics<
94
109
  if (abiItem.type !== 'event')
95
110
  throw new AbiEventNotFoundError(undefined, { docsPath })
96
111
 
97
- const definition = formatAbiItem(abiItem)
98
- const signature = toEventSelector(definition as EventDefinition)
99
-
100
112
  let topics: (Hex | Hex[] | null)[] = []
101
113
  if (args && 'inputs' in abiItem) {
102
114
  const indexedInputs = abiItem.inputs?.filter(
@@ -121,7 +133,14 @@ export function encodeEventTopics<
121
133
  }) ?? []
122
134
  }
123
135
  }
124
- return [signature, ...topics]
136
+ // Anonymous events are not identified by a signature topic, so the event
137
+ // selector must not be prepended.
138
+ if (abiItem.anonymous)
139
+ return topics as EncodeEventTopicsReturnType<abi, eventName>
140
+
141
+ const definition = formatAbiItem(abiItem)
142
+ const signature = toEventSelector(definition as EventDefinition)
143
+ return [signature, ...topics] as EncodeEventTopicsReturnType<abi, eventName>
125
144
  }
126
145
 
127
146
  export type EncodeArgErrorType =
@@ -0,0 +1,63 @@
1
+ import { BaseError, type BaseErrorType } from '../../errors/base.js'
2
+ import type { BlockTag } from '../../types/block.js'
3
+ import type { Hash, Hex } from '../../types/misc.js'
4
+ import type { RpcBlockIdentifier } from '../../types/rpc.js'
5
+ import type { NumberToHexErrorType } from '../encoding/toHex.js'
6
+ import { numberToHex } from '../encoding/toHex.js'
7
+
8
+ type FormatBlockParameterParameters = {
9
+ blockHash?: Hash | undefined
10
+ blockNumber?: bigint | undefined
11
+ blockTag?: BlockTag | undefined
12
+ requireCanonical?: boolean | undefined
13
+ }
14
+
15
+ type RpcBlockHashIdentifier = Extract<RpcBlockIdentifier, { blockHash: Hash }>
16
+
17
+ type FormatBlockParameterReturnType = Hex | BlockTag | RpcBlockHashIdentifier
18
+
19
+ export type FormatBlockParameterErrorType = BaseErrorType | NumberToHexErrorType
20
+
21
+ /**
22
+ * Formats block parameters for RPC calls according to EIP-1898.
23
+ *
24
+ * @param parameters - Block parameters
25
+ * @returns Formatted block parameter for RPC call
26
+ *
27
+ * @example
28
+ * // Using block tag
29
+ * formatBlockParameter({ blockTag: 'latest' })
30
+ * // => 'latest'
31
+ *
32
+ * @example
33
+ * // Using block number
34
+ * formatBlockParameter({ blockNumber: 69420n })
35
+ * // => '0x10f2c'
36
+ *
37
+ * @example
38
+ * // Using block hash (EIP-1898)
39
+ * formatBlockParameter({ blockHash: '0x...' })
40
+ * // => { blockHash: '0x...' }
41
+ *
42
+ * @example
43
+ * // Using block hash with requireCanonical (EIP-1898)
44
+ * formatBlockParameter({ blockHash: '0x...', requireCanonical: true })
45
+ * // => { blockHash: '0x...', requireCanonical: true }
46
+ */
47
+ export function formatBlockParameter(
48
+ parameters: FormatBlockParameterParameters,
49
+ ): FormatBlockParameterReturnType {
50
+ const { blockHash, blockNumber, blockTag, requireCanonical } = parameters
51
+
52
+ if (requireCanonical !== undefined && !blockHash)
53
+ throw new BaseError(
54
+ '`requireCanonical` can only be provided when `blockHash` is set.',
55
+ )
56
+
57
+ if (blockHash)
58
+ return requireCanonical ? { blockHash, requireCanonical } : { blockHash }
59
+
60
+ if (typeof blockNumber === 'bigint') return numberToHex(blockNumber)
61
+
62
+ return blockTag ?? 'latest'
63
+ }
@@ -0,0 +1,67 @@
1
+ import { batchGatewayAbi } from '../constants/abis.js'
2
+ import { solidityError } from '../constants/solidity.js'
3
+ import { HttpRequestError } from '../errors/request.js'
4
+ import { decodeErrorResult } from './abi/decodeErrorResult.js'
5
+ import { decodeFunctionResult } from './abi/decodeFunctionResult.js'
6
+ import { encodeFunctionData } from './abi/encodeFunctionData.js'
7
+ import { ccipRequest as ccipRequest_ } from './ccip.js'
8
+ import { localBatchGatewayUrl } from './ens/localBatchGatewayRequest.js'
9
+
10
+ export type CcipReadTunnelParameters = {
11
+ batchGateways: string[]
12
+ ccipRequest?: typeof ccipRequest_
13
+ }
14
+
15
+ export function ccipReadTunnel({
16
+ batchGateways,
17
+ ccipRequest = ccipRequest_,
18
+ }: CcipReadTunnelParameters): { request: typeof ccipRequest_ } {
19
+ return {
20
+ async request({ data, sender, urls }) {
21
+ if (urls.includes(localBatchGatewayUrl)) {
22
+ return ccipRequest({
23
+ data,
24
+ sender,
25
+ urls: batchGateways,
26
+ })
27
+ } else {
28
+ const [failures, responses] = decodeFunctionResult({
29
+ abi: batchGatewayAbi,
30
+ functionName: 'query',
31
+ data: await ccipRequest({
32
+ data: encodeFunctionData({
33
+ abi: batchGatewayAbi,
34
+ functionName: 'query',
35
+ args: [[{ sender, data, urls }]],
36
+ }),
37
+ sender,
38
+ urls: batchGateways,
39
+ }),
40
+ })
41
+ if (failures[0]) {
42
+ let error: Error | undefined
43
+ try {
44
+ const res = decodeErrorResult({
45
+ abi: [...batchGatewayAbi, solidityError],
46
+ data: responses[0],
47
+ })
48
+ if (res.errorName === 'HttpError') {
49
+ error = new HttpRequestError({
50
+ body: { message: res.args[1] },
51
+ status: res.args[0],
52
+ url: urls.join(' | '),
53
+ })
54
+ } else {
55
+ const message = res.args[0]
56
+ if (message) {
57
+ error = new Error(message)
58
+ }
59
+ }
60
+ } catch {}
61
+ throw error ?? new Error('An unknown error occurred.')
62
+ }
63
+ return responses[0]
64
+ }
65
+ },
66
+ }
67
+ }
package/utils/index.ts CHANGED
@@ -155,6 +155,10 @@ export {
155
155
  offchainLookupAbiItem,
156
156
  offchainLookupSignature,
157
157
  } from './ccip.js'
158
+ export {
159
+ type CcipReadTunnelParameters,
160
+ ccipReadTunnel,
161
+ } from './ccipTunnel.js'
158
162
  export {
159
163
  type AssertCurrentChainErrorType,
160
164
  type AssertCurrentChainParameters,
@@ -50,6 +50,10 @@ export function createNonceManager(
50
50
 
51
51
  const getKey = ({ address, chainId }: FunctionParameters) =>
52
52
  `${address}.${chainId}`
53
+ const resetCache = (key: string) => {
54
+ deltaMap.delete(key)
55
+ promiseMap.delete(key)
56
+ }
53
57
 
54
58
  return {
55
59
  async consume({ address, chainId, client }) {
@@ -83,7 +87,7 @@ export function createNonceManager(
83
87
  nonceMap.delete(key)
84
88
  return nonce
85
89
  } finally {
86
- this.reset({ address, chainId })
90
+ resetCache(key)
87
91
  }
88
92
  })()
89
93
  promiseMap.set(key, promise)
@@ -94,8 +98,8 @@ export function createNonceManager(
94
98
  },
95
99
  reset({ address, chainId }) {
96
100
  const key = getKey({ address, chainId })
97
- deltaMap.delete(key)
98
- promiseMap.delete(key)
101
+ nonceMap.delete(key)
102
+ resetCache(key)
99
103
  },
100
104
  }
101
105
  }
package/utils/observe.ts CHANGED
@@ -39,10 +39,13 @@ export function observe<callbacks extends Callbacks>(
39
39
 
40
40
  const unsubscribe = () => {
41
41
  const listeners = getListeners()
42
- listenersCache.set(
43
- observerId,
44
- listeners.filter((cb: any) => cb.id !== callbackId),
45
- )
42
+ const nextListeners = listeners.filter((cb: any) => cb.id !== callbackId)
43
+ if (nextListeners.length === 0) {
44
+ listenersCache.delete(observerId)
45
+ cleanupCache.delete(observerId)
46
+ return
47
+ }
48
+ listenersCache.set(observerId, nextListeners)
46
49
  }
47
50
 
48
51
  const unwatch = () => {
@@ -131,11 +131,13 @@ export async function getSocketRpcClient<socket extends {}>(
131
131
  let error: Error | Event | undefined
132
132
  let socket: Socket<{}>
133
133
  let keepAliveTimer: ReturnType<typeof setInterval> | undefined
134
+ let reconnectTimer: ReturnType<typeof setTimeout> | undefined
134
135
 
135
136
  let reconnectInProgress = false
137
+ let intentionallyClosed = false
136
138
  function attemptReconnect() {
137
139
  // Attempt to reconnect.
138
- if (reconnect && reconnectCount < attempts) {
140
+ if (reconnect && !intentionallyClosed && reconnectCount < attempts) {
139
141
  if (reconnectInProgress) return
140
142
  reconnectInProgress = true
141
143
  reconnectCount++
@@ -143,7 +145,13 @@ export async function getSocketRpcClient<socket extends {}>(
143
145
  // Make sure the previous socket is definitely closed.
144
146
  socket?.close()
145
147
 
146
- setTimeout(async () => {
148
+ reconnectTimer = setTimeout(async () => {
149
+ reconnectTimer = undefined
150
+ // Bail if the client was intentionally closed during the delay.
151
+ if (intentionallyClosed) {
152
+ reconnectInProgress = false
153
+ return
154
+ }
147
155
  // biome-ignore lint/suspicious/noConsole: _
148
156
  await setup().catch(console.error)
149
157
  reconnectInProgress = false
@@ -192,6 +200,11 @@ export async function getSocketRpcClient<socket extends {}>(
192
200
  },
193
201
  })
194
202
 
203
+ if (intentionallyClosed) {
204
+ result.close()
205
+ return result
206
+ }
207
+
195
208
  socket = result
196
209
 
197
210
  if (keepAlive) {
@@ -220,7 +233,13 @@ export async function getSocketRpcClient<socket extends {}>(
220
233
  // Create a new socket instance.
221
234
  socketClient = {
222
235
  close() {
236
+ intentionallyClosed = true
223
237
  keepAliveTimer && clearInterval(keepAliveTimer)
238
+ if (reconnectTimer) {
239
+ clearTimeout(reconnectTimer)
240
+ reconnectTimer = undefined
241
+ reconnectInProgress = false
242
+ }
224
243
  socket.close()
225
244
  socketClientCache.delete(id)
226
245
  },