@w3lib/solana-batch-call 0.0.0-stage → 0.2.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 +35 -0
- package/LICENSE +21 -0
- package/README.md +270 -2
- package/dist/address.d.ts +20 -0
- package/dist/address.d.ts.map +1 -0
- package/dist/address.js +120 -0
- package/dist/address.js.map +1 -0
- package/dist/client.d.ts +190 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +971 -0
- package/dist/client.js.map +1 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +35 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +84 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +237 -0
- package/dist/layout.js.map +1 -0
- package/dist/rpc.d.ts +115 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +458 -0
- package/dist/rpc.js.map +1 -0
- package/dist/shortcuts.d.ts +93 -0
- package/dist/shortcuts.d.ts.map +1 -0
- package/dist/shortcuts.js +281 -0
- package/dist/shortcuts.js.map +1 -0
- package/dist/source.d.ts +35 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +124 -0
- package/dist/source.js.map +1 -0
- package/dist/types.d.ts +155 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -4
- package/src/address.ts +134 -0
- package/src/client.ts +1298 -0
- package/src/constants.ts +41 -0
- package/src/index.ts +98 -0
- package/src/layout.ts +320 -0
- package/src/rpc.ts +549 -0
- package/src/shortcuts.ts +367 -0
- package/src/source.ts +149 -0
- package/src/types.ts +164 -0
package/dist/rpc.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/** 最小的 JSON-RPC 传输接口:可以传入自己的实现(如包一层 @solana/kit 的 rpc) */
|
|
2
|
+
export interface RpcTransport {
|
|
3
|
+
request<T = unknown>(method: string, params?: readonly unknown[]): Promise<T>;
|
|
4
|
+
/** 节点名称,用于 AllNodesFailedError / onRequest 里标识节点;不传时自定义传输显示为 'custom' */
|
|
5
|
+
readonly label?: string;
|
|
6
|
+
}
|
|
7
|
+
/** 节点返回的 JSON-RPC 错误 */
|
|
8
|
+
export declare class RpcError extends Error {
|
|
9
|
+
readonly code: number | undefined;
|
|
10
|
+
readonly data: unknown;
|
|
11
|
+
/** 是否是节点自身的限制(限频、需要 API Key、禁止访问等),换节点可能成功 */
|
|
12
|
+
readonly nodeFault: boolean;
|
|
13
|
+
constructor(message: string, code?: number, data?: unknown);
|
|
14
|
+
}
|
|
15
|
+
/** HTTP 层错误(非 2xx、网络错误、超时) */
|
|
16
|
+
export declare class HttpError extends Error {
|
|
17
|
+
readonly status: number | undefined;
|
|
18
|
+
/** 请求超时(HttpRpcOptions.timeout) */
|
|
19
|
+
readonly timeout: boolean;
|
|
20
|
+
constructor(message: string, status?: number, timeout?: boolean);
|
|
21
|
+
}
|
|
22
|
+
/** JSON-RPC 错误码:节点高度还没到请求的 minContextSlot */
|
|
23
|
+
export declare const MIN_CONTEXT_SLOT_NOT_REACHED = -32016;
|
|
24
|
+
/** 是否是请求超时(HttpRpc 的超时,或自定义传输抛出的 TimeoutError) */
|
|
25
|
+
export declare function isTimeout(err: unknown): boolean;
|
|
26
|
+
/** 是否是“节点高度没到 minContextSlot”(所有节点都落后时也算) */
|
|
27
|
+
export declare function isBehind(err: unknown): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* 多节点时所有节点都失败(都是节点问题)。errors 是各节点的错误,按尝试顺序;
|
|
30
|
+
* node 是节点名称(URL 只保留 host,不会带出 path / query 里的 API Key)
|
|
31
|
+
*/
|
|
32
|
+
export declare class AllNodesFailedError extends Error {
|
|
33
|
+
readonly errors: ReadonlyArray<{
|
|
34
|
+
node: string;
|
|
35
|
+
error: unknown;
|
|
36
|
+
}>;
|
|
37
|
+
constructor(errors: ReadonlyArray<{
|
|
38
|
+
node: string;
|
|
39
|
+
error: unknown;
|
|
40
|
+
}>);
|
|
41
|
+
}
|
|
42
|
+
/** 是否是节点问题(应换节点重试):除了确定性的 JSON-RPC 错误(如参数错误),其余都算(包括 AllNodesFailedError) */
|
|
43
|
+
export declare function isNodeFault(err: unknown): boolean;
|
|
44
|
+
export interface HttpRpcOptions {
|
|
45
|
+
/** 单次 HTTP 请求超时(毫秒),<= 0 不限制。默认 10000 */
|
|
46
|
+
timeout?: number;
|
|
47
|
+
headers?: Record<string, string>;
|
|
48
|
+
/** 一个 HTTP 批量请求最多包含的调用数。默认 20 */
|
|
49
|
+
maxBatchSize?: number;
|
|
50
|
+
/** 是否合并成 JSON-RPC 批量请求。默认 true;节点不支持时会自动关闭 */
|
|
51
|
+
batch?: boolean;
|
|
52
|
+
/** 收集窗口(毫秒),窗口内的调用合并成一个 HTTP 请求。默认 0(同一 tick) */
|
|
53
|
+
batchWait?: number;
|
|
54
|
+
/** 遇到 HTTP 429 时的重试次数(指数退避,从 500ms 开始)。默认 2 */
|
|
55
|
+
retries?: number;
|
|
56
|
+
/** 自定义 fetch(如需要代理时) */
|
|
57
|
+
fetch?: typeof fetch;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 基于 fetch 的 JSON-RPC 传输:同一收集窗口内的调用合并成一个 JSON-RPC 批量请求。
|
|
61
|
+
* 节点不支持批量(返回非数组)或限制批量大小(如 drpc 免费档最多 3 条)时自动降级。
|
|
62
|
+
*/
|
|
63
|
+
export declare class HttpRpc implements RpcTransport {
|
|
64
|
+
#private;
|
|
65
|
+
readonly url: string;
|
|
66
|
+
constructor(url: string, options?: HttpRpcOptions);
|
|
67
|
+
request<T = unknown>(method: string, params?: readonly unknown[]): Promise<T>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* onRequest 的事件:每个 JSON-RPC 调用对每个节点的每次尝试一条(合并成批量 HTTP 请求时,批里每个调用各一条,
|
|
71
|
+
* ms 是该调用从发出到返回的时间;HttpRpc 内部的 429 退避重试算在同一条里)
|
|
72
|
+
*/
|
|
73
|
+
export interface RequestEvent {
|
|
74
|
+
/** 节点名称:URL 的 host,自定义传输的 label(没有时为 'custom') */
|
|
75
|
+
node: string;
|
|
76
|
+
method: string;
|
|
77
|
+
ms: number;
|
|
78
|
+
ok: boolean;
|
|
79
|
+
/** 失败时的错误 */
|
|
80
|
+
error?: unknown;
|
|
81
|
+
/** 本次调用按故障切换顺序尝试的第几个节点(0 起);大于 0 说明换过节点 */
|
|
82
|
+
attempt: number;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 监听所有客户端发出的 JSON-RPC 调用(节点、方法、耗时、成功与否、第几次尝试),用于统计和排查。返回取消监听的函数。
|
|
86
|
+
*
|
|
87
|
+
* ```ts
|
|
88
|
+
* const stop = onRequest((e) => console.log(e.node, e.method, e.ms, e.ok, e.attempt))
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function onRequest(listener: (event: RequestEvent) => void): () => void;
|
|
92
|
+
/** 节点名称:优先用传输自带的 label;HttpRpc 取 URL 的 host(不带 path / query,避免泄露 API Key) */
|
|
93
|
+
export declare function nodeLabel(node: RpcTransport): string;
|
|
94
|
+
/** 测试用:清空节点健康状态 */
|
|
95
|
+
export declare function resetNodeHealth(): void;
|
|
96
|
+
export interface FallbackOptions {
|
|
97
|
+
/** 出错节点的冷却时间(毫秒),期间排到最后。默认 30000 */
|
|
98
|
+
cooldown?: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 多节点故障切换:按顺序使用,节点问题(网络、超时、限频、需要 Key、403、高度不够等)换下一个;
|
|
102
|
+
* 参数错误等确定性错误直接抛出。单个节点也用它包一层(统一 onRequest 事件),此时失败抛原始错误。
|
|
103
|
+
*
|
|
104
|
+
* - 出错的节点在冷却期内排到最后;健康状态按节点全局共享(URL 相同即同一节点),客户端重建后仍然有效
|
|
105
|
+
* - 超时只换节点、不冷却(大批量查询慢一点很正常),同一节点连续 3 次超时才冷却
|
|
106
|
+
* - 节点高度没到 minContextSlot 只换节点、不冷却(只是这次请求要求的 slot 太新)
|
|
107
|
+
* - 多个节点都失败时抛 AllNodesFailedError,带上每个节点的错误
|
|
108
|
+
*/
|
|
109
|
+
export declare class FallbackRpc implements RpcTransport {
|
|
110
|
+
#private;
|
|
111
|
+
readonly nodes: readonly RpcTransport[];
|
|
112
|
+
constructor(nodes: readonly RpcTransport[], options?: FallbackOptions);
|
|
113
|
+
request<T = unknown>(method: string, params?: readonly unknown[]): Promise<T>;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"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"}
|
package/dist/rpc.js
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
/** 节点返回的 JSON-RPC 错误 */
|
|
2
|
+
export class RpcError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
data;
|
|
5
|
+
/** 是否是节点自身的限制(限频、需要 API Key、禁止访问等),换节点可能成功 */
|
|
6
|
+
nodeFault;
|
|
7
|
+
constructor(message, code, data) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'RpcError';
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.data = data;
|
|
12
|
+
this.nodeFault =
|
|
13
|
+
code === 403 ||
|
|
14
|
+
code === 429 ||
|
|
15
|
+
code === -32005 ||
|
|
16
|
+
// 节点高度没到 minContextSlot:换节点可能成功
|
|
17
|
+
code === MIN_CONTEXT_SLOT_NOT_REACHED ||
|
|
18
|
+
/minimum context slot/i.test(message) ||
|
|
19
|
+
/forbidden|blocked|personal token|api.?key|rate.?limit|too many|not allowed|unauthori[sz]ed|limit exceeded|disabled|not available|not supported/i.test(message);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** HTTP 层错误(非 2xx、网络错误、超时) */
|
|
23
|
+
export class HttpError extends Error {
|
|
24
|
+
status;
|
|
25
|
+
/** 请求超时(HttpRpcOptions.timeout) */
|
|
26
|
+
timeout;
|
|
27
|
+
constructor(message, status, timeout = false) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = 'HttpError';
|
|
30
|
+
this.status = status;
|
|
31
|
+
this.timeout = timeout;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** JSON-RPC 错误码:节点高度还没到请求的 minContextSlot */
|
|
35
|
+
export const MIN_CONTEXT_SLOT_NOT_REACHED = -32016;
|
|
36
|
+
/** 是否是请求超时(HttpRpc 的超时,或自定义传输抛出的 TimeoutError) */
|
|
37
|
+
export function isTimeout(err) {
|
|
38
|
+
return (err instanceof HttpError && err.timeout) || err?.name === 'TimeoutError';
|
|
39
|
+
}
|
|
40
|
+
/** 是否是“节点高度没到 minContextSlot”(所有节点都落后时也算) */
|
|
41
|
+
export function isBehind(err) {
|
|
42
|
+
if (err instanceof AllNodesFailedError) {
|
|
43
|
+
return err.errors.length > 0 && err.errors.every((e) => isBehind(e.error));
|
|
44
|
+
}
|
|
45
|
+
return err instanceof RpcError && (err.code === MIN_CONTEXT_SLOT_NOT_REACHED || /minimum context slot/i.test(err.message));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 多节点时所有节点都失败(都是节点问题)。errors 是各节点的错误,按尝试顺序;
|
|
49
|
+
* node 是节点名称(URL 只保留 host,不会带出 path / query 里的 API Key)
|
|
50
|
+
*/
|
|
51
|
+
export class AllNodesFailedError extends Error {
|
|
52
|
+
errors;
|
|
53
|
+
constructor(errors) {
|
|
54
|
+
super(`All RPC nodes failed: ${errors.map((e) => `${e.node}: ${errorMessage(e.error)}`).join(' | ')}`, { cause: errors[errors.length - 1]?.error });
|
|
55
|
+
this.name = 'AllNodesFailedError';
|
|
56
|
+
this.errors = errors;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function errorMessage(err) {
|
|
60
|
+
return err instanceof Error ? err.message : String(err);
|
|
61
|
+
}
|
|
62
|
+
/** 是否是节点问题(应换节点重试):除了确定性的 JSON-RPC 错误(如参数错误),其余都算(包括 AllNodesFailedError) */
|
|
63
|
+
export function isNodeFault(err) {
|
|
64
|
+
if (err instanceof RpcError) {
|
|
65
|
+
return err.nodeFault;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
let nextId = 1;
|
|
70
|
+
/** 批量请求被拒绝、可以降级为逐条请求的 HTTP 状态 */
|
|
71
|
+
const BATCH_REJECTED_STATUS = new Set([400, 404, 405, 415, 422]);
|
|
72
|
+
function isBatchLimitError(message) {
|
|
73
|
+
return !!message && /batch/i.test(message) && /more than \d+|too (large|many|big)|not (allowed|supported)|exceed/i.test(message);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 基于 fetch 的 JSON-RPC 传输:同一收集窗口内的调用合并成一个 JSON-RPC 批量请求。
|
|
77
|
+
* 节点不支持批量(返回非数组)或限制批量大小(如 drpc 免费档最多 3 条)时自动降级。
|
|
78
|
+
*/
|
|
79
|
+
export class HttpRpc {
|
|
80
|
+
url;
|
|
81
|
+
/** 报错信息里用的地址:只保留 origin,不带 path / query(常含 API Key) */
|
|
82
|
+
#safeUrl;
|
|
83
|
+
#timeout;
|
|
84
|
+
#headers;
|
|
85
|
+
#batchWait;
|
|
86
|
+
#retries;
|
|
87
|
+
#fetch;
|
|
88
|
+
#maxBatchSize;
|
|
89
|
+
#batch;
|
|
90
|
+
#queue = [];
|
|
91
|
+
#timer = null;
|
|
92
|
+
constructor(url, options = {}) {
|
|
93
|
+
this.url = url;
|
|
94
|
+
this.#safeUrl = safeOrigin(url);
|
|
95
|
+
this.#timeout = options.timeout ?? 10_000;
|
|
96
|
+
this.#headers = { 'content-type': 'application/json', ...options.headers };
|
|
97
|
+
this.#maxBatchSize = Math.max(1, options.maxBatchSize ?? 20);
|
|
98
|
+
this.#batch = options.batch ?? true;
|
|
99
|
+
this.#batchWait = options.batchWait ?? 0;
|
|
100
|
+
this.#retries = Math.max(0, options.retries ?? 2);
|
|
101
|
+
this.#fetch = options.fetch ?? ((...args) => fetch(...args));
|
|
102
|
+
}
|
|
103
|
+
request(method, params = []) {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
this.#queue.push({ method, params, resolve: resolve, reject });
|
|
106
|
+
if (!this.#batch || this.#queue.length >= this.#maxBatchSize) {
|
|
107
|
+
this.#flush();
|
|
108
|
+
}
|
|
109
|
+
else if (!this.#timer) {
|
|
110
|
+
this.#timer = setTimeout(() => this.#flush(), this.#batchWait);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
#flush() {
|
|
115
|
+
if (this.#timer) {
|
|
116
|
+
clearTimeout(this.#timer);
|
|
117
|
+
this.#timer = null;
|
|
118
|
+
}
|
|
119
|
+
const queue = this.#queue;
|
|
120
|
+
this.#queue = [];
|
|
121
|
+
for (let i = 0; i < queue.length; i += this.#maxBatchSize) {
|
|
122
|
+
void this.#dispatch(queue.slice(i, i + this.#maxBatchSize));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async #dispatch(items) {
|
|
126
|
+
if (items.length === 1 || !this.#batch) {
|
|
127
|
+
await Promise.all(items.map((item) => this.#single(item)));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const ids = items.map(() => nextId++);
|
|
131
|
+
let body;
|
|
132
|
+
try {
|
|
133
|
+
body = await this.#post(items.map((item, i) => ({ jsonrpc: '2.0', id: ids[i], method: item.method, params: item.params })));
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err instanceof HttpError && err.status === 413 && items.length > 1) {
|
|
137
|
+
// 请求体太大:批量减半后重发
|
|
138
|
+
this.#maxBatchSize = Math.max(1, Math.floor(items.length / 2));
|
|
139
|
+
await this.#redispatch(items);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
// 400 / 404 / 405 / 415 / 422 等:节点多半不接受批量请求,降级为逐条请求
|
|
143
|
+
// (401 / 403 / 429 / 5xx 是鉴权、限频或节点本身的问题,降级没有用,原样报错)
|
|
144
|
+
if (err instanceof HttpError && err.status !== undefined && BATCH_REJECTED_STATUS.has(err.status)) {
|
|
145
|
+
this.#disableBatch();
|
|
146
|
+
await Promise.all(items.map((item) => this.#single(item)));
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
items.forEach((item) => item.reject(err));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (!Array.isArray(body)) {
|
|
153
|
+
const error = body?.error;
|
|
154
|
+
const rpcError = new RpcError(error?.message ?? 'Invalid JSON-RPC batch response', error?.code, error?.data);
|
|
155
|
+
// 限频 / 鉴权等节点问题:原样报错,不降级(降级成逐条请求只会让限频更严重)
|
|
156
|
+
if (rpcError.nodeFault) {
|
|
157
|
+
items.forEach((item) => item.reject(rpcError));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// 其他(如 -32600 invalid request):节点不支持批量,降级为逐条请求
|
|
161
|
+
this.#disableBatch();
|
|
162
|
+
await Promise.all(items.map((item) => this.#single(item)));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const byId = new Map(body.map((res) => [res.id, res]));
|
|
166
|
+
const limited = body.find((res) => isBatchLimitError(res.error?.message));
|
|
167
|
+
if (limited) {
|
|
168
|
+
// 如 “Batch of more than 3 requests are not allowed”:按限制缩小批量后重发;
|
|
169
|
+
// 限制不小于当前批量(节点的上限判断有偏差)或解析不出数字时,降级为逐条请求,避免无限重发
|
|
170
|
+
const max = Number(/more than (\d+)/i.exec(limited.error?.message ?? '')?.[1]);
|
|
171
|
+
if (Number.isFinite(max) && max > 1 && max < items.length) {
|
|
172
|
+
this.#maxBatchSize = max;
|
|
173
|
+
await this.#redispatch(items);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
this.#disableBatch();
|
|
177
|
+
await Promise.all(items.map((item) => this.#single(item)));
|
|
178
|
+
}
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// 批量里个别调用被限频(JSON-RPC 429):只把这些调用退避后单独重试
|
|
182
|
+
const limitedItems = [];
|
|
183
|
+
items.forEach((item, i) => {
|
|
184
|
+
const response = byId.get(ids[i]);
|
|
185
|
+
if (response?.error?.code === 429 && this.#retries > 0) {
|
|
186
|
+
limitedItems.push(item);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
settle(item, response);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
if (limitedItems.length) {
|
|
193
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
194
|
+
await Promise.all(limitedItems.map((item) => this.#single(item)));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** 按当前的 maxBatchSize 重新分批发送(每批都比原来小,不会无限循环) */
|
|
198
|
+
async #redispatch(items) {
|
|
199
|
+
const size = this.#maxBatchSize;
|
|
200
|
+
const chunks = [];
|
|
201
|
+
for (let i = 0; i < items.length; i += size) {
|
|
202
|
+
chunks.push(items.slice(i, i + size));
|
|
203
|
+
}
|
|
204
|
+
await Promise.all(chunks.map((chunk) => this.#dispatch(chunk)));
|
|
205
|
+
}
|
|
206
|
+
async #single(item) {
|
|
207
|
+
try {
|
|
208
|
+
const body = (await this.#post({ jsonrpc: '2.0', id: nextId++, method: item.method, params: item.params }));
|
|
209
|
+
settle(item, body);
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
item.reject(err);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
#disableBatch() {
|
|
216
|
+
this.#batch = false;
|
|
217
|
+
}
|
|
218
|
+
async #post(payload) {
|
|
219
|
+
for (let attempt = 0;; attempt++) {
|
|
220
|
+
let response;
|
|
221
|
+
try {
|
|
222
|
+
response = await this.#fetch(this.url, {
|
|
223
|
+
method: 'POST',
|
|
224
|
+
headers: this.#headers,
|
|
225
|
+
body: JSON.stringify(payload),
|
|
226
|
+
signal: this.#timeout > 0 && Number.isFinite(this.#timeout) ? AbortSignal.timeout(this.#timeout) : undefined,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
// AbortSignal.timeout 触发时是 TimeoutError(DOMException)
|
|
231
|
+
const timeout = err?.name === 'TimeoutError';
|
|
232
|
+
throw new HttpError(`Request to ${this.#safeUrl} failed: ${err?.message ?? err}`, undefined, timeout);
|
|
233
|
+
}
|
|
234
|
+
if (response.status === 429 && attempt < this.#retries) {
|
|
235
|
+
await new Promise((r) => setTimeout(r, 500 * 2 ** attempt));
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const text = await response.text();
|
|
239
|
+
let body;
|
|
240
|
+
try {
|
|
241
|
+
body = parseJson(text);
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
throw new HttpError(`Invalid JSON from ${this.#safeUrl} (HTTP ${response.status})`, response.status);
|
|
245
|
+
}
|
|
246
|
+
// 非 2xx 但返回了 JSON-RPC 结构(如 403 Access forbidden、drpc 的 500 + 批量错误数组):交给上层解析
|
|
247
|
+
if (!response.ok && !Array.isArray(body) && !body?.error) {
|
|
248
|
+
throw new HttpError(`HTTP ${response.status} from ${this.#safeUrl}`, response.status);
|
|
249
|
+
}
|
|
250
|
+
// 有的节点限频时返回 HTTP 200 + JSON-RPC 错误码 429:同样退避重试
|
|
251
|
+
if (attempt < this.#retries && isRateLimited(body)) {
|
|
252
|
+
await new Promise((r) => setTimeout(r, 500 * 2 ** attempt));
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
return body;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// lamports 等 u64 以 JSON 数字返回,超过 2^53(约 900 万 SOL)时 JSON.parse 会丢精度:
|
|
260
|
+
// 支持 JSON.parse source text access 的环境(Node 21+、新版浏览器)直接取原文;否则先把超长整数改成字符串再解析
|
|
261
|
+
let sourceAccess;
|
|
262
|
+
function parseJson(text) {
|
|
263
|
+
sourceAccess ??= (() => {
|
|
264
|
+
let supported = false;
|
|
265
|
+
JSON.parse('1', (_key, value, context) => {
|
|
266
|
+
supported = typeof context?.source === 'string';
|
|
267
|
+
return value;
|
|
268
|
+
});
|
|
269
|
+
return supported;
|
|
270
|
+
})();
|
|
271
|
+
if (sourceAccess) {
|
|
272
|
+
return JSON.parse(text, (_key, value, context) => typeof value === 'number' && !Number.isSafeInteger(value) && Number.isInteger(value) && context?.source ? context.source : value);
|
|
273
|
+
}
|
|
274
|
+
return JSON.parse(text.replace(/([:[,]\s*)(-?\d{16,})(?=\s*[,}\]])/g, '$1"$2"'));
|
|
275
|
+
}
|
|
276
|
+
function safeOrigin(url) {
|
|
277
|
+
try {
|
|
278
|
+
return new URL(url).origin;
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
return 'invalid URL';
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function isRateLimited(body) {
|
|
285
|
+
const responses = (Array.isArray(body) ? body : [body]);
|
|
286
|
+
return responses.length > 0 && responses.every((res) => res?.error?.code === 429);
|
|
287
|
+
}
|
|
288
|
+
function settle(item, response) {
|
|
289
|
+
if (!response) {
|
|
290
|
+
item.reject(new HttpError('Missing response in JSON-RPC batch'));
|
|
291
|
+
}
|
|
292
|
+
else if (response.error) {
|
|
293
|
+
item.reject(new RpcError(response.error.message ?? 'JSON-RPC error', response.error.code, response.error.data));
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
item.resolve(response.result);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const requestListeners = new Set();
|
|
300
|
+
/**
|
|
301
|
+
* 监听所有客户端发出的 JSON-RPC 调用(节点、方法、耗时、成功与否、第几次尝试),用于统计和排查。返回取消监听的函数。
|
|
302
|
+
*
|
|
303
|
+
* ```ts
|
|
304
|
+
* const stop = onRequest((e) => console.log(e.node, e.method, e.ms, e.ok, e.attempt))
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
export function onRequest(listener) {
|
|
308
|
+
requestListeners.add(listener);
|
|
309
|
+
return () => {
|
|
310
|
+
requestListeners.delete(listener);
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function emit(event) {
|
|
314
|
+
for (const listener of requestListeners) {
|
|
315
|
+
try {
|
|
316
|
+
listener(event);
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
// 监听函数出错不影响请求
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/** 节点名称:优先用传输自带的 label;HttpRpc 取 URL 的 host(不带 path / query,避免泄露 API Key) */
|
|
324
|
+
export function nodeLabel(node) {
|
|
325
|
+
if (typeof node.label === 'string') {
|
|
326
|
+
return node.label;
|
|
327
|
+
}
|
|
328
|
+
const base = unwrap(node);
|
|
329
|
+
if (base !== node && typeof base.label === 'string') {
|
|
330
|
+
return base.label;
|
|
331
|
+
}
|
|
332
|
+
if (base instanceof HttpRpc) {
|
|
333
|
+
try {
|
|
334
|
+
return new URL(base.url).host || 'custom';
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
return 'custom';
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return 'custom';
|
|
341
|
+
}
|
|
342
|
+
/** 去掉校验层等包装(有 inner 属性的传输),取底层节点 */
|
|
343
|
+
function unwrap(node) {
|
|
344
|
+
let current = node;
|
|
345
|
+
for (let inner = current.inner; inner && typeof inner.request === 'function'; inner = current.inner) {
|
|
346
|
+
current = inner;
|
|
347
|
+
}
|
|
348
|
+
return current;
|
|
349
|
+
}
|
|
350
|
+
// 节点健康状态按节点共享(模块级):客户端重建后,刚出过错的节点仍排在后面。URL 节点按完整 URL,其他按对象
|
|
351
|
+
const healthByUrl = new Map();
|
|
352
|
+
let healthByObject = new WeakMap();
|
|
353
|
+
const MAX_TRACKED_URLS = 1000;
|
|
354
|
+
/** 连续超时这么多次才冷却(单次超时多半只是这次请求慢) */
|
|
355
|
+
const TIMEOUTS_BEFORE_COOLDOWN = 3;
|
|
356
|
+
/** 健康状态的 key:HttpRpc 按完整 URL(不同连接对象共享),其他节点按对象(去掉校验层) */
|
|
357
|
+
function healthKeyOf(node) {
|
|
358
|
+
const base = unwrap(node);
|
|
359
|
+
return base instanceof HttpRpc ? base.url : base;
|
|
360
|
+
}
|
|
361
|
+
/** 每次用时按 key 从全局表里取:表淘汰条目后,各实例仍取到同一个对象 */
|
|
362
|
+
function healthOf(key) {
|
|
363
|
+
if (typeof key === 'string') {
|
|
364
|
+
let health = healthByUrl.get(key);
|
|
365
|
+
if (!health) {
|
|
366
|
+
health = { failedAt: 0, timeouts: 0 };
|
|
367
|
+
healthByUrl.set(key, health);
|
|
368
|
+
if (healthByUrl.size > MAX_TRACKED_URLS) {
|
|
369
|
+
healthByUrl.delete(healthByUrl.keys().next().value);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return health;
|
|
373
|
+
}
|
|
374
|
+
let health = healthByObject.get(key);
|
|
375
|
+
if (!health) {
|
|
376
|
+
health = { failedAt: 0, timeouts: 0 };
|
|
377
|
+
healthByObject.set(key, health);
|
|
378
|
+
}
|
|
379
|
+
return health;
|
|
380
|
+
}
|
|
381
|
+
/** 测试用:清空节点健康状态 */
|
|
382
|
+
export function resetNodeHealth() {
|
|
383
|
+
healthByUrl.clear();
|
|
384
|
+
healthByObject = new WeakMap();
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* 多节点故障切换:按顺序使用,节点问题(网络、超时、限频、需要 Key、403、高度不够等)换下一个;
|
|
388
|
+
* 参数错误等确定性错误直接抛出。单个节点也用它包一层(统一 onRequest 事件),此时失败抛原始错误。
|
|
389
|
+
*
|
|
390
|
+
* - 出错的节点在冷却期内排到最后;健康状态按节点全局共享(URL 相同即同一节点),客户端重建后仍然有效
|
|
391
|
+
* - 超时只换节点、不冷却(大批量查询慢一点很正常),同一节点连续 3 次超时才冷却
|
|
392
|
+
* - 节点高度没到 minContextSlot 只换节点、不冷却(只是这次请求要求的 slot 太新)
|
|
393
|
+
* - 多个节点都失败时抛 AllNodesFailedError,带上每个节点的错误
|
|
394
|
+
*/
|
|
395
|
+
export class FallbackRpc {
|
|
396
|
+
nodes;
|
|
397
|
+
#cooldown;
|
|
398
|
+
/** 节点标识和健康状态的 key 不会变,构造时算好(每次请求只做一次 Map 查找) */
|
|
399
|
+
#labels;
|
|
400
|
+
#healthKeys;
|
|
401
|
+
constructor(nodes, options = {}) {
|
|
402
|
+
if (!nodes.length) {
|
|
403
|
+
throw new Error('FallbackRpc requires at least one node');
|
|
404
|
+
}
|
|
405
|
+
this.nodes = nodes;
|
|
406
|
+
this.#cooldown = options.cooldown ?? 30_000;
|
|
407
|
+
this.#labels = nodes.map(nodeLabel);
|
|
408
|
+
this.#healthKeys = nodes.map(healthKeyOf);
|
|
409
|
+
}
|
|
410
|
+
async request(method, params) {
|
|
411
|
+
const errors = [];
|
|
412
|
+
const order = this.#order();
|
|
413
|
+
for (let attempt = 0; attempt < order.length; attempt++) {
|
|
414
|
+
const index = order[attempt];
|
|
415
|
+
const node = this.nodes[index];
|
|
416
|
+
const label = this.#labels[index];
|
|
417
|
+
const health = healthOf(this.#healthKeys[index]);
|
|
418
|
+
const started = Date.now();
|
|
419
|
+
try {
|
|
420
|
+
const result = await node.request(method, params);
|
|
421
|
+
health.failedAt = 0;
|
|
422
|
+
health.timeouts = 0;
|
|
423
|
+
emit({ node: label, method, ms: Date.now() - started, ok: true, attempt });
|
|
424
|
+
return result;
|
|
425
|
+
}
|
|
426
|
+
catch (err) {
|
|
427
|
+
emit({ node: label, method, ms: Date.now() - started, ok: false, error: err, attempt });
|
|
428
|
+
if (!isNodeFault(err)) {
|
|
429
|
+
throw err;
|
|
430
|
+
}
|
|
431
|
+
if (isTimeout(err)) {
|
|
432
|
+
if (++health.timeouts >= TIMEOUTS_BEFORE_COOLDOWN) {
|
|
433
|
+
health.failedAt = Date.now();
|
|
434
|
+
health.timeouts = 0;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
else if (!isBehind(err)) {
|
|
438
|
+
health.failedAt = Date.now();
|
|
439
|
+
}
|
|
440
|
+
errors.push({ node: label, error: err });
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (this.nodes.length === 1) {
|
|
444
|
+
throw errors[0]?.error;
|
|
445
|
+
}
|
|
446
|
+
throw new AllNodesFailedError(errors);
|
|
447
|
+
}
|
|
448
|
+
#order() {
|
|
449
|
+
const now = Date.now();
|
|
450
|
+
const failedAt = this.#healthKeys.map((key) => healthOf(key).failedAt);
|
|
451
|
+
const healthy = [];
|
|
452
|
+
const cooling = [];
|
|
453
|
+
failedAt.forEach((at, i) => (at && now - at < this.#cooldown ? cooling : healthy).push(i));
|
|
454
|
+
cooling.sort((a, b) => failedAt[a] - failedAt[b]);
|
|
455
|
+
return [...healthy, ...cooling];
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
//# sourceMappingURL=rpc.js.map
|
package/dist/rpc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"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"}
|