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.
- package/CHANGELOG.md +12 -0
- package/_cjs/chains/definitions/blastSepolia.js +26 -0
- package/_cjs/chains/definitions/blastSepolia.js.map +1 -0
- package/_cjs/chains/index.js +6 -4
- package/_cjs/chains/index.js.map +1 -1
- package/_cjs/clients/transports/http.js +8 -5
- package/_cjs/clients/transports/http.js.map +1 -1
- package/_cjs/clients/transports/ipc.js +77 -0
- package/_cjs/clients/transports/ipc.js.map +1 -0
- package/_cjs/clients/transports/webSocket.js +11 -7
- package/_cjs/clients/transports/webSocket.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/node/index.js +8 -0
- package/_cjs/node/index.js.map +1 -0
- package/_cjs/utils/index.js +13 -6
- package/_cjs/utils/index.js.map +1 -1
- package/_cjs/utils/rpc/compat.js +35 -0
- package/_cjs/utils/rpc/compat.js.map +1 -0
- package/_cjs/utils/rpc/http.js +74 -0
- package/_cjs/utils/rpc/http.js.map +1 -0
- package/_cjs/utils/rpc/id.js +17 -0
- package/_cjs/utils/rpc/id.js.map +1 -0
- package/_cjs/utils/rpc/ipc.js +75 -0
- package/_cjs/utils/rpc/ipc.js.map +1 -0
- package/_cjs/utils/rpc/socket.js +85 -0
- package/_cjs/utils/rpc/socket.js.map +1 -0
- package/_cjs/utils/rpc/webSocket.js +50 -0
- package/_cjs/utils/rpc/webSocket.js.map +1 -0
- package/_esm/chains/definitions/blastSepolia.js +23 -0
- package/_esm/chains/definitions/blastSepolia.js.map +1 -0
- package/_esm/chains/index.js +1 -0
- package/_esm/chains/index.js.map +1 -1
- package/_esm/clients/transports/http.js +8 -5
- package/_esm/clients/transports/http.js.map +1 -1
- package/_esm/clients/transports/ipc.js +77 -0
- package/_esm/clients/transports/ipc.js.map +1 -0
- package/_esm/clients/transports/webSocket.js +10 -6
- package/_esm/clients/transports/webSocket.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/node/index.js +3 -0
- package/_esm/node/index.js.map +1 -0
- package/_esm/utils/index.js +4 -1
- package/_esm/utils/index.js.map +1 -1
- package/_esm/utils/rpc/compat.js +86 -0
- package/_esm/utils/rpc/compat.js.map +1 -0
- package/_esm/utils/rpc/http.js +70 -0
- package/_esm/utils/rpc/http.js.map +1 -0
- package/_esm/utils/rpc/id.js +13 -0
- package/_esm/utils/rpc/id.js.map +1 -0
- package/_esm/utils/rpc/ipc.js +71 -0
- package/_esm/utils/rpc/ipc.js.map +1 -0
- package/_esm/utils/rpc/socket.js +90 -0
- package/_esm/utils/rpc/socket.js.map +1 -0
- package/_esm/utils/rpc/webSocket.js +48 -0
- package/_esm/utils/rpc/webSocket.js.map +1 -0
- package/_types/chains/definitions/blastSepolia.d.ts +34 -0
- package/_types/chains/definitions/blastSepolia.d.ts.map +1 -0
- package/_types/chains/index.d.ts +1 -0
- package/_types/chains/index.d.ts.map +1 -1
- package/_types/clients/transports/http.d.ts +2 -2
- package/_types/clients/transports/http.d.ts.map +1 -1
- package/_types/clients/transports/ipc.d.ts +46 -0
- package/_types/clients/transports/ipc.d.ts.map +1 -0
- package/_types/clients/transports/webSocket.d.ts +6 -1
- package/_types/clients/transports/webSocket.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/node/index.d.ts +3 -0
- package/_types/node/index.d.ts.map +1 -0
- package/_types/types/rpc.d.ts +35 -0
- package/_types/types/rpc.d.ts.map +1 -1
- package/_types/utils/buildRequest.d.ts +2 -2
- package/_types/utils/buildRequest.d.ts.map +1 -1
- package/_types/utils/index.d.ts +4 -1
- package/_types/utils/index.d.ts.map +1 -1
- package/_types/utils/rpc/compat.d.ts +78 -0
- package/_types/utils/rpc/compat.d.ts.map +1 -0
- package/_types/utils/rpc/http.d.ts +20 -0
- package/_types/utils/rpc/http.d.ts.map +1 -0
- package/_types/utils/rpc/id.d.ts +11 -0
- package/_types/utils/rpc/id.d.ts.map +1 -0
- package/_types/utils/rpc/ipc.d.ts +8 -0
- package/_types/utils/rpc/ipc.d.ts.map +1 -0
- package/_types/utils/rpc/socket.d.ts +45 -0
- package/_types/utils/rpc/socket.d.ts.map +1 -0
- package/_types/utils/rpc/webSocket.d.ts +3 -0
- package/_types/utils/rpc/webSocket.d.ts.map +1 -0
- package/chains/definitions/blastSepolia.ts +23 -0
- package/chains/index.ts +1 -0
- package/clients/transports/http.ts +15 -6
- package/clients/transports/ipc.ts +144 -0
- package/clients/transports/webSocket.ts +16 -6
- package/errors/version.ts +1 -1
- package/node/index.ts +11 -0
- package/node/package.json +6 -0
- package/package.json +9 -1
- package/types/rpc.ts +44 -0
- package/utils/buildRequest.ts +2 -2
- package/utils/index.ts +19 -8
- package/utils/rpc/compat.ts +117 -0
- package/utils/rpc/http.ts +132 -0
- package/utils/rpc/id.ts +13 -0
- package/utils/rpc/ipc.ts +89 -0
- package/utils/rpc/socket.ts +162 -0
- package/utils/rpc/webSocket.ts +63 -0
- package/_cjs/utils/rpc.js +0 -154
- package/_cjs/utils/rpc.js.map +0 -1
- package/_esm/utils/rpc.js +0 -160
- package/_esm/utils/rpc.js.map +0 -1
- package/_types/utils/rpc.d.ts +0 -80
- package/_types/utils/rpc.d.ts.map +0 -1
- 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
|
-
}
|