@solana/web3.js 2.0.0-experimental.d16acbd → 2.0.0-experimental.d2e0117
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.browser.cjs +81 -9
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +77 -9
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +204 -51
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +77 -9
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +81 -9
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +77 -9
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +4 -4
- package/dist/types/rpc-request-coalescer.d.ts +5 -0
- package/dist/types/rpc-request-deduplication.d.ts +2 -0
- package/package.json +7 -6
package/dist/index.browser.cjs
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
var keys = require('@solana/keys');
|
|
4
4
|
var rpcCore = require('@solana/rpc-core');
|
|
5
5
|
var rpcTransport = require('@solana/rpc-transport');
|
|
6
|
+
var fastStableStringify = require('fast-stable-stringify');
|
|
7
|
+
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var fastStableStringify__default = /*#__PURE__*/_interopDefault(fastStableStringify);
|
|
6
11
|
|
|
7
12
|
// src/index.ts
|
|
8
13
|
|
|
@@ -41,12 +46,76 @@ var DEFAULT_RPC_CONFIG = {
|
|
|
41
46
|
throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);
|
|
42
47
|
}
|
|
43
48
|
};
|
|
49
|
+
|
|
50
|
+
// src/rpc.ts
|
|
44
51
|
function createSolanaRpc(config) {
|
|
45
52
|
return rpcTransport.createJsonRpc({
|
|
46
53
|
...config,
|
|
47
54
|
api: rpcCore.createSolanaRpcApi(DEFAULT_RPC_CONFIG)
|
|
48
55
|
});
|
|
49
56
|
}
|
|
57
|
+
|
|
58
|
+
// src/rpc-request-coalescer.ts
|
|
59
|
+
function getRpcTransportWithRequestCoalescing(transport, getDeduplicationKey) {
|
|
60
|
+
let coalescedRequestsByDeduplicationKey;
|
|
61
|
+
return async function makeCoalescedHttpRequest(config) {
|
|
62
|
+
const { payload, signal } = config;
|
|
63
|
+
const deduplicationKey = getDeduplicationKey(payload);
|
|
64
|
+
if (deduplicationKey === void 0) {
|
|
65
|
+
return await transport(config);
|
|
66
|
+
}
|
|
67
|
+
if (!coalescedRequestsByDeduplicationKey) {
|
|
68
|
+
Promise.resolve().then(() => {
|
|
69
|
+
coalescedRequestsByDeduplicationKey = void 0;
|
|
70
|
+
});
|
|
71
|
+
coalescedRequestsByDeduplicationKey = {};
|
|
72
|
+
}
|
|
73
|
+
if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {
|
|
74
|
+
const abortController = new AbortController();
|
|
75
|
+
coalescedRequestsByDeduplicationKey[deduplicationKey] = {
|
|
76
|
+
abortController,
|
|
77
|
+
numConsumers: 0,
|
|
78
|
+
responsePromise: transport({
|
|
79
|
+
...config,
|
|
80
|
+
signal: abortController.signal
|
|
81
|
+
})
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];
|
|
85
|
+
coalescedRequest.numConsumers++;
|
|
86
|
+
if (signal) {
|
|
87
|
+
const responsePromise = coalescedRequest.responsePromise;
|
|
88
|
+
return await new Promise((resolve, reject) => {
|
|
89
|
+
const handleAbort = (e) => {
|
|
90
|
+
signal.removeEventListener("abort", handleAbort);
|
|
91
|
+
coalescedRequest.numConsumers -= 1;
|
|
92
|
+
if (coalescedRequest.numConsumers === 0) {
|
|
93
|
+
const abortController = coalescedRequest.abortController;
|
|
94
|
+
abortController.abort();
|
|
95
|
+
}
|
|
96
|
+
const abortError = new DOMException(e.target.reason, "AbortError");
|
|
97
|
+
reject(abortError);
|
|
98
|
+
};
|
|
99
|
+
signal.addEventListener("abort", handleAbort);
|
|
100
|
+
responsePromise.then(resolve).finally(() => {
|
|
101
|
+
signal.removeEventListener("abort", handleAbort);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
} else {
|
|
105
|
+
return await coalescedRequest.responsePromise;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function getSolanaRpcPayloadDeduplicationKey(payload) {
|
|
110
|
+
if (payload == null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if ("jsonrpc" in payload && payload.jsonrpc === "2.0" && "method" in payload && "params" in payload) {
|
|
114
|
+
return fastStableStringify__default.default([payload.method, payload.params]);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/rpc-transport.ts
|
|
50
119
|
function normalizeHeaders(headers) {
|
|
51
120
|
const out = {};
|
|
52
121
|
for (const headerName in headers) {
|
|
@@ -55,16 +124,19 @@ function normalizeHeaders(headers) {
|
|
|
55
124
|
return out;
|
|
56
125
|
}
|
|
57
126
|
function createDefaultRpcTransport(config) {
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
127
|
+
return getRpcTransportWithRequestCoalescing(
|
|
128
|
+
rpcTransport.createHttpTransport({
|
|
129
|
+
...config,
|
|
130
|
+
headers: {
|
|
131
|
+
...config.headers ? normalizeHeaders(config.headers) : void 0,
|
|
132
|
+
...{
|
|
133
|
+
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
134
|
+
"solana-client": `js/${"2.0.0-development"}` ?? "UNKNOWN"
|
|
135
|
+
}
|
|
65
136
|
}
|
|
66
|
-
}
|
|
67
|
-
|
|
137
|
+
}),
|
|
138
|
+
getSolanaRpcPayloadDeduplicationKey
|
|
139
|
+
);
|
|
68
140
|
}
|
|
69
141
|
|
|
70
142
|
exports.createDefaultRpcTransport = createDefaultRpcTransport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/rpc.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/rpc-transport.ts"],"names":[],"mappings":";AAAA,cAAc;;;ACAd,SAA2B,0BAA0B;;;ACA9C,IAAM,oCAAN,cAAgD,MAAM;AAAA,EAIzD,YAAY,YAAoB,SAA8B,OAAe;AACzE,UAAM,eAAe,OAAO,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,IAAI,SAAS,QAAQ,CAAC,GAAG,EAAE,KAAK;AAC/F,QAAI,UAAU;AACd,UAAM,YAAY,cAAc;AAChC,UAAM,gBAAgB,cAAc;AACpC,QAAI,aAAa,KAAK,iBAAiB,IAAI;AACvC,gBAAU,cAAc;AAAA,IAC5B,WAAW,aAAa,KAAK,iBAAiB,IAAI;AAC9C,gBAAU,cAAc;AAAA,IAC5B,WAAW,aAAa,KAAK,iBAAiB,IAAI;AAC9C,gBAAU,cAAc;AAAA,IAC5B,OAAO;AACH,gBAAU,cAAc;AAAA,IAC5B;AACA,UAAM,OACF,QAAQ,SAAS,IACX,QACK,MAAM,CAAC,EACP,IAAI,cAAa,OAAO,aAAa,WAAW,IAAI,cAAc,QAAS,EAC3E,KAAK,GAAG,IACb;AACV;AAAA,MACI,OAAO,6BAA6B,0BAC7B,OAAO,cAAc,WAAW,YAAY;AAAA,IAGvD;AACA,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,QAAQ;AAAA,EACjB;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;ACnCO,IAAM,qBAAwE;AAAA,EACjF,kBAAkB,YAAY,SAAS,OAAO;AAC1C,UAAM,IAAI,kCAAkC,YAAY,SAAS,KAAK;AAAA,EAC1E;AACJ;;;AFJA,SAAS,qBAAqB;AAGvB,SAAS,gBAAgB,QAAiF;AAC7G,SAAO,cAAgC;AAAA,IACnC,GAAG;AAAA,IACH,KAAK,mBAAmB,kBAAkB;AAAA,EAC9C,CAAC;AACL;;;AGXA,SAAS,2BAA2B;AAMpC,SAAS,iBACL,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;AAEO,SAAS,0BAA0B,QAAkE;AACxG,SAAO,oBAAoB;AAAA,IACvB,GAAG;AAAA,IACH,SAAS;AAAA,MACL,GAAI,OAAO,UAAU,iBAAiB,OAAO,OAAO,IAAI;AAAA,MACxD,GAAI;AAAA;AAAA,QAEA,iBAAiB,MAAM,yBAAiB;AAAA,MAC5C;AAAA,IACJ;AAAA,EACJ,CAAC;AACL","sourcesContent":["export * from '@solana/keys';\nexport * from './rpc';\nexport * from './rpc-transport';\n","import { SolanaRpcMethods, createSolanaRpcApi } from '@solana/rpc-core';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\n\nimport { createJsonRpc } from '@solana/rpc-transport';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nexport function createSolanaRpc(config: Omit<Parameters<typeof createJsonRpc>[0], 'api'>): Rpc<SolanaRpcMethods> {\n return createJsonRpc<SolanaRpcMethods>({\n ...config,\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n });\n}\n","export class SolanaJsonRpcIntegerOverflowError extends Error {\n readonly methodName: string;\n readonly keyPath: (number | string)[];\n readonly value: bigint;\n constructor(methodName: string, keyPath: (number | string)[], value: bigint) {\n const argPosition = (typeof keyPath[0] === 'number' ? keyPath[0] : parseInt(keyPath[0], 10)) + 1;\n let ordinal = '';\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n ordinal = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n ordinal = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n ordinal = argPosition + 'rd';\n } else {\n ordinal = argPosition + 'th';\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : null;\n super(\n `The ${ordinal} argument to the \\`${methodName}\\` RPC method` +\n `${path ? ` at path \\`${path}\\`` : ''} was \\`${value}\\`. This number is ` +\n 'unsafe for use with the Solana JSON-RPC because it exceeds ' +\n '`Number.MAX_SAFE_INTEGER`.'\n );\n this.keyPath = keyPath;\n this.methodName = methodName;\n this.value = value;\n }\n get name() {\n return 'SolanaJsonRpcIntegerOverflowError';\n }\n}\n","import { createSolanaRpcApi } from '@solana/rpc-core';\nimport { SolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcApi>[0]> = {\n onIntegerOverflow(methodName, keyPath, value) {\n throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","import { createHttpTransport } from '@solana/rpc-transport';\nimport { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers.\n */\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n\nexport function createDefaultRpcTransport(config: Parameters<typeof createHttpTransport>[0]): IRpcTransport {\n return createHttpTransport({\n ...config,\n headers: {\n ...(config.headers ? normalizeHeaders(config.headers) : undefined),\n ...({\n // Keep these headers lowercase so they will override any user-supplied headers above.\n 'solana-client': `js/${__VERSION__}` ?? 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/rpc.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/rpc-transport.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts"],"names":[],"mappings":"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","sourcesContent":["export * from '@solana/keys';\nexport * from './rpc';\nexport * from './rpc-transport';\n","import { createSolanaRpcApi, SolanaRpcMethods } from '@solana/rpc-core';\nimport { createJsonRpc } from '@solana/rpc-transport';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\n\nexport function createSolanaRpc(config: Omit<Parameters<typeof createJsonRpc>[0], 'api'>): Rpc<SolanaRpcMethods> {\n return createJsonRpc<SolanaRpcMethods>({\n ...config,\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n });\n}\n","export class SolanaJsonRpcIntegerOverflowError extends Error {\n readonly methodName: string;\n readonly keyPath: (number | string)[];\n readonly value: bigint;\n constructor(methodName: string, keyPath: (number | string)[], value: bigint) {\n const argPosition = (typeof keyPath[0] === 'number' ? keyPath[0] : parseInt(keyPath[0], 10)) + 1;\n let ordinal = '';\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n ordinal = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n ordinal = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n ordinal = argPosition + 'rd';\n } else {\n ordinal = argPosition + 'th';\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : null;\n super(\n `The ${ordinal} argument to the \\`${methodName}\\` RPC method` +\n `${path ? ` at path \\`${path}\\`` : ''} was \\`${value}\\`. This number is ` +\n 'unsafe for use with the Solana JSON-RPC because it exceeds ' +\n '`Number.MAX_SAFE_INTEGER`.'\n );\n this.keyPath = keyPath;\n this.methodName = methodName;\n this.value = value;\n }\n get name() {\n return 'SolanaJsonRpcIntegerOverflowError';\n }\n}\n","import { createSolanaRpcApi } from '@solana/rpc-core';\n\nimport { SolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcApi>[0]> = {\n onIntegerOverflow(methodName, keyPath, value) {\n throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","import { createHttpTransport } from '@solana/rpc-transport';\nimport { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers.\n */\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n\nexport function createDefaultRpcTransport(config: Parameters<typeof createHttpTransport>[0]): IRpcTransport {\n return getRpcTransportWithRequestCoalescing(\n createHttpTransport({\n ...config,\n headers: {\n ...(config.headers ? normalizeHeaders(config.headers) : undefined),\n ...({\n // Keep these headers lowercase so they will override any user-supplied headers above.\n 'solana-client': `js/${__VERSION__}` ?? 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }),\n getSolanaRpcPayloadDeduplicationKey\n );\n}\n","import { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<unknown>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\nexport function getRpcTransportWithRequestCoalescing(\n transport: IRpcTransport,\n getDeduplicationKey: GetDeduplicationKeyFn\n): IRpcTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n config: Parameters<IRpcTransport>[0]\n ): Promise<TResponse> {\n const { payload, signal } = config;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(config);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n Promise.resolve().then(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise: transport<TResponse>({\n ...config,\n signal: abortController.signal,\n }),\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<TResponse>;\n return await new Promise<TResponse>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort();\n }\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise.then(resolve).finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as TResponse;\n }\n };\n}\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport fastStableStringify from 'fast-stable-stringify';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n if (payload == null || typeof payload !== 'object' || Array.isArray(payload)) {\n return;\n }\n if ('jsonrpc' in payload && payload.jsonrpc === '2.0' && 'method' in payload && 'params' in payload) {\n return fastStableStringify([payload.method, payload.params]);\n }\n}\n"]}
|
package/dist/index.browser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from '@solana/keys';
|
|
2
2
|
import { createSolanaRpcApi } from '@solana/rpc-core';
|
|
3
3
|
import { createJsonRpc, createHttpTransport } from '@solana/rpc-transport';
|
|
4
|
+
import fastStableStringify from 'fast-stable-stringify';
|
|
4
5
|
|
|
5
6
|
// src/index.ts
|
|
6
7
|
|
|
@@ -39,12 +40,76 @@ var DEFAULT_RPC_CONFIG = {
|
|
|
39
40
|
throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);
|
|
40
41
|
}
|
|
41
42
|
};
|
|
43
|
+
|
|
44
|
+
// src/rpc.ts
|
|
42
45
|
function createSolanaRpc(config) {
|
|
43
46
|
return createJsonRpc({
|
|
44
47
|
...config,
|
|
45
48
|
api: createSolanaRpcApi(DEFAULT_RPC_CONFIG)
|
|
46
49
|
});
|
|
47
50
|
}
|
|
51
|
+
|
|
52
|
+
// src/rpc-request-coalescer.ts
|
|
53
|
+
function getRpcTransportWithRequestCoalescing(transport, getDeduplicationKey) {
|
|
54
|
+
let coalescedRequestsByDeduplicationKey;
|
|
55
|
+
return async function makeCoalescedHttpRequest(config) {
|
|
56
|
+
const { payload, signal } = config;
|
|
57
|
+
const deduplicationKey = getDeduplicationKey(payload);
|
|
58
|
+
if (deduplicationKey === void 0) {
|
|
59
|
+
return await transport(config);
|
|
60
|
+
}
|
|
61
|
+
if (!coalescedRequestsByDeduplicationKey) {
|
|
62
|
+
Promise.resolve().then(() => {
|
|
63
|
+
coalescedRequestsByDeduplicationKey = void 0;
|
|
64
|
+
});
|
|
65
|
+
coalescedRequestsByDeduplicationKey = {};
|
|
66
|
+
}
|
|
67
|
+
if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {
|
|
68
|
+
const abortController = new AbortController();
|
|
69
|
+
coalescedRequestsByDeduplicationKey[deduplicationKey] = {
|
|
70
|
+
abortController,
|
|
71
|
+
numConsumers: 0,
|
|
72
|
+
responsePromise: transport({
|
|
73
|
+
...config,
|
|
74
|
+
signal: abortController.signal
|
|
75
|
+
})
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];
|
|
79
|
+
coalescedRequest.numConsumers++;
|
|
80
|
+
if (signal) {
|
|
81
|
+
const responsePromise = coalescedRequest.responsePromise;
|
|
82
|
+
return await new Promise((resolve, reject) => {
|
|
83
|
+
const handleAbort = (e) => {
|
|
84
|
+
signal.removeEventListener("abort", handleAbort);
|
|
85
|
+
coalescedRequest.numConsumers -= 1;
|
|
86
|
+
if (coalescedRequest.numConsumers === 0) {
|
|
87
|
+
const abortController = coalescedRequest.abortController;
|
|
88
|
+
abortController.abort();
|
|
89
|
+
}
|
|
90
|
+
const abortError = new DOMException(e.target.reason, "AbortError");
|
|
91
|
+
reject(abortError);
|
|
92
|
+
};
|
|
93
|
+
signal.addEventListener("abort", handleAbort);
|
|
94
|
+
responsePromise.then(resolve).finally(() => {
|
|
95
|
+
signal.removeEventListener("abort", handleAbort);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
} else {
|
|
99
|
+
return await coalescedRequest.responsePromise;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function getSolanaRpcPayloadDeduplicationKey(payload) {
|
|
104
|
+
if (payload == null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if ("jsonrpc" in payload && payload.jsonrpc === "2.0" && "method" in payload && "params" in payload) {
|
|
108
|
+
return fastStableStringify([payload.method, payload.params]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/rpc-transport.ts
|
|
48
113
|
function normalizeHeaders(headers) {
|
|
49
114
|
const out = {};
|
|
50
115
|
for (const headerName in headers) {
|
|
@@ -53,16 +118,19 @@ function normalizeHeaders(headers) {
|
|
|
53
118
|
return out;
|
|
54
119
|
}
|
|
55
120
|
function createDefaultRpcTransport(config) {
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
121
|
+
return getRpcTransportWithRequestCoalescing(
|
|
122
|
+
createHttpTransport({
|
|
123
|
+
...config,
|
|
124
|
+
headers: {
|
|
125
|
+
...config.headers ? normalizeHeaders(config.headers) : void 0,
|
|
126
|
+
...{
|
|
127
|
+
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
128
|
+
"solana-client": `js/${"2.0.0-development"}` ?? "UNKNOWN"
|
|
129
|
+
}
|
|
63
130
|
}
|
|
64
|
-
}
|
|
65
|
-
|
|
131
|
+
}),
|
|
132
|
+
getSolanaRpcPayloadDeduplicationKey
|
|
133
|
+
);
|
|
66
134
|
}
|
|
67
135
|
|
|
68
136
|
export { createDefaultRpcTransport, createSolanaRpc };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/rpc.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/rpc-transport.ts"],"names":[],"mappings":";AAAA,cAAc;;;ACAd,SAA2B,0BAA0B;;;ACA9C,IAAM,oCAAN,cAAgD,MAAM;AAAA,EAIzD,YAAY,YAAoB,SAA8B,OAAe;AACzE,UAAM,eAAe,OAAO,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,IAAI,SAAS,QAAQ,CAAC,GAAG,EAAE,KAAK;AAC/F,QAAI,UAAU;AACd,UAAM,YAAY,cAAc;AAChC,UAAM,gBAAgB,cAAc;AACpC,QAAI,aAAa,KAAK,iBAAiB,IAAI;AACvC,gBAAU,cAAc;AAAA,IAC5B,WAAW,aAAa,KAAK,iBAAiB,IAAI;AAC9C,gBAAU,cAAc;AAAA,IAC5B,WAAW,aAAa,KAAK,iBAAiB,IAAI;AAC9C,gBAAU,cAAc;AAAA,IAC5B,OAAO;AACH,gBAAU,cAAc;AAAA,IAC5B;AACA,UAAM,OACF,QAAQ,SAAS,IACX,QACK,MAAM,CAAC,EACP,IAAI,cAAa,OAAO,aAAa,WAAW,IAAI,cAAc,QAAS,EAC3E,KAAK,GAAG,IACb;AACV;AAAA,MACI,OAAO,6BAA6B,0BAC7B,OAAO,cAAc,WAAW,YAAY;AAAA,IAGvD;AACA,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,QAAQ;AAAA,EACjB;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;ACnCO,IAAM,qBAAwE;AAAA,EACjF,kBAAkB,YAAY,SAAS,OAAO;AAC1C,UAAM,IAAI,kCAAkC,YAAY,SAAS,KAAK;AAAA,EAC1E;AACJ;;;AFJA,SAAS,qBAAqB;AAGvB,SAAS,gBAAgB,QAAiF;AAC7G,SAAO,cAAgC;AAAA,IACnC,GAAG;AAAA,IACH,KAAK,mBAAmB,kBAAkB;AAAA,EAC9C,CAAC;AACL;;;AGXA,SAAS,2BAA2B;AAMpC,SAAS,iBACL,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;AAEO,SAAS,0BAA0B,QAAkE;AACxG,SAAO,oBAAoB;AAAA,IACvB,GAAG;AAAA,IACH,SAAS;AAAA,MACL,GAAI,OAAO,UAAU,iBAAiB,OAAO,OAAO,IAAI;AAAA,MACxD,GAAI;AAAA;AAAA,QAEA,iBAAiB,MAAM,yBAAiB;AAAA,MAC5C;AAAA,IACJ;AAAA,EACJ,CAAC;AACL","sourcesContent":["export * from '@solana/keys';\nexport * from './rpc';\nexport * from './rpc-transport';\n","import { SolanaRpcMethods, createSolanaRpcApi } from '@solana/rpc-core';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\n\nimport { createJsonRpc } from '@solana/rpc-transport';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nexport function createSolanaRpc(config: Omit<Parameters<typeof createJsonRpc>[0], 'api'>): Rpc<SolanaRpcMethods> {\n return createJsonRpc<SolanaRpcMethods>({\n ...config,\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n });\n}\n","export class SolanaJsonRpcIntegerOverflowError extends Error {\n readonly methodName: string;\n readonly keyPath: (number | string)[];\n readonly value: bigint;\n constructor(methodName: string, keyPath: (number | string)[], value: bigint) {\n const argPosition = (typeof keyPath[0] === 'number' ? keyPath[0] : parseInt(keyPath[0], 10)) + 1;\n let ordinal = '';\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n ordinal = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n ordinal = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n ordinal = argPosition + 'rd';\n } else {\n ordinal = argPosition + 'th';\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : null;\n super(\n `The ${ordinal} argument to the \\`${methodName}\\` RPC method` +\n `${path ? ` at path \\`${path}\\`` : ''} was \\`${value}\\`. This number is ` +\n 'unsafe for use with the Solana JSON-RPC because it exceeds ' +\n '`Number.MAX_SAFE_INTEGER`.'\n );\n this.keyPath = keyPath;\n this.methodName = methodName;\n this.value = value;\n }\n get name() {\n return 'SolanaJsonRpcIntegerOverflowError';\n }\n}\n","import { createSolanaRpcApi } from '@solana/rpc-core';\nimport { SolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcApi>[0]> = {\n onIntegerOverflow(methodName, keyPath, value) {\n throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","import { createHttpTransport } from '@solana/rpc-transport';\nimport { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers.\n */\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n\nexport function createDefaultRpcTransport(config: Parameters<typeof createHttpTransport>[0]): IRpcTransport {\n return createHttpTransport({\n ...config,\n headers: {\n ...(config.headers ? normalizeHeaders(config.headers) : undefined),\n ...({\n // Keep these headers lowercase so they will override any user-supplied headers above.\n 'solana-client': `js/${__VERSION__}` ?? 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/rpc.ts","../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../src/rpc-transport.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts"],"names":[],"mappings":";AAAA,cAAc;;;ACAd,SAAS,0BAA4C;AACrD,SAAS,qBAAqB;;;ACDvB,IAAM,oCAAN,cAAgD,MAAM;AAAA,EAIzD,YAAY,YAAoB,SAA8B,OAAe;AACzE,UAAM,eAAe,OAAO,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,IAAI,SAAS,QAAQ,CAAC,GAAG,EAAE,KAAK;AAC/F,QAAI,UAAU;AACd,UAAM,YAAY,cAAc;AAChC,UAAM,gBAAgB,cAAc;AACpC,QAAI,aAAa,KAAK,iBAAiB,IAAI;AACvC,gBAAU,cAAc;AAAA,IAC5B,WAAW,aAAa,KAAK,iBAAiB,IAAI;AAC9C,gBAAU,cAAc;AAAA,IAC5B,WAAW,aAAa,KAAK,iBAAiB,IAAI;AAC9C,gBAAU,cAAc;AAAA,IAC5B,OAAO;AACH,gBAAU,cAAc;AAAA,IAC5B;AACA,UAAM,OACF,QAAQ,SAAS,IACX,QACK,MAAM,CAAC,EACP,IAAI,cAAa,OAAO,aAAa,WAAW,IAAI,cAAc,QAAS,EAC3E,KAAK,GAAG,IACb;AACV;AAAA,MACI,OAAO,6BAA6B,0BAC7B,OAAO,cAAc,WAAW,YAAY;AAAA,IAGvD;AACA,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,QAAQ;AAAA,EACjB;AAAA,EACA,IAAI,OAAO;AACP,WAAO;AAAA,EACX;AACJ;;;AClCO,IAAM,qBAAwE;AAAA,EACjF,kBAAkB,YAAY,SAAS,OAAO;AAC1C,UAAM,IAAI,kCAAkC,YAAY,SAAS,KAAK;AAAA,EAC1E;AACJ;;;AFFO,SAAS,gBAAgB,QAAiF;AAC7G,SAAO,cAAgC;AAAA,IACnC,GAAG;AAAA,IACH,KAAK,mBAAmB,kBAAkB;AAAA,EAC9C,CAAC;AACL;;;AGXA,SAAS,2BAA2B;;;ACU7B,SAAS,qCACZ,WACA,qBACa;AACb,MAAI;AACJ,SAAO,eAAe,yBAClB,QACkB;AAClB,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,UAAM,mBAAmB,oBAAoB,OAAO;AACpD,QAAI,qBAAqB,QAAW;AAChC,aAAO,MAAM,UAAU,MAAM;AAAA,IACjC;AACA,QAAI,CAAC,qCAAqC;AACtC,cAAQ,QAAQ,EAAE,KAAK,MAAM;AACzB,8CAAsC;AAAA,MAC1C,CAAC;AACD,4CAAsC,CAAC;AAAA,IAC3C;AACA,QAAI,oCAAoC,gBAAgB,KAAK,MAAM;AAC/D,YAAM,kBAAkB,IAAI,gBAAgB;AAC5C,0CAAoC,gBAAgB,IAAI;AAAA,QACpD;AAAA,QACA,cAAc;AAAA,QACd,iBAAiB,UAAqB;AAAA,UAClC,GAAG;AAAA,UACH,QAAQ,gBAAgB;AAAA,QAC5B,CAAC;AAAA,MACL;AAAA,IACJ;AACA,UAAM,mBAAmB,oCAAoC,gBAAgB;AAC7E,qBAAiB;AACjB,QAAI,QAAQ;AACR,YAAM,kBAAkB,iBAAiB;AACzC,aAAO,MAAM,IAAI,QAAmB,CAAC,SAAS,WAAW;AACrD,cAAM,cAAc,CAAC,MAAoC;AACrD,iBAAO,oBAAoB,SAAS,WAAW;AAC/C,2BAAiB,gBAAgB;AACjC,cAAI,iBAAiB,iBAAiB,GAAG;AACrC,kBAAM,kBAAkB,iBAAiB;AACzC,4BAAgB,MAAM;AAAA,UAC1B;AACA,gBAAM,aAAa,IAAI,aAAc,EAAE,OAAuB,QAAQ,YAAY;AAClF,iBAAO,UAAU;AAAA,QACrB;AACA,eAAO,iBAAiB,SAAS,WAAW;AAC5C,wBAAgB,KAAK,OAAO,EAAE,QAAQ,MAAM;AACxC,iBAAO,oBAAoB,SAAS,WAAW;AAAA,QACnD,CAAC;AAAA,MACL,CAAC;AAAA,IACL,OAAO;AACH,aAAQ,MAAM,iBAAiB;AAAA,IACnC;AAAA,EACJ;AACJ;;;AC9DA,OAAO,yBAAyB;AAEzB,SAAS,oCAAoC,SAAsC;AACtF,MAAI,WAAW,QAAQ,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AAC1E;AAAA,EACJ;AACA,MAAI,aAAa,WAAW,QAAQ,YAAY,SAAS,YAAY,WAAW,YAAY,SAAS;AACjG,WAAO,oBAAoB,CAAC,QAAQ,QAAQ,QAAQ,MAAM,CAAC;AAAA,EAC/D;AACJ;;;AFFA,SAAS,iBACL,SACiD;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,cAAc,SAAS;AAC9B,QAAI,WAAW,YAAY,CAAC,IAAI,QAAQ,UAAU;AAAA,EACtD;AACA,SAAO;AACX;AAEO,SAAS,0BAA0B,QAAkE;AACxG,SAAO;AAAA,IACH,oBAAoB;AAAA,MAChB,GAAG;AAAA,MACH,SAAS;AAAA,QACL,GAAI,OAAO,UAAU,iBAAiB,OAAO,OAAO,IAAI;AAAA,QACxD,GAAI;AAAA;AAAA,UAEA,iBAAiB,MAAM,yBAAiB;AAAA,QAC5C;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,IACD;AAAA,EACJ;AACJ","sourcesContent":["export * from '@solana/keys';\nexport * from './rpc';\nexport * from './rpc-transport';\n","import { createSolanaRpcApi, SolanaRpcMethods } from '@solana/rpc-core';\nimport { createJsonRpc } from '@solana/rpc-transport';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\n\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\n\nexport function createSolanaRpc(config: Omit<Parameters<typeof createJsonRpc>[0], 'api'>): Rpc<SolanaRpcMethods> {\n return createJsonRpc<SolanaRpcMethods>({\n ...config,\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n });\n}\n","export class SolanaJsonRpcIntegerOverflowError extends Error {\n readonly methodName: string;\n readonly keyPath: (number | string)[];\n readonly value: bigint;\n constructor(methodName: string, keyPath: (number | string)[], value: bigint) {\n const argPosition = (typeof keyPath[0] === 'number' ? keyPath[0] : parseInt(keyPath[0], 10)) + 1;\n let ordinal = '';\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n ordinal = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n ordinal = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n ordinal = argPosition + 'rd';\n } else {\n ordinal = argPosition + 'th';\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : null;\n super(\n `The ${ordinal} argument to the \\`${methodName}\\` RPC method` +\n `${path ? ` at path \\`${path}\\`` : ''} was \\`${value}\\`. This number is ` +\n 'unsafe for use with the Solana JSON-RPC because it exceeds ' +\n '`Number.MAX_SAFE_INTEGER`.'\n );\n this.keyPath = keyPath;\n this.methodName = methodName;\n this.value = value;\n }\n get name() {\n return 'SolanaJsonRpcIntegerOverflowError';\n }\n}\n","import { createSolanaRpcApi } from '@solana/rpc-core';\n\nimport { SolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_CONFIG: Partial<Parameters<typeof createSolanaRpcApi>[0]> = {\n onIntegerOverflow(methodName, keyPath, value) {\n throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);\n },\n};\n","import { createHttpTransport } from '@solana/rpc-transport';\nimport { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\n/**\n * Lowercasing header names makes it easier to override user-supplied headers.\n */\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T\n): { [K in keyof T & string as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in keyof T & string as Lowercase<K>]: T[K] };\n}\n\nexport function createDefaultRpcTransport(config: Parameters<typeof createHttpTransport>[0]): IRpcTransport {\n return getRpcTransportWithRequestCoalescing(\n createHttpTransport({\n ...config,\n headers: {\n ...(config.headers ? normalizeHeaders(config.headers) : undefined),\n ...({\n // Keep these headers lowercase so they will override any user-supplied headers above.\n 'solana-client': `js/${__VERSION__}` ?? 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }),\n getSolanaRpcPayloadDeduplicationKey\n );\n}\n","import { IRpcTransport } from '@solana/rpc-transport/dist/types/transports/transport-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<unknown>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\nexport function getRpcTransportWithRequestCoalescing(\n transport: IRpcTransport,\n getDeduplicationKey: GetDeduplicationKeyFn\n): IRpcTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n config: Parameters<IRpcTransport>[0]\n ): Promise<TResponse> {\n const { payload, signal } = config;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(config);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n Promise.resolve().then(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise: transport<TResponse>({\n ...config,\n signal: abortController.signal,\n }),\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<TResponse>;\n return await new Promise<TResponse>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort();\n }\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise.then(resolve).finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as TResponse;\n }\n };\n}\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport fastStableStringify from 'fast-stable-stringify';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n if (payload == null || typeof payload !== 'object' || Array.isArray(payload)) {\n return;\n }\n if ('jsonrpc' in payload && payload.jsonrpc === '2.0' && 'method' in payload && 'params' in payload) {\n return fastStableStringify([payload.method, payload.params]);\n }\n}\n"]}
|
|
@@ -178,6 +178,83 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
178
178
|
}
|
|
179
179
|
});
|
|
180
180
|
|
|
181
|
+
// ../../node_modules/.pnpm/fast-stable-stringify@1.0.0/node_modules/fast-stable-stringify/index.js
|
|
182
|
+
var require_fast_stable_stringify = __commonJS({
|
|
183
|
+
"../../node_modules/.pnpm/fast-stable-stringify@1.0.0/node_modules/fast-stable-stringify/index.js"(exports, module) {
|
|
184
|
+
init_env_shim();
|
|
185
|
+
var objToString = Object.prototype.toString;
|
|
186
|
+
var objKeys = Object.keys || function(obj) {
|
|
187
|
+
var keys = [];
|
|
188
|
+
for (var name in obj) {
|
|
189
|
+
keys.push(name);
|
|
190
|
+
}
|
|
191
|
+
return keys;
|
|
192
|
+
};
|
|
193
|
+
function stringify(val, isArrayProp) {
|
|
194
|
+
var i, max, str, keys, key, propVal, toStr;
|
|
195
|
+
if (val === true) {
|
|
196
|
+
return "true";
|
|
197
|
+
}
|
|
198
|
+
if (val === false) {
|
|
199
|
+
return "false";
|
|
200
|
+
}
|
|
201
|
+
switch (typeof val) {
|
|
202
|
+
case "object":
|
|
203
|
+
if (val === null) {
|
|
204
|
+
return null;
|
|
205
|
+
} else if (val.toJSON && typeof val.toJSON === "function") {
|
|
206
|
+
return stringify(val.toJSON(), isArrayProp);
|
|
207
|
+
} else {
|
|
208
|
+
toStr = objToString.call(val);
|
|
209
|
+
if (toStr === "[object Array]") {
|
|
210
|
+
str = "[";
|
|
211
|
+
max = val.length - 1;
|
|
212
|
+
for (i = 0; i < max; i++) {
|
|
213
|
+
str += stringify(val[i], true) + ",";
|
|
214
|
+
}
|
|
215
|
+
if (max > -1) {
|
|
216
|
+
str += stringify(val[i], true);
|
|
217
|
+
}
|
|
218
|
+
return str + "]";
|
|
219
|
+
} else if (toStr === "[object Object]") {
|
|
220
|
+
keys = objKeys(val).sort();
|
|
221
|
+
max = keys.length;
|
|
222
|
+
str = "";
|
|
223
|
+
i = 0;
|
|
224
|
+
while (i < max) {
|
|
225
|
+
key = keys[i];
|
|
226
|
+
propVal = stringify(val[key], false);
|
|
227
|
+
if (propVal !== void 0) {
|
|
228
|
+
if (str) {
|
|
229
|
+
str += ",";
|
|
230
|
+
}
|
|
231
|
+
str += JSON.stringify(key) + ":" + propVal;
|
|
232
|
+
}
|
|
233
|
+
i++;
|
|
234
|
+
}
|
|
235
|
+
return "{" + str + "}";
|
|
236
|
+
} else {
|
|
237
|
+
return JSON.stringify(val);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
case "function":
|
|
241
|
+
case "undefined":
|
|
242
|
+
return isArrayProp ? null : void 0;
|
|
243
|
+
case "string":
|
|
244
|
+
return JSON.stringify(val);
|
|
245
|
+
default:
|
|
246
|
+
return isFinite(val) ? val : null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
module.exports = function(val) {
|
|
250
|
+
var returnVal = stringify(val, false);
|
|
251
|
+
if (returnVal !== void 0) {
|
|
252
|
+
return "" + returnVal;
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
|
|
181
258
|
// src/index.ts
|
|
182
259
|
init_env_shim();
|
|
183
260
|
|
|
@@ -238,7 +315,13 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
238
315
|
}
|
|
239
316
|
var KEYPATH_WILDCARD = {};
|
|
240
317
|
var ALLOWED_NUMERIC_KEYPATHS = {
|
|
241
|
-
|
|
318
|
+
getBlockTime: [[]],
|
|
319
|
+
getInflationReward: [[KEYPATH_WILDCARD, "commission"]],
|
|
320
|
+
getRecentPerformanceSamples: [[KEYPATH_WILDCARD, "samplePeriodSecs"]],
|
|
321
|
+
getVoteAccounts: [
|
|
322
|
+
["current", KEYPATH_WILDCARD, "commission"],
|
|
323
|
+
["delinquent", KEYPATH_WILDCARD, "commission"]
|
|
324
|
+
]
|
|
242
325
|
};
|
|
243
326
|
function getNextAllowedKeypaths(keyPaths, property) {
|
|
244
327
|
return keyPaths.filter((keyPath) => keyPath[0] === KEYPATH_WILDCARD && typeof property === "number" || keyPath[0] === property).map((keyPath) => keyPath.slice(1));
|
|
@@ -295,46 +378,6 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
295
378
|
});
|
|
296
379
|
}
|
|
297
380
|
|
|
298
|
-
// src/rpc-default-config.ts
|
|
299
|
-
init_env_shim();
|
|
300
|
-
|
|
301
|
-
// src/rpc-integer-overflow-error.ts
|
|
302
|
-
init_env_shim();
|
|
303
|
-
var SolanaJsonRpcIntegerOverflowError = class extends Error {
|
|
304
|
-
constructor(methodName, keyPath, value) {
|
|
305
|
-
const argPosition = (typeof keyPath[0] === "number" ? keyPath[0] : parseInt(keyPath[0], 10)) + 1;
|
|
306
|
-
let ordinal = "";
|
|
307
|
-
const lastDigit = argPosition % 10;
|
|
308
|
-
const lastTwoDigits = argPosition % 100;
|
|
309
|
-
if (lastDigit == 1 && lastTwoDigits != 11) {
|
|
310
|
-
ordinal = argPosition + "st";
|
|
311
|
-
} else if (lastDigit == 2 && lastTwoDigits != 12) {
|
|
312
|
-
ordinal = argPosition + "nd";
|
|
313
|
-
} else if (lastDigit == 3 && lastTwoDigits != 13) {
|
|
314
|
-
ordinal = argPosition + "rd";
|
|
315
|
-
} else {
|
|
316
|
-
ordinal = argPosition + "th";
|
|
317
|
-
}
|
|
318
|
-
const path = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : null;
|
|
319
|
-
super(
|
|
320
|
-
`The ${ordinal} argument to the \`${methodName}\` RPC method${path ? ` at path \`${path}\`` : ""} was \`${value}\`. This number is unsafe for use with the Solana JSON-RPC because it exceeds \`Number.MAX_SAFE_INTEGER\`.`
|
|
321
|
-
);
|
|
322
|
-
this.keyPath = keyPath;
|
|
323
|
-
this.methodName = methodName;
|
|
324
|
-
this.value = value;
|
|
325
|
-
}
|
|
326
|
-
get name() {
|
|
327
|
-
return "SolanaJsonRpcIntegerOverflowError";
|
|
328
|
-
}
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
// src/rpc-default-config.ts
|
|
332
|
-
var DEFAULT_RPC_CONFIG = {
|
|
333
|
-
onIntegerOverflow(methodName, keyPath, value) {
|
|
334
|
-
throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
|
-
|
|
338
381
|
// ../rpc-transport/dist/index.browser.js
|
|
339
382
|
init_env_shim();
|
|
340
383
|
var SolanaJsonRpcError = class extends Error {
|
|
@@ -400,6 +443,7 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
400
443
|
function createJsonRpc(rpcConfig) {
|
|
401
444
|
return makeProxy(rpcConfig);
|
|
402
445
|
}
|
|
446
|
+
var e = globalThis.fetch;
|
|
403
447
|
var SolanaHttpError = class extends Error {
|
|
404
448
|
constructor(details) {
|
|
405
449
|
super(`HTTP error (${details.statusCode}): ${details.message}`);
|
|
@@ -458,7 +502,6 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
458
502
|
}
|
|
459
503
|
return out;
|
|
460
504
|
}
|
|
461
|
-
var e = globalThis.fetch;
|
|
462
505
|
function createHttpTransport({ httpAgentNodeOnly, headers, url }) {
|
|
463
506
|
if (headers) {
|
|
464
507
|
assertIsAllowedHttpRequestHeaders(headers);
|
|
@@ -499,6 +542,46 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
499
542
|
};
|
|
500
543
|
}
|
|
501
544
|
|
|
545
|
+
// src/rpc-default-config.ts
|
|
546
|
+
init_env_shim();
|
|
547
|
+
|
|
548
|
+
// src/rpc-integer-overflow-error.ts
|
|
549
|
+
init_env_shim();
|
|
550
|
+
var SolanaJsonRpcIntegerOverflowError = class extends Error {
|
|
551
|
+
constructor(methodName, keyPath, value) {
|
|
552
|
+
const argPosition = (typeof keyPath[0] === "number" ? keyPath[0] : parseInt(keyPath[0], 10)) + 1;
|
|
553
|
+
let ordinal = "";
|
|
554
|
+
const lastDigit = argPosition % 10;
|
|
555
|
+
const lastTwoDigits = argPosition % 100;
|
|
556
|
+
if (lastDigit == 1 && lastTwoDigits != 11) {
|
|
557
|
+
ordinal = argPosition + "st";
|
|
558
|
+
} else if (lastDigit == 2 && lastTwoDigits != 12) {
|
|
559
|
+
ordinal = argPosition + "nd";
|
|
560
|
+
} else if (lastDigit == 3 && lastTwoDigits != 13) {
|
|
561
|
+
ordinal = argPosition + "rd";
|
|
562
|
+
} else {
|
|
563
|
+
ordinal = argPosition + "th";
|
|
564
|
+
}
|
|
565
|
+
const path = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : null;
|
|
566
|
+
super(
|
|
567
|
+
`The ${ordinal} argument to the \`${methodName}\` RPC method${path ? ` at path \`${path}\`` : ""} was \`${value}\`. This number is unsafe for use with the Solana JSON-RPC because it exceeds \`Number.MAX_SAFE_INTEGER\`.`
|
|
568
|
+
);
|
|
569
|
+
this.keyPath = keyPath;
|
|
570
|
+
this.methodName = methodName;
|
|
571
|
+
this.value = value;
|
|
572
|
+
}
|
|
573
|
+
get name() {
|
|
574
|
+
return "SolanaJsonRpcIntegerOverflowError";
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
// src/rpc-default-config.ts
|
|
579
|
+
var DEFAULT_RPC_CONFIG = {
|
|
580
|
+
onIntegerOverflow(methodName, keyPath, value) {
|
|
581
|
+
throw new SolanaJsonRpcIntegerOverflowError(methodName, keyPath, value);
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
|
|
502
585
|
// src/rpc.ts
|
|
503
586
|
function createSolanaRpc(config) {
|
|
504
587
|
return createJsonRpc({
|
|
@@ -509,6 +592,73 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
509
592
|
|
|
510
593
|
// src/rpc-transport.ts
|
|
511
594
|
init_env_shim();
|
|
595
|
+
|
|
596
|
+
// src/rpc-request-coalescer.ts
|
|
597
|
+
init_env_shim();
|
|
598
|
+
function getRpcTransportWithRequestCoalescing(transport, getDeduplicationKey) {
|
|
599
|
+
let coalescedRequestsByDeduplicationKey;
|
|
600
|
+
return async function makeCoalescedHttpRequest(config) {
|
|
601
|
+
const { payload, signal } = config;
|
|
602
|
+
const deduplicationKey = getDeduplicationKey(payload);
|
|
603
|
+
if (deduplicationKey === void 0) {
|
|
604
|
+
return await transport(config);
|
|
605
|
+
}
|
|
606
|
+
if (!coalescedRequestsByDeduplicationKey) {
|
|
607
|
+
Promise.resolve().then(() => {
|
|
608
|
+
coalescedRequestsByDeduplicationKey = void 0;
|
|
609
|
+
});
|
|
610
|
+
coalescedRequestsByDeduplicationKey = {};
|
|
611
|
+
}
|
|
612
|
+
if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {
|
|
613
|
+
const abortController = new AbortController();
|
|
614
|
+
coalescedRequestsByDeduplicationKey[deduplicationKey] = {
|
|
615
|
+
abortController,
|
|
616
|
+
numConsumers: 0,
|
|
617
|
+
responsePromise: transport({
|
|
618
|
+
...config,
|
|
619
|
+
signal: abortController.signal
|
|
620
|
+
})
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];
|
|
624
|
+
coalescedRequest.numConsumers++;
|
|
625
|
+
if (signal) {
|
|
626
|
+
const responsePromise = coalescedRequest.responsePromise;
|
|
627
|
+
return await new Promise((resolve, reject) => {
|
|
628
|
+
const handleAbort = (e2) => {
|
|
629
|
+
signal.removeEventListener("abort", handleAbort);
|
|
630
|
+
coalescedRequest.numConsumers -= 1;
|
|
631
|
+
if (coalescedRequest.numConsumers === 0) {
|
|
632
|
+
const abortController = coalescedRequest.abortController;
|
|
633
|
+
abortController.abort();
|
|
634
|
+
}
|
|
635
|
+
const abortError = new DOMException(e2.target.reason, "AbortError");
|
|
636
|
+
reject(abortError);
|
|
637
|
+
};
|
|
638
|
+
signal.addEventListener("abort", handleAbort);
|
|
639
|
+
responsePromise.then(resolve).finally(() => {
|
|
640
|
+
signal.removeEventListener("abort", handleAbort);
|
|
641
|
+
});
|
|
642
|
+
});
|
|
643
|
+
} else {
|
|
644
|
+
return await coalescedRequest.responsePromise;
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// src/rpc-request-deduplication.ts
|
|
650
|
+
init_env_shim();
|
|
651
|
+
var import_fast_stable_stringify = __toESM(require_fast_stable_stringify(), 1);
|
|
652
|
+
function getSolanaRpcPayloadDeduplicationKey(payload) {
|
|
653
|
+
if (payload == null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
if ("jsonrpc" in payload && payload.jsonrpc === "2.0" && "method" in payload && "params" in payload) {
|
|
657
|
+
return (0, import_fast_stable_stringify.default)([payload.method, payload.params]);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// src/rpc-transport.ts
|
|
512
662
|
function normalizeHeaders2(headers) {
|
|
513
663
|
const out = {};
|
|
514
664
|
for (const headerName in headers) {
|
|
@@ -517,16 +667,19 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
517
667
|
return out;
|
|
518
668
|
}
|
|
519
669
|
function createDefaultRpcTransport(config) {
|
|
520
|
-
return
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
670
|
+
return getRpcTransportWithRequestCoalescing(
|
|
671
|
+
createHttpTransport({
|
|
672
|
+
...config,
|
|
673
|
+
headers: {
|
|
674
|
+
...config.headers ? normalizeHeaders2(config.headers) : void 0,
|
|
675
|
+
...{
|
|
676
|
+
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
677
|
+
"solana-client": `js/${"2.0.0-development"}` ?? "UNKNOWN"
|
|
678
|
+
}
|
|
527
679
|
}
|
|
528
|
-
}
|
|
529
|
-
|
|
680
|
+
}),
|
|
681
|
+
getSolanaRpcPayloadDeduplicationKey
|
|
682
|
+
);
|
|
530
683
|
}
|
|
531
684
|
|
|
532
685
|
exports.assertIsBase58EncodedAddress = assertIsBase58EncodedAddress;
|