@psalomo/jsonrpc-client 0.1.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/dist/index.js ADDED
@@ -0,0 +1,367 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ JsonRpcClientError: () => JsonRpcClientError,
24
+ JsonRpcNetworkError: () => JsonRpcNetworkError,
25
+ NearRpcClient: () => NearRpcClient,
26
+ NearRpcError: () => NearRpcError,
27
+ RPC_METHODS: () => import_jsonrpc_types2.RPC_METHODS,
28
+ default: () => NearRpcClient
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/client.ts
33
+ var import_jsonrpc_types = require("@psalomo/jsonrpc-types");
34
+ var JsonRpcClientError = class extends Error {
35
+ constructor(message, code, data) {
36
+ super(message);
37
+ this.code = code;
38
+ this.data = data;
39
+ this.name = "JsonRpcClientError";
40
+ }
41
+ };
42
+ var JsonRpcNetworkError = class extends Error {
43
+ constructor(message, originalError) {
44
+ super(message);
45
+ this.originalError = originalError;
46
+ this.name = "JsonRpcNetworkError";
47
+ }
48
+ };
49
+ function camelToSnake(str) {
50
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
51
+ }
52
+ function snakeToCamel(str) {
53
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
54
+ }
55
+ function convertKeysToSnakeCase(obj) {
56
+ if (obj === null || typeof obj !== "object") {
57
+ return obj;
58
+ }
59
+ if (Array.isArray(obj)) {
60
+ return obj.map(convertKeysToSnakeCase);
61
+ }
62
+ const converted = {};
63
+ for (const [key, value] of Object.entries(obj)) {
64
+ const snakeKey = camelToSnake(key);
65
+ converted[snakeKey] = convertKeysToSnakeCase(value);
66
+ }
67
+ return converted;
68
+ }
69
+ function convertKeysToCamelCase(obj) {
70
+ if (obj === null || typeof obj !== "object") {
71
+ return obj;
72
+ }
73
+ if (Array.isArray(obj)) {
74
+ return obj.map(convertKeysToCamelCase);
75
+ }
76
+ const converted = {};
77
+ for (const [key, value] of Object.entries(obj)) {
78
+ const camelKey = snakeToCamel(key);
79
+ converted[camelKey] = convertKeysToCamelCase(value);
80
+ }
81
+ return converted;
82
+ }
83
+ var NearRpcClient = class {
84
+ endpoint;
85
+ headers;
86
+ timeout;
87
+ retries;
88
+ validateResponses;
89
+ requestIdCounter = 0;
90
+ constructor(config) {
91
+ if (typeof config === "string") {
92
+ this.endpoint = config;
93
+ this.headers = {
94
+ "Content-Type": "application/json"
95
+ };
96
+ this.timeout = 3e4;
97
+ this.retries = 3;
98
+ this.validateResponses = true;
99
+ } else {
100
+ this.endpoint = config.endpoint;
101
+ this.headers = {
102
+ "Content-Type": "application/json",
103
+ ...config.headers
104
+ };
105
+ this.timeout = config.timeout || 3e4;
106
+ this.retries = config.retries || 3;
107
+ this.validateResponses = config.validateResponses ?? true;
108
+ }
109
+ }
110
+ /**
111
+ * Generate a unique request ID
112
+ */
113
+ generateRequestId() {
114
+ return `near-rpc-${Date.now()}-${++this.requestIdCounter}`;
115
+ }
116
+ /**
117
+ * Make a raw JSON-RPC call
118
+ */
119
+ async call(method, params) {
120
+ const requestId = this.generateRequestId();
121
+ const snakeCaseParams = params ? convertKeysToSnakeCase(params) : void 0;
122
+ const request = {
123
+ jsonrpc: "2.0",
124
+ id: requestId,
125
+ method,
126
+ params: snakeCaseParams
127
+ };
128
+ if (this.validateResponses) {
129
+ try {
130
+ import_jsonrpc_types.JsonRpcRequestSchema.parse(request);
131
+ } catch (error) {
132
+ throw new JsonRpcNetworkError(
133
+ `Invalid request format: ${error instanceof Error ? error.message : "Unknown error"}`,
134
+ error
135
+ );
136
+ }
137
+ }
138
+ let lastError = null;
139
+ for (let attempt = 0; attempt <= this.retries; attempt++) {
140
+ try {
141
+ const controller = new AbortController();
142
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
143
+ const response = await fetch(this.endpoint, {
144
+ method: "POST",
145
+ headers: this.headers,
146
+ body: JSON.stringify(request),
147
+ signal: controller.signal
148
+ });
149
+ clearTimeout(timeoutId);
150
+ const jsonResponse = await response.json();
151
+ if (this.validateResponses) {
152
+ try {
153
+ import_jsonrpc_types.JsonRpcResponseSchema.parse(jsonResponse);
154
+ } catch (error) {
155
+ throw new JsonRpcClientError(
156
+ `Invalid response format: ${error instanceof Error ? error.message : "Unknown error"}`
157
+ );
158
+ }
159
+ }
160
+ const rpcResponse = jsonResponse;
161
+ if (rpcResponse.error) {
162
+ throw new JsonRpcClientError(
163
+ rpcResponse.error.message,
164
+ rpcResponse.error.code,
165
+ rpcResponse.error.data
166
+ );
167
+ }
168
+ if (!response.ok) {
169
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
170
+ }
171
+ const camelCaseResult = rpcResponse.result ? convertKeysToCamelCase(rpcResponse.result) : rpcResponse.result;
172
+ return camelCaseResult;
173
+ } catch (error) {
174
+ lastError = error;
175
+ if (error instanceof JsonRpcClientError) {
176
+ throw error;
177
+ }
178
+ if (attempt < this.retries) {
179
+ const delay = Math.min(1e3 * Math.pow(2, attempt), 1e4);
180
+ await new Promise((resolve) => setTimeout(resolve, delay));
181
+ continue;
182
+ }
183
+ }
184
+ }
185
+ throw new JsonRpcNetworkError(
186
+ `Failed to make RPC call after ${this.retries + 1} attempts: ${lastError?.message}`,
187
+ lastError
188
+ );
189
+ }
190
+ // Generated RPC methods will be added here
191
+ // This section will be auto-generated based on the OpenAPI spec
192
+ /**
193
+ * Get node status
194
+ */
195
+ async status() {
196
+ return this.call("status");
197
+ }
198
+ /**
199
+ * Get block information
200
+ */
201
+ async block(params) {
202
+ return this.call("block", params);
203
+ }
204
+ /**
205
+ * Get current gas price
206
+ */
207
+ async gasPrice(params) {
208
+ return this.call("gas_price", params);
209
+ }
210
+ /**
211
+ * Get chunk information
212
+ */
213
+ async chunk(params) {
214
+ return this.call("chunk", params);
215
+ }
216
+ /**
217
+ * Health check
218
+ */
219
+ async health() {
220
+ return this.call("health");
221
+ }
222
+ /**
223
+ * Get network information
224
+ */
225
+ async networkInfo() {
226
+ return this.call("network_info");
227
+ }
228
+ /**
229
+ * Get current validators
230
+ */
231
+ async validators(params) {
232
+ return this.call("validators", params);
233
+ }
234
+ /**
235
+ * Get client configuration
236
+ */
237
+ async clientConfig() {
238
+ return this.call("client_config");
239
+ }
240
+ /**
241
+ * Broadcast transaction asynchronously
242
+ */
243
+ async broadcastTxAsync(params) {
244
+ return this.call("broadcast_tx_async", params);
245
+ }
246
+ /**
247
+ * Broadcast transaction and wait for commit
248
+ */
249
+ async broadcastTxCommit(params) {
250
+ return this.call("broadcast_tx_commit", params);
251
+ }
252
+ /**
253
+ * Send transaction
254
+ */
255
+ async sendTx(params) {
256
+ return await this.call("send_tx", params);
257
+ }
258
+ /**
259
+ * Get transaction status
260
+ */
261
+ async tx(params) {
262
+ return this.call("tx", params);
263
+ }
264
+ /**
265
+ * Query account/contract state
266
+ */
267
+ async query(params) {
268
+ return this.call("query", params);
269
+ }
270
+ /**
271
+ * View account information (convenience method)
272
+ */
273
+ async viewAccount(params) {
274
+ return this.query({
275
+ requestType: "view_account",
276
+ ...params
277
+ });
278
+ }
279
+ /**
280
+ * View function call (convenience method)
281
+ */
282
+ async viewFunction(params) {
283
+ return this.query({
284
+ requestType: "call_function",
285
+ ...params
286
+ });
287
+ }
288
+ /**
289
+ * View access key (convenience method)
290
+ */
291
+ async viewAccessKey(params) {
292
+ return this.query({
293
+ requestType: "view_access_key",
294
+ ...params
295
+ });
296
+ }
297
+ /**
298
+ * Get light client proof
299
+ */
300
+ async lightClientProof(params) {
301
+ return this.call("light_client_proof", params);
302
+ }
303
+ // Experimental methods
304
+ /**
305
+ * Get state changes (experimental)
306
+ */
307
+ async experimentalChanges(params) {
308
+ return this.call("EXPERIMENTAL_changes", params);
309
+ }
310
+ /**
311
+ * Get state changes in block (experimental)
312
+ */
313
+ async experimentalChangesInBlock(params) {
314
+ return this.call("EXPERIMENTAL_changes_in_block", params);
315
+ }
316
+ /**
317
+ * Get ordered validators (experimental)
318
+ */
319
+ async experimentalValidatorsOrdered(params) {
320
+ return this.call("EXPERIMENTAL_validators_ordered", params);
321
+ }
322
+ /**
323
+ * Get protocol configuration (experimental)
324
+ */
325
+ async experimentalProtocolConfig(params) {
326
+ return this.call("EXPERIMENTAL_protocol_config", params);
327
+ }
328
+ /**
329
+ * Get genesis configuration (experimental)
330
+ */
331
+ async experimentalGenesisConfig() {
332
+ return this.call("EXPERIMENTAL_genesis_config");
333
+ }
334
+ /**
335
+ * Get receipt information (experimental)
336
+ */
337
+ async experimentalReceipt(params) {
338
+ return this.call("EXPERIMENTAL_receipt", params);
339
+ }
340
+ /**
341
+ * Get transaction status (experimental)
342
+ */
343
+ async experimentalTxStatus(params) {
344
+ return this.call("EXPERIMENTAL_tx_status", params);
345
+ }
346
+ };
347
+
348
+ // src/types.ts
349
+ var NearRpcError = class extends Error {
350
+ constructor(code, message, data) {
351
+ super(message);
352
+ this.code = code;
353
+ this.data = data;
354
+ this.name = "NearRpcError";
355
+ }
356
+ };
357
+
358
+ // src/index.ts
359
+ var import_jsonrpc_types2 = require("@psalomo/jsonrpc-types");
360
+ // Annotate the CommonJS export names for ESM import in node:
361
+ 0 && (module.exports = {
362
+ JsonRpcClientError,
363
+ JsonRpcNetworkError,
364
+ NearRpcClient,
365
+ NearRpcError,
366
+ RPC_METHODS
367
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,339 @@
1
+ // src/client.ts
2
+ import {
3
+ JsonRpcRequestSchema,
4
+ JsonRpcResponseSchema
5
+ } from "@psalomo/jsonrpc-types";
6
+ var JsonRpcClientError = class extends Error {
7
+ constructor(message, code, data) {
8
+ super(message);
9
+ this.code = code;
10
+ this.data = data;
11
+ this.name = "JsonRpcClientError";
12
+ }
13
+ };
14
+ var JsonRpcNetworkError = class extends Error {
15
+ constructor(message, originalError) {
16
+ super(message);
17
+ this.originalError = originalError;
18
+ this.name = "JsonRpcNetworkError";
19
+ }
20
+ };
21
+ function camelToSnake(str) {
22
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
23
+ }
24
+ function snakeToCamel(str) {
25
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
26
+ }
27
+ function convertKeysToSnakeCase(obj) {
28
+ if (obj === null || typeof obj !== "object") {
29
+ return obj;
30
+ }
31
+ if (Array.isArray(obj)) {
32
+ return obj.map(convertKeysToSnakeCase);
33
+ }
34
+ const converted = {};
35
+ for (const [key, value] of Object.entries(obj)) {
36
+ const snakeKey = camelToSnake(key);
37
+ converted[snakeKey] = convertKeysToSnakeCase(value);
38
+ }
39
+ return converted;
40
+ }
41
+ function convertKeysToCamelCase(obj) {
42
+ if (obj === null || typeof obj !== "object") {
43
+ return obj;
44
+ }
45
+ if (Array.isArray(obj)) {
46
+ return obj.map(convertKeysToCamelCase);
47
+ }
48
+ const converted = {};
49
+ for (const [key, value] of Object.entries(obj)) {
50
+ const camelKey = snakeToCamel(key);
51
+ converted[camelKey] = convertKeysToCamelCase(value);
52
+ }
53
+ return converted;
54
+ }
55
+ var NearRpcClient = class {
56
+ endpoint;
57
+ headers;
58
+ timeout;
59
+ retries;
60
+ validateResponses;
61
+ requestIdCounter = 0;
62
+ constructor(config) {
63
+ if (typeof config === "string") {
64
+ this.endpoint = config;
65
+ this.headers = {
66
+ "Content-Type": "application/json"
67
+ };
68
+ this.timeout = 3e4;
69
+ this.retries = 3;
70
+ this.validateResponses = true;
71
+ } else {
72
+ this.endpoint = config.endpoint;
73
+ this.headers = {
74
+ "Content-Type": "application/json",
75
+ ...config.headers
76
+ };
77
+ this.timeout = config.timeout || 3e4;
78
+ this.retries = config.retries || 3;
79
+ this.validateResponses = config.validateResponses ?? true;
80
+ }
81
+ }
82
+ /**
83
+ * Generate a unique request ID
84
+ */
85
+ generateRequestId() {
86
+ return `near-rpc-${Date.now()}-${++this.requestIdCounter}`;
87
+ }
88
+ /**
89
+ * Make a raw JSON-RPC call
90
+ */
91
+ async call(method, params) {
92
+ const requestId = this.generateRequestId();
93
+ const snakeCaseParams = params ? convertKeysToSnakeCase(params) : void 0;
94
+ const request = {
95
+ jsonrpc: "2.0",
96
+ id: requestId,
97
+ method,
98
+ params: snakeCaseParams
99
+ };
100
+ if (this.validateResponses) {
101
+ try {
102
+ JsonRpcRequestSchema.parse(request);
103
+ } catch (error) {
104
+ throw new JsonRpcNetworkError(
105
+ `Invalid request format: ${error instanceof Error ? error.message : "Unknown error"}`,
106
+ error
107
+ );
108
+ }
109
+ }
110
+ let lastError = null;
111
+ for (let attempt = 0; attempt <= this.retries; attempt++) {
112
+ try {
113
+ const controller = new AbortController();
114
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
115
+ const response = await fetch(this.endpoint, {
116
+ method: "POST",
117
+ headers: this.headers,
118
+ body: JSON.stringify(request),
119
+ signal: controller.signal
120
+ });
121
+ clearTimeout(timeoutId);
122
+ const jsonResponse = await response.json();
123
+ if (this.validateResponses) {
124
+ try {
125
+ JsonRpcResponseSchema.parse(jsonResponse);
126
+ } catch (error) {
127
+ throw new JsonRpcClientError(
128
+ `Invalid response format: ${error instanceof Error ? error.message : "Unknown error"}`
129
+ );
130
+ }
131
+ }
132
+ const rpcResponse = jsonResponse;
133
+ if (rpcResponse.error) {
134
+ throw new JsonRpcClientError(
135
+ rpcResponse.error.message,
136
+ rpcResponse.error.code,
137
+ rpcResponse.error.data
138
+ );
139
+ }
140
+ if (!response.ok) {
141
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
142
+ }
143
+ const camelCaseResult = rpcResponse.result ? convertKeysToCamelCase(rpcResponse.result) : rpcResponse.result;
144
+ return camelCaseResult;
145
+ } catch (error) {
146
+ lastError = error;
147
+ if (error instanceof JsonRpcClientError) {
148
+ throw error;
149
+ }
150
+ if (attempt < this.retries) {
151
+ const delay = Math.min(1e3 * Math.pow(2, attempt), 1e4);
152
+ await new Promise((resolve) => setTimeout(resolve, delay));
153
+ continue;
154
+ }
155
+ }
156
+ }
157
+ throw new JsonRpcNetworkError(
158
+ `Failed to make RPC call after ${this.retries + 1} attempts: ${lastError?.message}`,
159
+ lastError
160
+ );
161
+ }
162
+ // Generated RPC methods will be added here
163
+ // This section will be auto-generated based on the OpenAPI spec
164
+ /**
165
+ * Get node status
166
+ */
167
+ async status() {
168
+ return this.call("status");
169
+ }
170
+ /**
171
+ * Get block information
172
+ */
173
+ async block(params) {
174
+ return this.call("block", params);
175
+ }
176
+ /**
177
+ * Get current gas price
178
+ */
179
+ async gasPrice(params) {
180
+ return this.call("gas_price", params);
181
+ }
182
+ /**
183
+ * Get chunk information
184
+ */
185
+ async chunk(params) {
186
+ return this.call("chunk", params);
187
+ }
188
+ /**
189
+ * Health check
190
+ */
191
+ async health() {
192
+ return this.call("health");
193
+ }
194
+ /**
195
+ * Get network information
196
+ */
197
+ async networkInfo() {
198
+ return this.call("network_info");
199
+ }
200
+ /**
201
+ * Get current validators
202
+ */
203
+ async validators(params) {
204
+ return this.call("validators", params);
205
+ }
206
+ /**
207
+ * Get client configuration
208
+ */
209
+ async clientConfig() {
210
+ return this.call("client_config");
211
+ }
212
+ /**
213
+ * Broadcast transaction asynchronously
214
+ */
215
+ async broadcastTxAsync(params) {
216
+ return this.call("broadcast_tx_async", params);
217
+ }
218
+ /**
219
+ * Broadcast transaction and wait for commit
220
+ */
221
+ async broadcastTxCommit(params) {
222
+ return this.call("broadcast_tx_commit", params);
223
+ }
224
+ /**
225
+ * Send transaction
226
+ */
227
+ async sendTx(params) {
228
+ return await this.call("send_tx", params);
229
+ }
230
+ /**
231
+ * Get transaction status
232
+ */
233
+ async tx(params) {
234
+ return this.call("tx", params);
235
+ }
236
+ /**
237
+ * Query account/contract state
238
+ */
239
+ async query(params) {
240
+ return this.call("query", params);
241
+ }
242
+ /**
243
+ * View account information (convenience method)
244
+ */
245
+ async viewAccount(params) {
246
+ return this.query({
247
+ requestType: "view_account",
248
+ ...params
249
+ });
250
+ }
251
+ /**
252
+ * View function call (convenience method)
253
+ */
254
+ async viewFunction(params) {
255
+ return this.query({
256
+ requestType: "call_function",
257
+ ...params
258
+ });
259
+ }
260
+ /**
261
+ * View access key (convenience method)
262
+ */
263
+ async viewAccessKey(params) {
264
+ return this.query({
265
+ requestType: "view_access_key",
266
+ ...params
267
+ });
268
+ }
269
+ /**
270
+ * Get light client proof
271
+ */
272
+ async lightClientProof(params) {
273
+ return this.call("light_client_proof", params);
274
+ }
275
+ // Experimental methods
276
+ /**
277
+ * Get state changes (experimental)
278
+ */
279
+ async experimentalChanges(params) {
280
+ return this.call("EXPERIMENTAL_changes", params);
281
+ }
282
+ /**
283
+ * Get state changes in block (experimental)
284
+ */
285
+ async experimentalChangesInBlock(params) {
286
+ return this.call("EXPERIMENTAL_changes_in_block", params);
287
+ }
288
+ /**
289
+ * Get ordered validators (experimental)
290
+ */
291
+ async experimentalValidatorsOrdered(params) {
292
+ return this.call("EXPERIMENTAL_validators_ordered", params);
293
+ }
294
+ /**
295
+ * Get protocol configuration (experimental)
296
+ */
297
+ async experimentalProtocolConfig(params) {
298
+ return this.call("EXPERIMENTAL_protocol_config", params);
299
+ }
300
+ /**
301
+ * Get genesis configuration (experimental)
302
+ */
303
+ async experimentalGenesisConfig() {
304
+ return this.call("EXPERIMENTAL_genesis_config");
305
+ }
306
+ /**
307
+ * Get receipt information (experimental)
308
+ */
309
+ async experimentalReceipt(params) {
310
+ return this.call("EXPERIMENTAL_receipt", params);
311
+ }
312
+ /**
313
+ * Get transaction status (experimental)
314
+ */
315
+ async experimentalTxStatus(params) {
316
+ return this.call("EXPERIMENTAL_tx_status", params);
317
+ }
318
+ };
319
+
320
+ // src/types.ts
321
+ var NearRpcError = class extends Error {
322
+ constructor(code, message, data) {
323
+ super(message);
324
+ this.code = code;
325
+ this.data = data;
326
+ this.name = "NearRpcError";
327
+ }
328
+ };
329
+
330
+ // src/index.ts
331
+ import { RPC_METHODS as RPC_METHODS2 } from "@psalomo/jsonrpc-types";
332
+ export {
333
+ JsonRpcClientError,
334
+ JsonRpcNetworkError,
335
+ NearRpcClient,
336
+ NearRpcError,
337
+ RPC_METHODS2 as RPC_METHODS,
338
+ NearRpcClient as default
339
+ };