viem 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/chains/definitions/blastSepolia.js +26 -0
  3. package/_cjs/chains/definitions/blastSepolia.js.map +1 -0
  4. package/_cjs/chains/index.js +6 -4
  5. package/_cjs/chains/index.js.map +1 -1
  6. package/_cjs/clients/transports/http.js +8 -5
  7. package/_cjs/clients/transports/http.js.map +1 -1
  8. package/_cjs/clients/transports/ipc.js +77 -0
  9. package/_cjs/clients/transports/ipc.js.map +1 -0
  10. package/_cjs/clients/transports/webSocket.js +11 -7
  11. package/_cjs/clients/transports/webSocket.js.map +1 -1
  12. package/_cjs/errors/version.js +1 -1
  13. package/_cjs/node/index.js +8 -0
  14. package/_cjs/node/index.js.map +1 -0
  15. package/_cjs/utils/index.js +13 -6
  16. package/_cjs/utils/index.js.map +1 -1
  17. package/_cjs/utils/rpc/compat.js +35 -0
  18. package/_cjs/utils/rpc/compat.js.map +1 -0
  19. package/_cjs/utils/rpc/http.js +74 -0
  20. package/_cjs/utils/rpc/http.js.map +1 -0
  21. package/_cjs/utils/rpc/id.js +17 -0
  22. package/_cjs/utils/rpc/id.js.map +1 -0
  23. package/_cjs/utils/rpc/ipc.js +75 -0
  24. package/_cjs/utils/rpc/ipc.js.map +1 -0
  25. package/_cjs/utils/rpc/socket.js +85 -0
  26. package/_cjs/utils/rpc/socket.js.map +1 -0
  27. package/_cjs/utils/rpc/webSocket.js +50 -0
  28. package/_cjs/utils/rpc/webSocket.js.map +1 -0
  29. package/_esm/chains/definitions/blastSepolia.js +23 -0
  30. package/_esm/chains/definitions/blastSepolia.js.map +1 -0
  31. package/_esm/chains/index.js +1 -0
  32. package/_esm/chains/index.js.map +1 -1
  33. package/_esm/clients/transports/http.js +8 -5
  34. package/_esm/clients/transports/http.js.map +1 -1
  35. package/_esm/clients/transports/ipc.js +77 -0
  36. package/_esm/clients/transports/ipc.js.map +1 -0
  37. package/_esm/clients/transports/webSocket.js +10 -6
  38. package/_esm/clients/transports/webSocket.js.map +1 -1
  39. package/_esm/errors/version.js +1 -1
  40. package/_esm/node/index.js +3 -0
  41. package/_esm/node/index.js.map +1 -0
  42. package/_esm/utils/index.js +4 -1
  43. package/_esm/utils/index.js.map +1 -1
  44. package/_esm/utils/rpc/compat.js +86 -0
  45. package/_esm/utils/rpc/compat.js.map +1 -0
  46. package/_esm/utils/rpc/http.js +70 -0
  47. package/_esm/utils/rpc/http.js.map +1 -0
  48. package/_esm/utils/rpc/id.js +13 -0
  49. package/_esm/utils/rpc/id.js.map +1 -0
  50. package/_esm/utils/rpc/ipc.js +71 -0
  51. package/_esm/utils/rpc/ipc.js.map +1 -0
  52. package/_esm/utils/rpc/socket.js +90 -0
  53. package/_esm/utils/rpc/socket.js.map +1 -0
  54. package/_esm/utils/rpc/webSocket.js +48 -0
  55. package/_esm/utils/rpc/webSocket.js.map +1 -0
  56. package/_types/chains/definitions/blastSepolia.d.ts +34 -0
  57. package/_types/chains/definitions/blastSepolia.d.ts.map +1 -0
  58. package/_types/chains/index.d.ts +1 -0
  59. package/_types/chains/index.d.ts.map +1 -1
  60. package/_types/clients/transports/http.d.ts +2 -2
  61. package/_types/clients/transports/http.d.ts.map +1 -1
  62. package/_types/clients/transports/ipc.d.ts +46 -0
  63. package/_types/clients/transports/ipc.d.ts.map +1 -0
  64. package/_types/clients/transports/webSocket.d.ts +6 -1
  65. package/_types/clients/transports/webSocket.d.ts.map +1 -1
  66. package/_types/errors/version.d.ts +1 -1
  67. package/_types/node/index.d.ts +3 -0
  68. package/_types/node/index.d.ts.map +1 -0
  69. package/_types/types/rpc.d.ts +35 -0
  70. package/_types/types/rpc.d.ts.map +1 -1
  71. package/_types/utils/buildRequest.d.ts +2 -2
  72. package/_types/utils/buildRequest.d.ts.map +1 -1
  73. package/_types/utils/index.d.ts +4 -1
  74. package/_types/utils/index.d.ts.map +1 -1
  75. package/_types/utils/rpc/compat.d.ts +78 -0
  76. package/_types/utils/rpc/compat.d.ts.map +1 -0
  77. package/_types/utils/rpc/http.d.ts +20 -0
  78. package/_types/utils/rpc/http.d.ts.map +1 -0
  79. package/_types/utils/rpc/id.d.ts +11 -0
  80. package/_types/utils/rpc/id.d.ts.map +1 -0
  81. package/_types/utils/rpc/ipc.d.ts +8 -0
  82. package/_types/utils/rpc/ipc.d.ts.map +1 -0
  83. package/_types/utils/rpc/socket.d.ts +45 -0
  84. package/_types/utils/rpc/socket.d.ts.map +1 -0
  85. package/_types/utils/rpc/webSocket.d.ts +3 -0
  86. package/_types/utils/rpc/webSocket.d.ts.map +1 -0
  87. package/chains/definitions/blastSepolia.ts +23 -0
  88. package/chains/index.ts +1 -0
  89. package/clients/transports/http.ts +15 -6
  90. package/clients/transports/ipc.ts +144 -0
  91. package/clients/transports/webSocket.ts +16 -6
  92. package/errors/version.ts +1 -1
  93. package/node/index.ts +11 -0
  94. package/node/package.json +6 -0
  95. package/package.json +9 -1
  96. package/types/rpc.ts +44 -0
  97. package/utils/buildRequest.ts +2 -2
  98. package/utils/index.ts +19 -8
  99. package/utils/rpc/compat.ts +117 -0
  100. package/utils/rpc/http.ts +132 -0
  101. package/utils/rpc/id.ts +13 -0
  102. package/utils/rpc/ipc.ts +89 -0
  103. package/utils/rpc/socket.ts +162 -0
  104. package/utils/rpc/webSocket.ts +63 -0
  105. package/_cjs/utils/rpc.js +0 -154
  106. package/_cjs/utils/rpc.js.map +0 -1
  107. package/_esm/utils/rpc.js +0 -160
  108. package/_esm/utils/rpc.js.map +0 -1
  109. package/_types/utils/rpc.d.ts +0 -80
  110. package/_types/utils/rpc.d.ts.map +0 -1
  111. package/utils/rpc.ts +0 -318
package/utils/rpc.ts DELETED
@@ -1,318 +0,0 @@
1
- import type { MessageEvent } from 'isows'
2
-
3
- import {
4
- HttpRequestError,
5
- type HttpRequestErrorType,
6
- TimeoutError,
7
- type TimeoutErrorType,
8
- WebSocketRequestError,
9
- } from '../errors/request.js'
10
- import type { ErrorType } from '../errors/utils.js'
11
- import {
12
- type CreateBatchSchedulerErrorType,
13
- createBatchScheduler,
14
- } from './promise/createBatchScheduler.js'
15
- import {
16
- type WithTimeoutErrorType,
17
- withTimeout,
18
- } from './promise/withTimeout.js'
19
- import { stringify } from './stringify.js'
20
-
21
- let id = 0
22
-
23
- type SuccessResult<T> = {
24
- method?: never
25
- result: T
26
- error?: never
27
- }
28
- type ErrorResult<T> = {
29
- method?: never
30
- result?: never
31
- error: T
32
- }
33
- type Subscription<TResult, TError> = {
34
- method: 'eth_subscription'
35
- error?: never
36
- result?: never
37
- params: {
38
- subscription: string
39
- } & (
40
- | {
41
- result: TResult
42
- error?: never
43
- }
44
- | {
45
- result?: never
46
- error: TError
47
- }
48
- )
49
- }
50
-
51
- export type RpcRequest = { method: string; params?: any; id?: number }
52
-
53
- export type RpcResponse<TResult = any, TError = any> = {
54
- jsonrpc: `${number}`
55
- id: number
56
- } & (
57
- | SuccessResult<TResult>
58
- | ErrorResult<TError>
59
- | Subscription<TResult, TError>
60
- )
61
-
62
- ///////////////////////////////////////////////////
63
- // HTTP
64
-
65
- export type HttpOptions<TBody extends RpcRequest | RpcRequest[] = RpcRequest> =
66
- {
67
- // The RPC request body.
68
- body: TBody
69
- // Request configuration to pass to `fetch`.
70
- fetchOptions?: Omit<RequestInit, 'body'>
71
- // The timeout (in ms) for the request.
72
- timeout?: number
73
- }
74
-
75
- export type HttpReturnType<
76
- TBody extends RpcRequest | RpcRequest[] = RpcRequest,
77
- > = TBody extends RpcRequest[] ? RpcResponse[] : RpcResponse
78
-
79
- export type HttpErrorType =
80
- | HttpRequestErrorType
81
- | TimeoutErrorType
82
- | WithTimeoutErrorType
83
- | ErrorType
84
-
85
- async function http<TBody extends RpcRequest | RpcRequest[]>(
86
- url: string,
87
- { body, fetchOptions = {}, timeout = 10_000 }: HttpOptions<TBody>,
88
- ): Promise<HttpReturnType<TBody>> {
89
- const { headers, method, signal: signal_ } = fetchOptions
90
- try {
91
- const response = await withTimeout(
92
- async ({ signal }) => {
93
- const response = await fetch(url, {
94
- ...fetchOptions,
95
- body: Array.isArray(body)
96
- ? stringify(
97
- body.map((body) => ({
98
- jsonrpc: '2.0',
99
- id: body.id ?? id++,
100
- ...body,
101
- })),
102
- )
103
- : stringify({ jsonrpc: '2.0', id: body.id ?? id++, ...body }),
104
- headers: {
105
- ...headers,
106
- 'Content-Type': 'application/json',
107
- },
108
- method: method || 'POST',
109
- signal: signal_ || (timeout > 0 ? signal : undefined),
110
- })
111
- return response
112
- },
113
- {
114
- errorInstance: new TimeoutError({ body, url }),
115
- timeout,
116
- signal: true,
117
- },
118
- )
119
-
120
- let data: any
121
- if (response.headers.get('Content-Type')?.startsWith('application/json')) {
122
- data = await response.json()
123
- } else {
124
- data = await response.text()
125
- }
126
-
127
- if (!response.ok) {
128
- throw new HttpRequestError({
129
- body,
130
- details: stringify(data.error) || response.statusText,
131
- headers: response.headers,
132
- status: response.status,
133
- url,
134
- })
135
- }
136
-
137
- return data
138
- } catch (err) {
139
- if (err instanceof HttpRequestError) throw err
140
- if (err instanceof TimeoutError) throw err
141
- throw new HttpRequestError({
142
- body,
143
- details: (err as Error).message,
144
- url,
145
- })
146
- }
147
- }
148
-
149
- ///////////////////////////////////////////////////
150
- // WebSocket
151
-
152
- type Id = string | number
153
- type CallbackFn = (message: any) => void
154
- type CallbackMap = Map<Id, CallbackFn>
155
-
156
- export type Socket = WebSocket & {
157
- requests: CallbackMap
158
- subscriptions: CallbackMap
159
- }
160
-
161
- export type GetSocketErrorType = CreateBatchSchedulerErrorType | ErrorType
162
-
163
- export const socketsCache = /*#__PURE__*/ new Map<string, Socket>()
164
-
165
- export async function getSocket(url: string) {
166
- let socket = socketsCache.get(url)
167
-
168
- // If the socket already exists, return it.
169
- if (socket) return socket
170
-
171
- const { schedule } = createBatchScheduler<undefined, [Socket]>({
172
- id: url,
173
- fn: async () => {
174
- const WebSocket = await import('isows').then((module) => module.WebSocket)
175
- const webSocket = new WebSocket(url)
176
-
177
- // Set up a cache for incoming "synchronous" requests.
178
- const requests = new Map<Id, CallbackFn>()
179
-
180
- // Set up a cache for subscriptions (eth_subscribe).
181
- const subscriptions = new Map<Id, CallbackFn>()
182
-
183
- const onMessage: (event: MessageEvent) => void = ({ data }) => {
184
- const message: RpcResponse = JSON.parse(data as string)
185
- const isSubscription = message.method === 'eth_subscription'
186
- const id = isSubscription ? message.params.subscription : message.id
187
- const cache = isSubscription ? subscriptions : requests
188
- const callback = cache.get(id)
189
- if (callback) callback({ data })
190
- if (!isSubscription) cache.delete(id)
191
- }
192
- const onClose = () => {
193
- socketsCache.delete(url)
194
- webSocket.removeEventListener('close', onClose)
195
- webSocket.removeEventListener('message', onMessage)
196
- }
197
-
198
- // Setup event listeners for RPC & subscription responses.
199
- webSocket.addEventListener('close', onClose)
200
- webSocket.addEventListener('message', onMessage)
201
-
202
- // Wait for the socket to open.
203
- if (webSocket.readyState === WebSocket.CONNECTING) {
204
- await new Promise((resolve, reject) => {
205
- if (!webSocket) return
206
- webSocket.onopen = resolve
207
- webSocket.onerror = reject
208
- })
209
- }
210
-
211
- // Create a new socket instance.
212
- socket = Object.assign(webSocket, {
213
- requests,
214
- subscriptions,
215
- })
216
- socketsCache.set(url, socket)
217
-
218
- return [socket]
219
- },
220
- })
221
-
222
- const [_, [socket_]] = await schedule()
223
- return socket_
224
- }
225
-
226
- export type WebSocketOptions = {
227
- /** The RPC request body. */
228
- body: RpcRequest
229
- /** The callback to invoke on response. */
230
- onResponse?: (message: RpcResponse) => void
231
- }
232
-
233
- export type WebSocketReturnType = Socket
234
-
235
- export type WebSocketErrorType = WebSocketRequestError | ErrorType
236
-
237
- function webSocket(
238
- socket: Socket,
239
- { body, onResponse }: WebSocketOptions,
240
- ): WebSocketReturnType {
241
- if (
242
- socket.readyState === socket.CLOSED ||
243
- socket.readyState === socket.CLOSING
244
- )
245
- throw new WebSocketRequestError({
246
- body,
247
- url: socket.url,
248
- details: 'Socket is closed.',
249
- })
250
-
251
- const id_ = id++
252
-
253
- const callback = ({ data }: { data: any }) => {
254
- const message: RpcResponse = JSON.parse(data)
255
-
256
- if (typeof message.id === 'number' && id_ !== message.id) return
257
-
258
- onResponse?.(message)
259
-
260
- // If we are subscribing to a topic, we want to set up a listener for incoming
261
- // messages.
262
- if (body.method === 'eth_subscribe' && typeof message.result === 'string') {
263
- socket.subscriptions.set(message.result, callback)
264
- }
265
-
266
- // If we are unsubscribing from a topic, we want to remove the listener.
267
- if (body.method === 'eth_unsubscribe') {
268
- socket.subscriptions.delete(body.params?.[0])
269
- }
270
- }
271
- socket.requests.set(id_, callback)
272
-
273
- socket.send(JSON.stringify({ jsonrpc: '2.0', ...body, id: id_ }))
274
-
275
- return socket
276
- }
277
-
278
- export type WebSocketAsyncOptions = {
279
- /** The RPC request body. */
280
- body: RpcRequest
281
- /** The timeout (in ms) for the request. */
282
- timeout?: number
283
- }
284
-
285
- export type WebSocketAsyncReturnType = RpcResponse
286
-
287
- export type WebSocketAsyncErrorType =
288
- | WebSocketErrorType
289
- | TimeoutErrorType
290
- | WithTimeoutErrorType
291
- | ErrorType
292
-
293
- async function webSocketAsync(
294
- socket: Socket,
295
- { body, timeout = 10_000 }: WebSocketAsyncOptions,
296
- ): Promise<WebSocketAsyncReturnType> {
297
- return withTimeout(
298
- () =>
299
- new Promise<RpcResponse>((onResponse) =>
300
- rpc.webSocket(socket, {
301
- body,
302
- onResponse,
303
- }),
304
- ),
305
- {
306
- errorInstance: new TimeoutError({ body, url: socket.url }),
307
- timeout,
308
- },
309
- )
310
- }
311
-
312
- ///////////////////////////////////////////////////
313
-
314
- export const rpc = {
315
- http,
316
- webSocket,
317
- webSocketAsync,
318
- }