@sidhujag/sysweb3-keyring 2.1.12 → 2.1.14
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 +9 -0
- package/cjs/index.js +4 -1
- package/cjs/index.js.map +1 -1
- package/cjs/providers.js +77 -166
- package/cjs/providers.js.map +1 -1
- package/cjs/rpc-read-client.js +394 -0
- package/cjs/rpc-read-client.js.map +1 -0
- package/cjs/rpc-transport.js +136 -0
- package/cjs/rpc-transport.js.map +1 -0
- package/cjs/transactions/syscoin-core.js +2 -1
- package/cjs/transactions/syscoin-core.js.map +1 -1
- package/cjs/utils/utxo-fee-rate.js +26 -0
- package/cjs/utils/utxo-fee-rate.js.map +1 -0
- package/esm/providers.js +76 -165
- package/esm/providers.js.map +1 -1
- package/esm/rpc-read-client.js +389 -0
- package/esm/rpc-read-client.js.map +1 -0
- package/esm/rpc-transport.js +130 -0
- package/esm/rpc-transport.js.map +1 -0
- package/esm/transactions/syscoin-core.js +2 -1
- package/esm/transactions/syscoin-core.js.map +1 -1
- package/esm/utils/utxo-fee-rate.js +23 -0
- package/esm/utils/utxo-fee-rate.js.map +1 -0
- package/package.json +13 -1
- package/types/index.d.ts +2 -0
- package/types/keyring-core.d.ts +1 -1
- package/types/providers.d.ts +8 -7
- package/types/rpc-read-client.d.ts +45 -0
- package/types/rpc-transport.d.ts +27 -0
- package/types/utils/utxo-fee-rate.d.ts +5 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { isReadOnlyRpcMethod, requestJsonRpc, RpcResponseIntegrityError, } from './rpc-transport';
|
|
2
|
+
class RpcBatchRefused extends Error {
|
|
3
|
+
}
|
|
4
|
+
class RpcPayloadTooLarge extends Error {
|
|
5
|
+
}
|
|
6
|
+
class RpcBatchLimit extends Error {
|
|
7
|
+
}
|
|
8
|
+
const aborted = (signal) => {
|
|
9
|
+
if (signal.reason instanceof Error)
|
|
10
|
+
return signal.reason;
|
|
11
|
+
return Object.assign(new Error('RPC read aborted'), { name: 'AbortError' });
|
|
12
|
+
};
|
|
13
|
+
const check = (signal) => {
|
|
14
|
+
if (signal.aborted)
|
|
15
|
+
throw aborted(signal);
|
|
16
|
+
};
|
|
17
|
+
const byteLength = (value) => new TextEncoder().encode(value).byteLength;
|
|
18
|
+
const boundedInteger = (value, maximum, name) => {
|
|
19
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > maximum)
|
|
20
|
+
throw new Error(`Invalid RPC ${name}`);
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
export class RpcReadError extends Error {
|
|
24
|
+
constructor(value) {
|
|
25
|
+
super(value.message);
|
|
26
|
+
this.name = 'RpcReadError';
|
|
27
|
+
this.code = value.code;
|
|
28
|
+
this.data = value.data;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const batchFailure = (value) => {
|
|
32
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
33
|
+
return undefined;
|
|
34
|
+
const { jsonrpc, result, error, id } = value;
|
|
35
|
+
if (jsonrpc !== '2.0' ||
|
|
36
|
+
result !== undefined ||
|
|
37
|
+
(id !== null && id !== undefined) ||
|
|
38
|
+
!error ||
|
|
39
|
+
!Number.isSafeInteger(error.code) ||
|
|
40
|
+
typeof error.message !== 'string')
|
|
41
|
+
return undefined;
|
|
42
|
+
if ((error.code === -32600 || error.code === -32005) &&
|
|
43
|
+
/batch|array/i.test(error.message)) {
|
|
44
|
+
if (/too (?:large|many)|more than|limit|maximum|max(?:imum)? size/i.test(error.message))
|
|
45
|
+
return new RpcBatchLimit();
|
|
46
|
+
if (/unsupported|not support|not allowed|invalid (?:request|batch|array)/i.test(error.message))
|
|
47
|
+
return new RpcBatchRefused();
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
};
|
|
51
|
+
async function responseText(response, maximum, signal) {
|
|
52
|
+
const declared = response.headers.get('content-length');
|
|
53
|
+
if (declared !== null &&
|
|
54
|
+
(!/^\d+$/.test(declared) || Number(declared) > maximum)) {
|
|
55
|
+
void response.body?.cancel().catch(() => undefined);
|
|
56
|
+
throw new RpcResponseIntegrityError('RPC response exceeded size limit', false);
|
|
57
|
+
}
|
|
58
|
+
if (!response.body?.getReader) {
|
|
59
|
+
const text = await response.text();
|
|
60
|
+
check(signal);
|
|
61
|
+
if (byteLength(text) > maximum)
|
|
62
|
+
throw new RpcResponseIntegrityError('RPC response exceeded size limit', false);
|
|
63
|
+
return text;
|
|
64
|
+
}
|
|
65
|
+
const reader = response.body.getReader();
|
|
66
|
+
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
67
|
+
let size = 0;
|
|
68
|
+
let text = '';
|
|
69
|
+
try {
|
|
70
|
+
let complete = false;
|
|
71
|
+
while (!complete) {
|
|
72
|
+
check(signal);
|
|
73
|
+
const part = await reader.read();
|
|
74
|
+
if (part.done) {
|
|
75
|
+
complete = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
size += part.value.byteLength;
|
|
79
|
+
if (size > maximum)
|
|
80
|
+
throw new RpcResponseIntegrityError('RPC response exceeded size limit', false);
|
|
81
|
+
text += decoder.decode(part.value, { stream: true });
|
|
82
|
+
}
|
|
83
|
+
return text + decoder.decode();
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
void reader.cancel().catch(() => undefined);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Bounded, read-only JSON-RPC transport. Each instance belongs to one endpoint generation. */
|
|
90
|
+
export class JsonRpcReadClient {
|
|
91
|
+
constructor(url, options = {}) {
|
|
92
|
+
this.lifetime = new AbortController();
|
|
93
|
+
this.queue = [];
|
|
94
|
+
this.active = 0;
|
|
95
|
+
this.chainGeneration = 0;
|
|
96
|
+
this.endpoint = url;
|
|
97
|
+
const endpoint = new URL(url);
|
|
98
|
+
if (!['https:', 'http:'].includes(endpoint.protocol))
|
|
99
|
+
throw new Error('Invalid RPC URL');
|
|
100
|
+
this.fetcher =
|
|
101
|
+
options.fetch ??
|
|
102
|
+
((address, init) => fetch(address, init));
|
|
103
|
+
this.options = {
|
|
104
|
+
requestInit: options.requestInit ?? {},
|
|
105
|
+
recoverResponse: options.recoverResponse ?? true,
|
|
106
|
+
maxBatchItems: boundedInteger(options.maxBatchItems ?? 40, 128, 'batch size'),
|
|
107
|
+
maxRequestBytes: boundedInteger(options.maxRequestBytes ?? 256 * 1024, 2 * 1024 * 1024, 'request size'),
|
|
108
|
+
maxResponseBytes: boundedInteger(options.maxResponseBytes ?? 2 * 1024 * 1024, 8 * 1024 * 1024, 'response size'),
|
|
109
|
+
maxConcurrency: boundedInteger(options.maxConcurrency ?? 4, 16, 'concurrency'),
|
|
110
|
+
timeoutMs: boundedInteger(options.timeoutMs ?? 12000, 30000, 'timeout'),
|
|
111
|
+
};
|
|
112
|
+
this.batchLimit = this.options.maxBatchItems;
|
|
113
|
+
if (options.signal?.aborted)
|
|
114
|
+
this.destroy();
|
|
115
|
+
else
|
|
116
|
+
options.signal?.addEventListener('abort', () => this.destroy(), {
|
|
117
|
+
once: true,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
get url() {
|
|
121
|
+
return this.endpoint;
|
|
122
|
+
}
|
|
123
|
+
destroy() {
|
|
124
|
+
this.chainGeneration++;
|
|
125
|
+
this.chainCache = undefined;
|
|
126
|
+
this.chainRequest?.controller.abort();
|
|
127
|
+
this.lifetime.abort();
|
|
128
|
+
}
|
|
129
|
+
async slot(signal, work) {
|
|
130
|
+
check(signal);
|
|
131
|
+
await new Promise((resolve, reject) => {
|
|
132
|
+
const waiter = {
|
|
133
|
+
run: () => {
|
|
134
|
+
signal.removeEventListener('abort', waiter.cancel);
|
|
135
|
+
this.active++;
|
|
136
|
+
resolve();
|
|
137
|
+
},
|
|
138
|
+
cancel: () => {
|
|
139
|
+
const i = this.queue.indexOf(waiter);
|
|
140
|
+
if (i >= 0)
|
|
141
|
+
this.queue.splice(i, 1);
|
|
142
|
+
reject(aborted(signal));
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
if (this.active < this.options.maxConcurrency)
|
|
146
|
+
waiter.run();
|
|
147
|
+
else {
|
|
148
|
+
this.queue.push(waiter);
|
|
149
|
+
signal.addEventListener('abort', waiter.cancel, { once: true });
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
try {
|
|
153
|
+
check(signal);
|
|
154
|
+
return await work();
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
this.active--;
|
|
158
|
+
this.queue.shift()?.run();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async readMany(inputs, options = {}) {
|
|
162
|
+
if (!Array.isArray(inputs) ||
|
|
163
|
+
inputs.length > 1024 ||
|
|
164
|
+
inputs.some((input) => !input ||
|
|
165
|
+
!isReadOnlyRpcMethod(input.method) ||
|
|
166
|
+
!Array.isArray(input.params)))
|
|
167
|
+
throw new Error('Invalid read-only RPC requests');
|
|
168
|
+
// Snapshot before any await so caller mutations cannot change dispatched reads.
|
|
169
|
+
const serialized = JSON.stringify(inputs);
|
|
170
|
+
if (byteLength(serialized) > this.options.maxRequestBytes * 16)
|
|
171
|
+
throw new Error('RPC read work exceeded request budget');
|
|
172
|
+
const snapshot = JSON.parse(serialized);
|
|
173
|
+
if (!Array.isArray(snapshot) ||
|
|
174
|
+
snapshot.length > 1024 ||
|
|
175
|
+
snapshot.some((input) => !input ||
|
|
176
|
+
!isReadOnlyRpcMethod(input.method) ||
|
|
177
|
+
!Array.isArray(input.params)))
|
|
178
|
+
throw new Error('Invalid read-only RPC requests');
|
|
179
|
+
const timeout = boundedInteger(options.timeoutMs ?? this.options.timeoutMs, 30000, 'timeout');
|
|
180
|
+
const maximum = boundedInteger(options.maxResponseBytes ?? this.options.maxResponseBytes, 8 * 1024 * 1024, 'response size');
|
|
181
|
+
const controller = new AbortController();
|
|
182
|
+
const abort = () => controller.abort(options.signal?.reason ?? this.lifetime.signal.reason);
|
|
183
|
+
const sources = [options.signal, this.lifetime.signal].filter((value) => !!value);
|
|
184
|
+
sources.forEach((source) => source.addEventListener('abort', abort, { once: true }));
|
|
185
|
+
if (sources.some((source) => source.aborted))
|
|
186
|
+
abort();
|
|
187
|
+
const timer = setTimeout(() => controller.abort(Object.assign(new Error('RPC read deadline exceeded'), {
|
|
188
|
+
name: 'AbortError',
|
|
189
|
+
})), timeout);
|
|
190
|
+
const signal = controller.signal;
|
|
191
|
+
let attempts = 0;
|
|
192
|
+
const request = (rows, batch) => requestJsonRpc(this.url, rows, batch, signal, async (url, body) => {
|
|
193
|
+
if (++attempts > 2048)
|
|
194
|
+
throw new Error('RPC attempt limit exceeded');
|
|
195
|
+
if (byteLength(body) > this.options.maxRequestBytes)
|
|
196
|
+
throw new RpcPayloadTooLarge();
|
|
197
|
+
return this.slot(signal, async () => {
|
|
198
|
+
const headers = new Headers(this.options.requestInit.headers);
|
|
199
|
+
headers.set('Content-Type', 'application/json');
|
|
200
|
+
headers.set('Accept', 'application/json');
|
|
201
|
+
const response = await this.fetcher(url, {
|
|
202
|
+
...this.options.requestInit,
|
|
203
|
+
method: 'POST',
|
|
204
|
+
headers,
|
|
205
|
+
body,
|
|
206
|
+
signal,
|
|
207
|
+
});
|
|
208
|
+
check(signal);
|
|
209
|
+
if (response.status === 413) {
|
|
210
|
+
void response.body?.cancel().catch(() => undefined);
|
|
211
|
+
throw new RpcPayloadTooLarge();
|
|
212
|
+
}
|
|
213
|
+
const contentType = response.headers.get('content-type');
|
|
214
|
+
if (contentType &&
|
|
215
|
+
!/^(application\/json|application\/[a-z0-9!#$&^_.+-]+\+json)(?:\s*;|$)/i.test(contentType)) {
|
|
216
|
+
void response.body?.cancel().catch(() => undefined);
|
|
217
|
+
throw new RpcResponseIntegrityError('Invalid JSON-RPC content type', false);
|
|
218
|
+
}
|
|
219
|
+
const text = await responseText(response, maximum, signal);
|
|
220
|
+
let json;
|
|
221
|
+
try {
|
|
222
|
+
json = JSON.parse(text);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
throw new RpcResponseIntegrityError('Invalid JSON-RPC JSON response', false);
|
|
226
|
+
}
|
|
227
|
+
const batchError = batch ? batchFailure(json) : undefined;
|
|
228
|
+
if (batchError)
|
|
229
|
+
throw batchError;
|
|
230
|
+
if (!response.ok || response.status !== 200)
|
|
231
|
+
throw Object.assign(new Error(`RPC HTTP ${response.status}`), {
|
|
232
|
+
status: response.status,
|
|
233
|
+
});
|
|
234
|
+
return json;
|
|
235
|
+
});
|
|
236
|
+
}, this.options.recoverResponse);
|
|
237
|
+
const execute = async (rows) => {
|
|
238
|
+
check(signal);
|
|
239
|
+
try {
|
|
240
|
+
const responses = await request(rows, rows.length > 1);
|
|
241
|
+
return responses.map((response) => {
|
|
242
|
+
if (response.error)
|
|
243
|
+
return {
|
|
244
|
+
status: 'rejected',
|
|
245
|
+
reason: new RpcReadError(response.error),
|
|
246
|
+
};
|
|
247
|
+
return { status: 'fulfilled', value: response.result };
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
check(signal);
|
|
252
|
+
if (rows.length > 1 &&
|
|
253
|
+
(error instanceof RpcBatchRefused ||
|
|
254
|
+
error instanceof RpcPayloadTooLarge ||
|
|
255
|
+
error instanceof RpcBatchLimit)) {
|
|
256
|
+
this.batchLimit =
|
|
257
|
+
error instanceof RpcBatchRefused
|
|
258
|
+
? 1
|
|
259
|
+
: Math.min(this.batchLimit, Math.ceil(rows.length / 2));
|
|
260
|
+
const results = [];
|
|
261
|
+
let offset = 0;
|
|
262
|
+
while (offset < rows.length) {
|
|
263
|
+
const next = Math.min(rows.length, offset + this.batchLimit);
|
|
264
|
+
const chunk = rows.slice(offset, next);
|
|
265
|
+
offset = next;
|
|
266
|
+
results.push(...(await execute(chunk)));
|
|
267
|
+
}
|
|
268
|
+
return results;
|
|
269
|
+
}
|
|
270
|
+
return rows.map(() => ({ status: 'rejected', reason: error }));
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
try {
|
|
274
|
+
check(signal);
|
|
275
|
+
const batches = [];
|
|
276
|
+
for (let i = 0; i < snapshot.length; i += this.batchLimit)
|
|
277
|
+
batches.push(snapshot.slice(i, i + this.batchLimit));
|
|
278
|
+
let next = 0;
|
|
279
|
+
const results = new Array(batches.length);
|
|
280
|
+
const workers = Array.from({ length: Math.min(batches.length, this.options.maxConcurrency) }, async () => {
|
|
281
|
+
while (next < batches.length) {
|
|
282
|
+
const index = next++;
|
|
283
|
+
results[index] = await execute(batches[index]);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
const work = Promise.all(workers).then(() => results.flat());
|
|
287
|
+
return await new Promise((resolve, reject) => {
|
|
288
|
+
const cancelled = () => reject(aborted(signal));
|
|
289
|
+
signal.addEventListener('abort', cancelled, { once: true });
|
|
290
|
+
work
|
|
291
|
+
.then(resolve, reject)
|
|
292
|
+
.finally(() => signal.removeEventListener('abort', cancelled));
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
finally {
|
|
296
|
+
clearTimeout(timer);
|
|
297
|
+
sources.forEach((source) => source.removeEventListener('abort', abort));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
async read(method, params, options) {
|
|
301
|
+
const [result] = await this.readMany([{ method, params }], options);
|
|
302
|
+
if (result.status === 'rejected')
|
|
303
|
+
throw result.reason;
|
|
304
|
+
return result.value;
|
|
305
|
+
}
|
|
306
|
+
getChainId(options = {}) {
|
|
307
|
+
const timeout = boundedInteger(options.timeoutMs ?? this.options.timeoutMs, 30000, 'timeout');
|
|
308
|
+
const maxResponseBytes = boundedInteger(options.maxResponseBytes ?? this.options.maxResponseBytes, 8 * 1024 * 1024, 'response size');
|
|
309
|
+
if (options.signal?.aborted)
|
|
310
|
+
return Promise.reject(aborted(options.signal));
|
|
311
|
+
if (this.lifetime.signal.aborted)
|
|
312
|
+
return Promise.reject(aborted(this.lifetime.signal));
|
|
313
|
+
if (!options.fresh &&
|
|
314
|
+
this.chainCache &&
|
|
315
|
+
this.chainCache.expires > Date.now())
|
|
316
|
+
return Promise.resolve(this.chainCache.value);
|
|
317
|
+
if (options.fresh) {
|
|
318
|
+
this.chainRequest = undefined;
|
|
319
|
+
this.chainCache = undefined;
|
|
320
|
+
}
|
|
321
|
+
let request = !options.fresh && this.chainRequest?.maxResponseBytes === maxResponseBytes
|
|
322
|
+
? this.chainRequest
|
|
323
|
+
: undefined;
|
|
324
|
+
if (!request) {
|
|
325
|
+
const controller = new AbortController();
|
|
326
|
+
const generation = ++this.chainGeneration;
|
|
327
|
+
// Each subscriber owns its deadline. A short first subscriber must not
|
|
328
|
+
// impose that deadline on later subscribers sharing the wire response.
|
|
329
|
+
const promise = this.read('eth_chainId', [], {
|
|
330
|
+
signal: controller.signal,
|
|
331
|
+
timeoutMs: 30000,
|
|
332
|
+
maxResponseBytes,
|
|
333
|
+
}).then((value) => {
|
|
334
|
+
if (typeof value !== 'string' ||
|
|
335
|
+
!/^0x(?:0|[1-9a-f][0-9a-f]*)$/i.test(value))
|
|
336
|
+
throw new RpcResponseIntegrityError('Invalid chain ID', false);
|
|
337
|
+
if (generation === this.chainGeneration && !controller.signal.aborted)
|
|
338
|
+
this.chainCache = { value, expires: Date.now() + 30000 };
|
|
339
|
+
return value;
|
|
340
|
+
});
|
|
341
|
+
request = {
|
|
342
|
+
promise,
|
|
343
|
+
controller,
|
|
344
|
+
maxResponseBytes,
|
|
345
|
+
subscribers: 0,
|
|
346
|
+
settled: false,
|
|
347
|
+
};
|
|
348
|
+
const captured = request;
|
|
349
|
+
void promise
|
|
350
|
+
.finally(() => {
|
|
351
|
+
captured.settled = true;
|
|
352
|
+
if (this.chainRequest === captured)
|
|
353
|
+
this.chainRequest = undefined;
|
|
354
|
+
})
|
|
355
|
+
.catch(() => undefined);
|
|
356
|
+
if (!options.fresh)
|
|
357
|
+
this.chainRequest = request;
|
|
358
|
+
}
|
|
359
|
+
const subscribed = request;
|
|
360
|
+
subscribed.subscribers++;
|
|
361
|
+
return new Promise((resolve, reject) => {
|
|
362
|
+
let finished = false;
|
|
363
|
+
const finish = (error, value) => {
|
|
364
|
+
if (finished)
|
|
365
|
+
return;
|
|
366
|
+
finished = true;
|
|
367
|
+
clearTimeout(timer);
|
|
368
|
+
options.signal?.removeEventListener('abort', cancel);
|
|
369
|
+
subscribed.subscribers--;
|
|
370
|
+
if (!subscribed.subscribers && !subscribed.settled) {
|
|
371
|
+
if (this.chainRequest === subscribed)
|
|
372
|
+
this.chainRequest = undefined;
|
|
373
|
+
subscribed.controller.abort();
|
|
374
|
+
}
|
|
375
|
+
if (error !== undefined)
|
|
376
|
+
reject(error);
|
|
377
|
+
else
|
|
378
|
+
resolve(value);
|
|
379
|
+
};
|
|
380
|
+
const cancel = () => finish(aborted(options.signal));
|
|
381
|
+
options.signal?.addEventListener('abort', cancel, { once: true });
|
|
382
|
+
const timer = setTimeout(() => finish(Object.assign(new Error('RPC read deadline exceeded'), {
|
|
383
|
+
name: 'AbortError',
|
|
384
|
+
})), timeout);
|
|
385
|
+
subscribed.promise.then((value) => finish(undefined, value), (error) => finish(error));
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
//# sourceMappingURL=rpc-read-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-read-client.js","sourceRoot":"","sources":["../../src/rpc-read-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// A stale response must never be interpreted as the result of another RPC.
|
|
2
|
+
// Keep the sentinel in the message for callers that serialize errors as text.
|
|
3
|
+
export class RpcResponseIntegrityError extends Error {
|
|
4
|
+
constructor(message = 'JSON-RPC response does not match its request', retryable = true) {
|
|
5
|
+
super(`[SYSWEB3_RPC_RESPONSE_INVALID] ${message}`);
|
|
6
|
+
this.retryable = retryable;
|
|
7
|
+
this.code = 'SYSWEB3_RPC_RESPONSE_INVALID';
|
|
8
|
+
this.name = 'RpcResponseIntegrityError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
// Only these standard, side-effect-free reads may recover from a stale cache
|
|
12
|
+
// entry. Never infer retry eligibility from an RPC method prefix.
|
|
13
|
+
const RECOVERABLE_READ_METHODS = new Set([
|
|
14
|
+
'eth_chainId',
|
|
15
|
+
'net_version',
|
|
16
|
+
'web3_clientVersion',
|
|
17
|
+
'eth_blockNumber',
|
|
18
|
+
'eth_syncing',
|
|
19
|
+
'eth_getBalance',
|
|
20
|
+
'eth_getTransactionCount',
|
|
21
|
+
'eth_getCode',
|
|
22
|
+
'eth_getStorageAt',
|
|
23
|
+
'eth_getProof',
|
|
24
|
+
'eth_call',
|
|
25
|
+
'eth_estimateGas',
|
|
26
|
+
'eth_createAccessList',
|
|
27
|
+
'eth_gasPrice',
|
|
28
|
+
'eth_maxPriorityFeePerGas',
|
|
29
|
+
'eth_feeHistory',
|
|
30
|
+
'eth_getBlockByNumber',
|
|
31
|
+
'eth_getBlockByHash',
|
|
32
|
+
'eth_getBlockTransactionCountByNumber',
|
|
33
|
+
'eth_getBlockTransactionCountByHash',
|
|
34
|
+
'eth_getTransactionByHash',
|
|
35
|
+
'eth_getTransactionByBlockNumberAndIndex',
|
|
36
|
+
'eth_getTransactionByBlockHashAndIndex',
|
|
37
|
+
'eth_getTransactionReceipt',
|
|
38
|
+
'eth_getLogs',
|
|
39
|
+
]);
|
|
40
|
+
export const isReadOnlyRpcMethod = (method) => RECOVERABLE_READ_METHODS.has(method);
|
|
41
|
+
let rpcRecoveryNonce = 0;
|
|
42
|
+
// Shared across provider instances and seeded anew on process restart. These
|
|
43
|
+
// numeric correlation IDs are not authorization tokens.
|
|
44
|
+
let nextRpcWireId = Math.floor(Math.random() * 2 ** 51);
|
|
45
|
+
const reserveRpcWireId = () => {
|
|
46
|
+
const id = ++nextRpcWireId;
|
|
47
|
+
if (!Number.isSafeInteger(id)) {
|
|
48
|
+
throw new RpcResponseIntegrityError('RPC request ID range exhausted', false);
|
|
49
|
+
}
|
|
50
|
+
return id;
|
|
51
|
+
};
|
|
52
|
+
const recoveryUrl = (original) => {
|
|
53
|
+
const url = new URL(original);
|
|
54
|
+
const token = `${Date.now()}-${++rpcRecoveryNonce}-${Math.random()
|
|
55
|
+
.toString(36)
|
|
56
|
+
.slice(2)}`;
|
|
57
|
+
// Append without reserializing existing query values (including auth data).
|
|
58
|
+
url.search += `${url.search ? '&' : '?'}sysweb3_rpc_request=${token}`;
|
|
59
|
+
return url.toString();
|
|
60
|
+
};
|
|
61
|
+
function validateRpcResponses(json, requests, batch) {
|
|
62
|
+
if (batch ? !Array.isArray(json) : Array.isArray(json)) {
|
|
63
|
+
throw new RpcResponseIntegrityError();
|
|
64
|
+
}
|
|
65
|
+
const responses = batch ? json : [json];
|
|
66
|
+
if (responses.length !== requests.length) {
|
|
67
|
+
throw new RpcResponseIntegrityError();
|
|
68
|
+
}
|
|
69
|
+
const expectedIds = new Set(requests.map((request) => request.id));
|
|
70
|
+
const byId = new Map();
|
|
71
|
+
for (const response of responses) {
|
|
72
|
+
if (!response ||
|
|
73
|
+
typeof response !== 'object' ||
|
|
74
|
+
Array.isArray(response) ||
|
|
75
|
+
typeof response.id !== 'number' ||
|
|
76
|
+
!expectedIds.has(response.id) ||
|
|
77
|
+
byId.has(response.id)) {
|
|
78
|
+
throw new RpcResponseIntegrityError();
|
|
79
|
+
}
|
|
80
|
+
const hasResult = Object.prototype.hasOwnProperty.call(response, 'result');
|
|
81
|
+
const hasError = Object.prototype.hasOwnProperty.call(response, 'error');
|
|
82
|
+
if (response.jsonrpc !== '2.0' ||
|
|
83
|
+
hasResult === hasError ||
|
|
84
|
+
(hasError &&
|
|
85
|
+
(!response.error ||
|
|
86
|
+
typeof response.error.message !== 'string' ||
|
|
87
|
+
!Number.isSafeInteger(response.error.code)))) {
|
|
88
|
+
throw new RpcResponseIntegrityError('Invalid JSON-RPC response envelope', false);
|
|
89
|
+
}
|
|
90
|
+
byId.set(response.id, response);
|
|
91
|
+
}
|
|
92
|
+
return requests.map((request) => byId.get(request.id));
|
|
93
|
+
}
|
|
94
|
+
/** Correlate exact wire responses and recover one stale read response. */
|
|
95
|
+
export async function requestJsonRpc(url, inputs, batch, signal, transport, recoverResponse = true) {
|
|
96
|
+
const canRecover = recoverResponse &&
|
|
97
|
+
inputs.every(({ method }) => RECOVERABLE_READ_METHODS.has(method));
|
|
98
|
+
const serialized = JSON.stringify(inputs);
|
|
99
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
100
|
+
if (signal.aborted)
|
|
101
|
+
throw signal.reason || new Error('RPC request aborted');
|
|
102
|
+
const source = JSON.parse(serialized);
|
|
103
|
+
const requests = source.map(({ method, params }) => ({
|
|
104
|
+
jsonrpc: '2.0',
|
|
105
|
+
method,
|
|
106
|
+
params,
|
|
107
|
+
id: reserveRpcWireId(),
|
|
108
|
+
}));
|
|
109
|
+
const json = await transport(attempt === 0 ? url : recoveryUrl(url), JSON.stringify(batch ? requests : requests[0]), signal).catch((error) => {
|
|
110
|
+
if (attempt === 0 ||
|
|
111
|
+
error instanceof RpcResponseIntegrityError ||
|
|
112
|
+
signal.aborted ||
|
|
113
|
+
error?.name === 'AbortError')
|
|
114
|
+
throw error;
|
|
115
|
+
throw new RpcResponseIntegrityError('JSON-RPC response recovery failed', false);
|
|
116
|
+
});
|
|
117
|
+
try {
|
|
118
|
+
return validateRpcResponses(json, requests, batch);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (!(error instanceof RpcResponseIntegrityError) ||
|
|
122
|
+
!error.retryable ||
|
|
123
|
+
attempt !== 0 ||
|
|
124
|
+
!canRecover)
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
throw new RpcResponseIntegrityError();
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=rpc-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-transport.js","sourceRoot":"","sources":["../../src/rpc-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import { excludedOutpointIds, filterExcludedUtxos, assertNoExcludedInputs, } fro
|
|
|
8
8
|
import { fetchOwnedBlockbookAccount } from '../utils/owned-blockbook-account';
|
|
9
9
|
import { PsbtUtils } from '../utils/psbt';
|
|
10
10
|
import { assertPsbtAccountScope, } from '../utils/psbt-account-scope';
|
|
11
|
+
import { utxoFeeRateUnits } from '../utils/utxo-fee-rate';
|
|
11
12
|
export const createHardwareSignerUnavailableError = (hardware) => Object.assign(new Error(`${hardware} signer is unavailable in this host`), {
|
|
12
13
|
code: 'HARDWARE_SIGNER_UNAVAILABLE',
|
|
13
14
|
});
|
|
@@ -602,7 +603,7 @@ export class SyscoinTransactionsCore {
|
|
|
602
603
|
// Blockbook returns coins per kB; after division by 1024, some testnets
|
|
603
604
|
// can yield < 1 sat/vB (e.g., 0.9765625). Round up and clamp to 1 to
|
|
604
605
|
// avoid zero-fee transactions due to truncation when converting to BN.
|
|
605
|
-
const satPerByte =
|
|
606
|
+
const satPerByte = utxoFeeRateUnits(actualFeeRate);
|
|
606
607
|
const feeRateBN = new syscoinjs.utils.BN(satPerByte);
|
|
607
608
|
// Step 2: Create unsigned PSBT
|
|
608
609
|
const result = await this.createUnsignedPSBT({
|