@solana/rpc 6.3.1 → 6.3.2-canary-20260313112147
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 +1 -1
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.mjs +1 -1
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.native.mjs +1 -1
- package/dist/index.native.mjs.map +1 -1
- package/dist/index.node.cjs +1 -1
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +1 -1
- package/dist/index.node.mjs.map +1 -1
- package/package.json +12 -11
- package/src/index.ts +18 -0
- package/src/rpc-clusters.ts +205 -0
- package/src/rpc-default-config.ts +22 -0
- package/src/rpc-integer-overflow-error.ts +43 -0
- package/src/rpc-request-coalescer.ts +102 -0
- package/src/rpc-request-deduplication.ts +6 -0
- package/src/rpc-transport.ts +60 -0
- package/src/rpc.ts +34 -0
package/dist/index.browser.cjs
CHANGED
|
@@ -143,7 +143,7 @@ function createDefaultRpcTransport(config) {
|
|
|
143
143
|
...config.headers ? normalizeHeaders(config.headers) : void 0,
|
|
144
144
|
...{
|
|
145
145
|
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
146
|
-
"solana-client": `js/${"6.3.
|
|
146
|
+
"solana-client": `js/${"6.3.2-canary-20260313112147"}`
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.browser.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["SolanaError","SOLANA_ERROR__RPC__INTEGER_OVERFLOW","safeCaptureStackTrace","AbortController","isJsonRpcPayload","fastStableStringify","pipe","createHttpTransportForSolanaRpc","createRpc","createSolanaRpcApi"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.browser.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["SolanaError","SOLANA_ERROR__RPC__INTEGER_OVERFLOW","safeCaptureStackTrace","AbortController","isJsonRpcPayload","fastStableStringify","pipe","createHttpTransportForSolanaRpc","createRpc","createSolanaRpcApi"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
package/dist/index.browser.mjs
CHANGED
|
@@ -139,7 +139,7 @@ function createDefaultRpcTransport(config) {
|
|
|
139
139
|
...config.headers ? normalizeHeaders(config.headers) : void 0,
|
|
140
140
|
...{
|
|
141
141
|
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
142
|
-
"solana-client": `js/${"6.3.
|
|
142
|
+
"solana-client": `js/${"6.3.2-canary-20260313112147"}`
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.browser.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["AbortController"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.browser.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["AbortController"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
package/dist/index.native.mjs
CHANGED
|
@@ -139,7 +139,7 @@ function createDefaultRpcTransport(config) {
|
|
|
139
139
|
...config.headers ? normalizeHeaders(config.headers) : void 0,
|
|
140
140
|
...{
|
|
141
141
|
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
142
|
-
"solana-client": `js/${"6.3.
|
|
142
|
+
"solana-client": `js/${"6.3.2-canary-20260313112147"}`
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.browser.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["AbortController"],"mappings":"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","file":"index.native.mjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.browser.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["AbortController"],"mappings":"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","file":"index.native.mjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
package/dist/index.node.cjs
CHANGED
|
@@ -153,7 +153,7 @@ function createDefaultRpcTransport(config) {
|
|
|
153
153
|
...config.headers ? normalizeHeaders(config.headers) : void 0,
|
|
154
154
|
...{
|
|
155
155
|
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
156
|
-
"solana-client": `js/${"6.3.
|
|
156
|
+
"solana-client": `js/${"6.3.2-canary-20260313112147"}`
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
}),
|
package/dist/index.node.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.node.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["SolanaError","SOLANA_ERROR__RPC__INTEGER_OVERFLOW","safeCaptureStackTrace","AbortController","args","setMaxListeners","e","isJsonRpcPayload","fastStableStringify","pipe","createHttpTransportForSolanaRpc","createRpc","createSolanaRpcApi"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.node.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["SolanaError","SOLANA_ERROR__RPC__INTEGER_OVERFLOW","safeCaptureStackTrace","AbortController","args","setMaxListeners","e","isJsonRpcPayload","fastStableStringify","pipe","createHttpTransportForSolanaRpc","createRpc","createSolanaRpcApi"],"mappings":";;;;;;;;;;;;;;;AAGO,SAAS,uCAAA,CACZ,UAAA,EACA,OAAA,EACA,KAAA,EACuD;AACvD,EAAA,IAAI,aAAA,GAAgB,EAAA;AACpB,EAAA,IAAI,OAAO,OAAA,CAAQ,CAAC,CAAA,KAAM,QAAA,EAAU;AAChC,IAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,CAAC,CAAA,GAAI,CAAA;AACjC,IAAA,MAAM,YAAY,WAAA,GAAc,EAAA;AAChC,IAAA,MAAM,gBAAgB,WAAA,GAAc,GAAA;AACpC,IAAA,IAAI,SAAA,IAAa,CAAA,IAAK,aAAA,IAAiB,EAAA,EAAI;AACvC,MAAA,aAAA,GAAgB,WAAA,GAAc,IAAA;AAAA,IAClC,CAAA,MAAA,IAAW,SAAA,IAAa,CAAA,IAAK,aAAA,IAAiB,EAAA,EAAI;AAC9C,MAAA,aAAA,GAAgB,WAAA,GAAc,IAAA;AAAA,IAClC,CAAA,MAAA,IAAW,SAAA,IAAa,CAAA,IAAK,aAAA,IAAiB,EAAA,EAAI;AAC9C,MAAA,aAAA,GAAgB,WAAA,GAAc,IAAA;AAAA,IAClC,CAAA,MAAO;AACH,MAAA,aAAA,GAAgB,WAAA,GAAc,IAAA;AAAA,IAClC;AAAA,EACJ,CAAA,MAAO;AACH,IAAA,aAAA,GAAgB,CAAA,EAAA,EAAK,OAAA,CAAQ,CAAC,CAAA,CAAE,UAAU,CAAA,EAAA,CAAA;AAAA,EAC9C;AACA,EAAA,MAAM,IAAA,GACF,QAAQ,MAAA,GAAS,CAAA,GACX,QACK,KAAA,CAAM,CAAC,EACP,GAAA,CAAI,CAAA,QAAA,KAAa,OAAO,QAAA,KAAa,QAAA,GAAW,IAAI,QAAQ,CAAA,CAAA,CAAA,GAAM,QAAS,CAAA,CAC3E,IAAA,CAAK,GAAG,CAAA,GACb,MAAA;AACV,EAAA,MAAM,KAAA,GAAQ,IAAIA,kBAAA,CAAYC,0CAAA,EAAqC;AAAA,IAC/D,aAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,iBAAA,EAAmB,IAAA,GAAO,CAAA,WAAA,EAAc,IAAI,CAAA,EAAA,CAAA,GAAO,EAAA;AAAA,IACnD,KAAA;AAAA,IACA,GAAI,IAAA,KAAS,MAAA,GAAY,EAAE,MAAK,GAAI;AAAA,GACvC,CAAA;AACD,EAAAC,4BAAA,CAAsB,OAAO,uCAAuC,CAAA;AACpE,EAAA,OAAO,KAAA;AACX;;;AC1BO,IAAM,kBAAA,GAAqF;AAAA,EAC9F,iBAAA,EAAmB,WAAA;AAAA,EACnB,iBAAA,CAAkB,OAAA,EAAS,OAAA,EAAS,KAAA,EAAO;AACvC,IAAA,MAAM,uCAAA,CAAwC,OAAA,CAAQ,UAAA,EAAY,OAAA,EAAS,KAAK,CAAA;AAAA,EACpF;AACJ;ICnBaC,CAAAA,GAAkB,cAAc,WAAW,eAAA,CAAgB;AACpE,EAAA,WAAA,CAAA,GAAeC,CAAAA,EAAgE;AAC3E,IAAA,KAAA,CAAM,GAAGA,CAAI,CAAA,EACbC,uBAAgB,MAAA,CAAO,gBAAA,EAAkB,KAAK,MAAM,CAAA;AACxD,EAAA;AACJ,CAAA;;;ACSA,IAAI,oBAAA;AACJ,SAAS,wBAAA,GAA2B;AAGhC,EAAA,OAAO,yBAAyB,YAAA,GAC1B;AAAA,IACI,oBAAA,EACI;AAAA,MAGR,EAAC;AACX;AAEO,SAAS,oCAAA,CACZ,WACA,mBAAA,EACU;AACV,EAAA,IAAI,mCAAA;AACJ,EAAA,OAAO,eAAe,yBAClB,OAAA,EAC+B;AAC/B,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,OAAA;AAC5B,IAAA,MAAM,gBAAA,GAAmB,oBAAoB,OAAO,CAAA;AACpD,IAAA,IAAI,qBAAqB,MAAA,EAAW;AAChC,MAAA,OAAO,MAAM,UAAU,OAAO,CAAA;AAAA,IAClC;AACA,IAAA,IAAI,CAAC,mCAAA,EAAqC;AACtC,MAAA,cAAA,CAAe,MAAM;AACjB,QAAA,mCAAA,GAAsC,MAAA;AAAA,MAC1C,CAAC,CAAA;AACD,MAAA,mCAAA,GAAsC,EAAC;AAAA,IAC3C;AACA,IAAA,IAAI,mCAAA,CAAoC,gBAAgB,CAAA,IAAK,IAAA,EAAM;AAC/D,MAAA,MAAM,eAAA,GAAkB,IAAI,CAAA,EAAgB;AAC5C,MAAA,MAAM,mBAAmB,YAAY;AACjC,QAAA,IAAI;AACA,UAAA,OAAO,MAAM,SAAA,CAAqB;AAAA,YAC9B,GAAG,OAAA;AAAA,YACH,QAAQ,eAAA,CAAgB;AAAA,WAC3B,CAAA;AAAA,QACL,SAASC,EAAAA,EAAG;AACR,UAAA,IAAIA,EAAAA,MAAO,oBAAA,KAAyB,wBAAA,EAAyB,CAAA,EAAI;AAI7D,YAAA;AAAA,UACJ;AACA,UAAA,MAAMA,EAAAA;AAAA,QACV;AAAA,MACJ,CAAA,GAAG;AACH,MAAA,mCAAA,CAAoC,gBAAgB,CAAA,GAAI;AAAA,QACpD,eAAA;AAAA,QACA,YAAA,EAAc,CAAA;AAAA,QACd;AAAA,OACJ;AAAA,IACJ;AACA,IAAA,MAAM,gBAAA,GAAmB,oCAAoC,gBAAgB,CAAA;AAC7E,IAAA,gBAAA,CAAiB,YAAA,EAAA;AACjB,IAAA,IAAI,MAAA,EAAQ;AACR,MAAA,MAAM,kBAAkB,gBAAA,CAAiB,eAAA;AACzC,MAAA,OAAO,MAAM,IAAI,OAAA,CAAgC,CAAC,SAAS,MAAA,KAAW;AAClE,QAAA,MAAM,WAAA,GAAc,CAACA,EAAAA,KAAoC;AACrD,UAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAC/C,UAAA,gBAAA,CAAiB,YAAA,IAAgB,CAAA;AACjC,UAAA,cAAA,CAAe,MAAM;AACjB,YAAA,IAAI,gBAAA,CAAiB,iBAAiB,CAAA,EAAG;AACrC,cAAA,MAAM,kBAAkB,gBAAA,CAAiB,eAAA;AACzC,cAAA,eAAA,CAAgB,KAAA,CAAO,oBAAA,KAAyB,wBAAA,EAA2B,CAAA;AAAA,YAC/E;AAAA,UACJ,CAAC,CAAA;AAED,UAAA,MAAA,CAAQA,EAAAA,CAAE,OAAuB,MAAM,CAAA;AAAA,QAC3C,CAAA;AACA,QAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC5C,QAAA,eAAA,CACK,KAAK,OAAO,CAAA,CACZ,MAAM,MAAM,CAAA,CACZ,QAAQ,MAAM;AACX,UAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAAA,QACnD,CAAC,CAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACL,CAAA,MAAO;AACH,MAAA,OAAQ,MAAM,gBAAA,CAAiB,eAAA;AAAA,IACnC;AAAA,EACJ,CAAA;AACJ;AClGO,SAAS,oCAAoC,OAAA,EAAsC;AACtF,EAAA,OAAOC,wBAAA,CAAiB,OAAO,CAAA,GAAIC,oCAAA,CAAoB,CAAC,QAAQ,MAAA,EAAQ,OAAA,CAAQ,MAAM,CAAC,CAAA,GAAI,MAAA;AAC/F;;;ACQA,SAAS,iBACL,OAAA,EACiD;AACjD,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,cAAc,OAAA,EAAS;AAE9B,IAAA,GAAA,CAAI,UAAA,CAAW,WAAA,EAAa,CAAA,GAAI,QAAQ,UAAU,CAAA;AAAA,EACtD;AACA,EAAA,OAAO,GAAA;AACX;AAcO,SAAS,0BACZ,MAAA,EACuC;AACvC,EAAA,OAAOC,eAAA;AAAA,IACHC,gDAAA,CAAgC;AAAA,MAC5B,GAAG,MAAA;AAAA,MACH,OAAA,EAAS;AAAA,QACL,GACK;AAAA;AAAA,UAEG,iBAAA;AAAA;AAAA,YAEI;AAAA;AAAA;AAAA,SACR;AAAA,QACJ,GAAI,MAAA,CAAO,OAAA,GAAU,gBAAA,CAAiB,MAAA,CAAO,OAAO,CAAA,GAAI,MAAA;AAAA,QACxD,GAAI;AAAA;AAAA,UAEA,eAAA,EAA+B,CAAA,GAAA,EAAM,6BAAW,CAAA,CAAA;AAAK;AACzD;AACJ,KACH,CAAA;AAAA,IACD,CAAA,SAAA,KAAa,oCAAA,CAAqC,SAAA,EAAW,mCAAmC;AAAA,GACpG;AACJ;;;AC1CO,SAAS,eAAA,CACZ,YACA,MAAA,EACF;AACE,EAAA,OAAO,4BAAA,CAA6B,0BAA0B,EAAE,GAAA,EAAK,YAAY,GAAG,MAAA,EAAQ,CAAC,CAAA;AACjG;AAMO,SAAS,6BAA8D,SAAA,EAAuB;AACjG,EAAA,OAAOC,iBAAA,CAAU;AAAA,IACb,GAAA,EAAKC,0BAAmB,kBAAkB,CAAA;AAAA,IAC1C;AAAA,GACH,CAAA;AACL","file":"index.node.cjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
package/dist/index.node.mjs
CHANGED
|
@@ -149,7 +149,7 @@ function createDefaultRpcTransport(config) {
|
|
|
149
149
|
...config.headers ? normalizeHeaders(config.headers) : void 0,
|
|
150
150
|
...{
|
|
151
151
|
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
152
|
-
"solana-client": `js/${"6.3.
|
|
152
|
+
"solana-client": `js/${"6.3.2-canary-20260313112147"}`
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
}),
|
package/dist/index.node.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.node.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["AbortController","args","setMaxListeners","e"],"mappings":"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","file":"index.node.mjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/rpc-integer-overflow-error.ts","../src/rpc-default-config.ts","../../event-target-impl/src/index.node.ts","../src/rpc-request-coalescer.ts","../src/rpc-request-deduplication.ts","../src/rpc-transport.ts","../src/rpc.ts"],"names":["AbortController","args","setMaxListeners","e"],"mappings":"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","file":"index.node.mjs","sourcesContent":["import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n methodName: string,\n keyPath: KeyPath,\n value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n let argumentLabel = '';\n if (typeof keyPath[0] === 'number') {\n const argPosition = keyPath[0] + 1;\n const lastDigit = argPosition % 10;\n const lastTwoDigits = argPosition % 100;\n if (lastDigit == 1 && lastTwoDigits != 11) {\n argumentLabel = argPosition + 'st';\n } else if (lastDigit == 2 && lastTwoDigits != 12) {\n argumentLabel = argPosition + 'nd';\n } else if (lastDigit == 3 && lastTwoDigits != 13) {\n argumentLabel = argPosition + 'rd';\n } else {\n argumentLabel = argPosition + 'th';\n }\n } else {\n argumentLabel = `\\`${keyPath[0].toString()}\\``;\n }\n const path =\n keyPath.length > 1\n ? keyPath\n .slice(1)\n .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n .join('.')\n : undefined;\n const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n argumentLabel,\n keyPath: keyPath as readonly (number | string | symbol)[],\n methodName,\n optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n value,\n ...(path !== undefined ? { path } : undefined),\n });\n safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n return error;\n}\n","import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n * api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n * transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n defaultCommitment: 'confirmed',\n onIntegerOverflow(request, keyPath, value) {\n throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n },\n};\n","import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n super(...args);\n setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n }\n};\n","import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n readonly abortController: AbortController;\n numConsumers: number;\n readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n return process.env.NODE_ENV !== \"production\"\n ? {\n EXPLICIT_ABORT_TOKEN:\n 'This object is thrown from the request that underlies a series of coalesced ' +\n 'requests when the last request in that series aborts',\n }\n : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n transport: TTransport,\n getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n return async function makeCoalescedHttpRequest<TResponse>(\n request: Parameters<RpcTransport>[0],\n ): Promise<RpcResponse<TResponse>> {\n const { payload, signal } = request;\n const deduplicationKey = getDeduplicationKey(payload);\n if (deduplicationKey === undefined) {\n return await transport(request);\n }\n if (!coalescedRequestsByDeduplicationKey) {\n queueMicrotask(() => {\n coalescedRequestsByDeduplicationKey = undefined;\n });\n coalescedRequestsByDeduplicationKey = {};\n }\n if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n const abortController = new AbortController();\n const responsePromise = (async () => {\n try {\n return await transport<TResponse>({\n ...request,\n signal: abortController.signal,\n });\n } catch (e) {\n if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n // We triggered this error when the last subscriber aborted. Letting this\n // error bubble up from here would cause runtime fatals where there should\n // be none.\n return;\n }\n throw e;\n }\n })();\n coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n abortController,\n numConsumers: 0,\n responsePromise,\n };\n }\n const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n coalescedRequest.numConsumers++;\n if (signal) {\n const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n signal.removeEventListener('abort', handleAbort);\n coalescedRequest.numConsumers -= 1;\n queueMicrotask(() => {\n if (coalescedRequest.numConsumers === 0) {\n const abortController = coalescedRequest.abortController;\n abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n }\n });\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject((e.target as AbortSignal).reason);\n };\n signal.addEventListener('abort', handleAbort);\n responsePromise\n .then(resolve)\n .catch(reject)\n .finally(() => {\n signal.removeEventListener('abort', handleAbort);\n });\n });\n } else {\n return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n }\n } as TTransport;\n}\n","import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n","import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n const out: Record<string, string> = {};\n for (const headerName in headers) {\n // Lowercasing header names makes it easier to override user-supplied headers.\n out[headerName.toLowerCase()] = headers[headerName];\n }\n return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n * arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n * responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n return pipe(\n createHttpTransportForSolanaRpc({\n ...config,\n headers: {\n ...(__NODEJS__ &&\n ({\n // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n 'accept-encoding':\n // Natively supported by Node LTS v20.18.0 and above.\n 'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n } as { [overrideHeader: string]: string })),\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': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n } as { [overrideHeader: string]: string }),\n },\n }) as RpcTransportFromClusterUrl<TClusterUrl>,\n transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n );\n}\n","import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n clusterUrl: TClusterUrl,\n config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n return createRpc({\n api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n transport,\n }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/rpc",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.2-canary-20260313112147",
|
|
4
4
|
"description": "A library for sending JSON RPC requests to Solana RPCs",
|
|
5
5
|
"homepage": "https://www.solanakit.com/api#solanarpc",
|
|
6
6
|
"exports": {
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"types": "./dist/types/index.d.ts",
|
|
34
34
|
"type": "commonjs",
|
|
35
35
|
"files": [
|
|
36
|
-
"./dist/"
|
|
36
|
+
"./dist/",
|
|
37
|
+
"./src/"
|
|
37
38
|
],
|
|
38
39
|
"sideEffects": false,
|
|
39
40
|
"keywords": [
|
|
@@ -55,15 +56,15 @@
|
|
|
55
56
|
"maintained node versions"
|
|
56
57
|
],
|
|
57
58
|
"dependencies": {
|
|
58
|
-
"@solana/errors": "6.3.
|
|
59
|
-
"@solana/fast-stable-stringify": "6.3.
|
|
60
|
-
"@solana/functional": "6.3.
|
|
61
|
-
"@solana/rpc-api": "6.3.
|
|
62
|
-
"@solana/rpc-spec": "6.3.
|
|
63
|
-
"@solana/rpc-spec-types": "6.3.
|
|
64
|
-
"@solana/rpc-
|
|
65
|
-
"@solana/rpc-
|
|
66
|
-
"@solana/rpc-types": "6.3.
|
|
59
|
+
"@solana/errors": "6.3.2-canary-20260313112147",
|
|
60
|
+
"@solana/fast-stable-stringify": "6.3.2-canary-20260313112147",
|
|
61
|
+
"@solana/functional": "6.3.2-canary-20260313112147",
|
|
62
|
+
"@solana/rpc-api": "6.3.2-canary-20260313112147",
|
|
63
|
+
"@solana/rpc-spec": "6.3.2-canary-20260313112147",
|
|
64
|
+
"@solana/rpc-spec-types": "6.3.2-canary-20260313112147",
|
|
65
|
+
"@solana/rpc-transformers": "6.3.2-canary-20260313112147",
|
|
66
|
+
"@solana/rpc-transport-http": "6.3.2-canary-20260313112147",
|
|
67
|
+
"@solana/rpc-types": "6.3.2-canary-20260313112147"
|
|
67
68
|
},
|
|
68
69
|
"peerDependencies": {
|
|
69
70
|
"typescript": "^5.0.0"
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This package contains utilities for creating objects that you can use to communicate with a
|
|
3
|
+
* Solana JSON RPC server. It can be used standalone, but it is also exported as part of Kit
|
|
4
|
+
* [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).
|
|
5
|
+
*
|
|
6
|
+
* Unless you plan to create a custom RPC interface, you can use the
|
|
7
|
+
* {@link createSolanaRpc} function to obtain a default implementation of the
|
|
8
|
+
* [Solana JSON RPC API](https://solana.com/docs/rpc/http).
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
export * from '@solana/rpc-api';
|
|
13
|
+
export * from '@solana/rpc-spec';
|
|
14
|
+
|
|
15
|
+
export * from './rpc';
|
|
16
|
+
export * from './rpc-default-config';
|
|
17
|
+
export * from './rpc-clusters';
|
|
18
|
+
export * from './rpc-transport';
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { SolanaRpcApi, SolanaRpcApiDevnet, SolanaRpcApiMainnet, SolanaRpcApiTestnet } from '@solana/rpc-api';
|
|
2
|
+
import type { Rpc, RpcTransport } from '@solana/rpc-spec';
|
|
3
|
+
import { type ClusterUrl, type DevnetUrl, type MainnetUrl, type TestnetUrl } from '@solana/rpc-types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A {@link RpcTransport} that communicates with the devnet cluster.
|
|
7
|
+
*
|
|
8
|
+
* Such transports are understood to communicate with a RPC server that services devnet, and as such
|
|
9
|
+
* might only be accepted for use as the transport of a {@link RpcDevnet}.
|
|
10
|
+
*
|
|
11
|
+
* This is useful in cases where you need to make assertions about what capabilities a RPC offers.
|
|
12
|
+
* For example, RPC methods like {@link requestAirdrop} are not available on mainnet. You can use
|
|
13
|
+
* the ability to assert on the type of RPC transport at compile time to prevent calling
|
|
14
|
+
* unimplemented methods or presuming the existence of unavailable capabilities.
|
|
15
|
+
*/
|
|
16
|
+
export type RpcTransportDevnet = RpcTransport & { '~cluster': 'devnet' };
|
|
17
|
+
/**
|
|
18
|
+
* A {@link RpcTransport} that communicates with the testnet cluster.
|
|
19
|
+
*
|
|
20
|
+
* Such transports are understood to communicate with a RPC server that services testnet, and as
|
|
21
|
+
* such might only be accepted for use as the transport of a {@link RpcTestnet}.
|
|
22
|
+
*
|
|
23
|
+
* This is useful in cases where you need to make assertions about what capabilities a RPC offers.
|
|
24
|
+
* For example, RPC methods like {@link requestAirdrop} are not available on mainnet. You can use
|
|
25
|
+
* the ability to assert on the type of RPC transport at compile time to prevent calling
|
|
26
|
+
* unimplemented methods or presuming the existence of unavailable capabilities.
|
|
27
|
+
*/
|
|
28
|
+
export type RpcTransportTestnet = RpcTransport & { '~cluster': 'testnet' };
|
|
29
|
+
/**
|
|
30
|
+
* A {@link RpcTransport} that communicates with the mainnet cluster.
|
|
31
|
+
*
|
|
32
|
+
* Such transports are understood to communicate with a RPC server that services mainnet, and as
|
|
33
|
+
* such might only be accepted for use as the transport of a {@link RpcMainnet}.
|
|
34
|
+
*
|
|
35
|
+
* This is useful in cases where you need to make assertions about what capabilities a RPC offers.
|
|
36
|
+
* For example, RPC methods like {@link requestAirdrop} are not available on mainnet. You can use
|
|
37
|
+
* the ability to assert on the type of RPC transport at compile time to prevent calling
|
|
38
|
+
* unimplemented methods or presuming the existence of unavailable capabilities.
|
|
39
|
+
*/
|
|
40
|
+
export type RpcTransportMainnet = RpcTransport & { '~cluster': 'mainnet' };
|
|
41
|
+
/**
|
|
42
|
+
* Given a {@link ClusterUrl}, this utility type will resolve to as specific a {@link RpcTransport}
|
|
43
|
+
* as possible.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* function createCustomTransport<TClusterUrl extends ClusterUrl>(
|
|
48
|
+
* clusterUrl: TClusterUrl,
|
|
49
|
+
* ): RpcTransportFromClusterUrl<TClusterUrl> {
|
|
50
|
+
* /* ... *\/
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
53
|
+
* const transport = createCustomTransport(testnet('http://api.testnet.solana.com'));
|
|
54
|
+
* transport satisfies RpcTransportTestnet; // OK
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export type RpcTransportFromClusterUrl<TClusterUrl extends ClusterUrl> = TClusterUrl extends DevnetUrl
|
|
58
|
+
? RpcTransportDevnet
|
|
59
|
+
: TClusterUrl extends TestnetUrl
|
|
60
|
+
? RpcTransportTestnet
|
|
61
|
+
: TClusterUrl extends MainnetUrl
|
|
62
|
+
? RpcTransportMainnet
|
|
63
|
+
: RpcTransport;
|
|
64
|
+
/**
|
|
65
|
+
* A {@link Rpc} that supports the RPC methods available on the devnet cluster.
|
|
66
|
+
*
|
|
67
|
+
* This is useful in cases where you need to make assertions about the suitability of a RPC for a
|
|
68
|
+
* given purpose. For example, you might like to make it a type error to combine certain types with
|
|
69
|
+
* RPCs belonging to certain clusters, at compile time.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* async function getSpecialAccountInfo(
|
|
74
|
+
* address: Address<'ReAL1111111111111111111111111111'>,
|
|
75
|
+
* rpc: RpcMainnet<unknown>,
|
|
76
|
+
* ): Promise<SpecialAccountInfo>;
|
|
77
|
+
* async function getSpecialAccountInfo(
|
|
78
|
+
* address: Address<'TeST1111111111111111111111111111'>,
|
|
79
|
+
* rpc: RpcDevnet<unknown> | RpcTestnet<unknown>,
|
|
80
|
+
* ): Promise<SpecialAccountInfo>;
|
|
81
|
+
* async function getSpecialAccountInfo(address: Address, rpc: Rpc<unknown>): Promise<SpecialAccountInfo> {
|
|
82
|
+
* /* ... *\/
|
|
83
|
+
* }
|
|
84
|
+
* const rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));
|
|
85
|
+
* await getSpecialAccountInfo(address('ReAL1111111111111111111111111111'), rpc); // ERROR
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export type RpcDevnet<TRpcMethods> = Rpc<TRpcMethods> & { '~cluster': 'devnet' };
|
|
89
|
+
/**
|
|
90
|
+
* A {@link Rpc} that supports the RPC methods available on the testnet cluster.
|
|
91
|
+
*
|
|
92
|
+
* This is useful in cases where you need to make assertions about the suitability of a RPC for a
|
|
93
|
+
* given purpose. For example, you might like to make it a type error to combine certain types with
|
|
94
|
+
* RPCs belonging to certain clusters, at compile time.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* async function getSpecialAccountInfo(
|
|
99
|
+
* address: Address<'ReAL1111111111111111111111111111'>,
|
|
100
|
+
* rpc: RpcMainnet<unknown>,
|
|
101
|
+
* ): Promise<SpecialAccountInfo>;
|
|
102
|
+
* async function getSpecialAccountInfo(
|
|
103
|
+
* address: Address<'TeST1111111111111111111111111111'>,
|
|
104
|
+
* rpc: RpcDevnet<unknown> | RpcTestnet<unknown>,
|
|
105
|
+
* ): Promise<SpecialAccountInfo>;
|
|
106
|
+
* async function getSpecialAccountInfo(address: Address, rpc: Rpc<unknown>): Promise<SpecialAccountInfo> {
|
|
107
|
+
* /* ... *\/
|
|
108
|
+
* }
|
|
109
|
+
* const rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));
|
|
110
|
+
* await getSpecialAccountInfo(address('ReAL1111111111111111111111111111'), rpc); // ERROR
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export type RpcTestnet<TRpcMethods> = Rpc<TRpcMethods> & { '~cluster': 'testnet' };
|
|
114
|
+
/**
|
|
115
|
+
* A {@link Rpc} that supports the RPC methods available on the mainnet cluster.
|
|
116
|
+
*
|
|
117
|
+
* This is useful in cases where you need to make assertions about the suitability of a RPC for a
|
|
118
|
+
* given purpose. For example, you might like to make it a type error to combine certain types with
|
|
119
|
+
* RPCs belonging to certain clusters, at compile time.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* async function getSpecialAccountInfo(
|
|
124
|
+
* address: Address<'ReAL1111111111111111111111111111'>,
|
|
125
|
+
* rpc: RpcMainnet<unknown>,
|
|
126
|
+
* ): Promise<SpecialAccountInfo>;
|
|
127
|
+
* async function getSpecialAccountInfo(
|
|
128
|
+
* address: Address<'TeST1111111111111111111111111111'>,
|
|
129
|
+
* rpc: RpcDevnet<unknown> | RpcTestnet<unknown>,
|
|
130
|
+
* ): Promise<SpecialAccountInfo>;
|
|
131
|
+
* async function getSpecialAccountInfo(address: Address, rpc: Rpc<unknown>): Promise<SpecialAccountInfo> {
|
|
132
|
+
* /* ... *\/
|
|
133
|
+
* }
|
|
134
|
+
* const rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));
|
|
135
|
+
* await getSpecialAccountInfo(address('ReAL1111111111111111111111111111'), rpc); // ERROR
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export type RpcMainnet<TRpcMethods> = Rpc<TRpcMethods> & { '~cluster': 'mainnet' };
|
|
139
|
+
/**
|
|
140
|
+
* Given a {@link RpcTransport} and a set of RPC methods denoted by `TRpcMethods`, this utility type
|
|
141
|
+
* will resolve to a {@link Rpc} that supports those methods on as specific a cluster as possible.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* function createCustomRpc<TRpcTransport extends RpcTransport>(
|
|
146
|
+
* transport: TRpcTransport,
|
|
147
|
+
* ): RpcFromTransport<MyCustomRpcMethods, TRpcTransport> {
|
|
148
|
+
* /* ... *\/
|
|
149
|
+
* }
|
|
150
|
+
* const transport = createDefaultRpcTransport({ url: mainnet('http://rpc.company') });
|
|
151
|
+
* transport satisfies RpcTransportMainnet; // OK
|
|
152
|
+
* const rpc = createCustomRpc(transport);
|
|
153
|
+
* rpc satisfies RpcMainnet<MyCustomRpcMethods>; // OK
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
export type RpcFromTransport<TRpcMethods, TRpcTransport extends RpcTransport> = TRpcTransport extends RpcTransportDevnet
|
|
157
|
+
? RpcDevnet<TRpcMethods>
|
|
158
|
+
: TRpcTransport extends RpcTransportTestnet
|
|
159
|
+
? RpcTestnet<TRpcMethods>
|
|
160
|
+
: TRpcTransport extends RpcTransportMainnet
|
|
161
|
+
? RpcMainnet<TRpcMethods>
|
|
162
|
+
: Rpc<TRpcMethods>;
|
|
163
|
+
/**
|
|
164
|
+
* Given a {@link RpcTransport} this utility type will resolve to a union of all the methods of the
|
|
165
|
+
* Solana RPC API supported by the transport's cluster.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* function createSolanaRpcFromTransport<TTransport extends RpcTransport>(
|
|
170
|
+
* transport: TTransport,
|
|
171
|
+
* ): RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport> {
|
|
172
|
+
* /* ... *\/
|
|
173
|
+
* }
|
|
174
|
+
* const transport = createDefaultRpcTransport({ url: mainnet('http://rpc.company') });
|
|
175
|
+
* transport satisfies RpcTransportMainnet; // OK
|
|
176
|
+
* const rpc = createSolanaRpcFromTransport(transport);
|
|
177
|
+
* rpc satisfies RpcMainnet<SolanaRpcApiMainnet>; // OK
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
export type SolanaRpcApiFromTransport<TTransport extends RpcTransport> = TTransport extends RpcTransportDevnet
|
|
181
|
+
? SolanaRpcApiDevnet
|
|
182
|
+
: TTransport extends RpcTransportTestnet
|
|
183
|
+
? SolanaRpcApiTestnet
|
|
184
|
+
: TTransport extends RpcTransportMainnet
|
|
185
|
+
? SolanaRpcApiMainnet
|
|
186
|
+
: SolanaRpcApi;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Given a {@link ClusterUrl} this utility type will resolve to a union of all the methods of the
|
|
190
|
+
* Solana RPC API supported by the URL's cluster.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* function createSolanaRpcFromClusterUrl<TClusterUrl extends ClusterUrl>(
|
|
195
|
+
* clusterUrl: TClusterUrl,
|
|
196
|
+
* ): Rpc<SolanaRpcApiFromClusterUrl<TClusterUrl>, RpcTransportFromClusterUrl<TClusterUrl>> {
|
|
197
|
+
* /* ... *\/
|
|
198
|
+
* }
|
|
199
|
+
* const rpc = createSolanaRpcFromClusterUrl(mainnet('http://rpc.company'));
|
|
200
|
+
* rpc satisfies Rpc<SolanaRpcApiMainnet>; // OK
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
export type SolanaRpcApiFromClusterUrl<TClusterUrl extends ClusterUrl> = SolanaRpcApiFromTransport<
|
|
204
|
+
RpcTransportFromClusterUrl<TClusterUrl>
|
|
205
|
+
>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { createSolanaRpcApi } from '@solana/rpc-api';
|
|
2
|
+
|
|
3
|
+
import { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* When you create {@link Rpc} instances with custom transports but otherwise the default RPC API
|
|
7
|
+
* behaviours, use this.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const myCustomRpc = createRpc({
|
|
12
|
+
* api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),
|
|
13
|
+
* transport: myCustomTransport,
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {
|
|
18
|
+
defaultCommitment: 'confirmed',
|
|
19
|
+
onIntegerOverflow(request, keyPath, value) {
|
|
20
|
+
throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';
|
|
2
|
+
import type { KeyPath } from '@solana/rpc-transformers';
|
|
3
|
+
|
|
4
|
+
export function createSolanaJsonRpcIntegerOverflowError(
|
|
5
|
+
methodName: string,
|
|
6
|
+
keyPath: KeyPath,
|
|
7
|
+
value: bigint,
|
|
8
|
+
): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {
|
|
9
|
+
let argumentLabel = '';
|
|
10
|
+
if (typeof keyPath[0] === 'number') {
|
|
11
|
+
const argPosition = keyPath[0] + 1;
|
|
12
|
+
const lastDigit = argPosition % 10;
|
|
13
|
+
const lastTwoDigits = argPosition % 100;
|
|
14
|
+
if (lastDigit == 1 && lastTwoDigits != 11) {
|
|
15
|
+
argumentLabel = argPosition + 'st';
|
|
16
|
+
} else if (lastDigit == 2 && lastTwoDigits != 12) {
|
|
17
|
+
argumentLabel = argPosition + 'nd';
|
|
18
|
+
} else if (lastDigit == 3 && lastTwoDigits != 13) {
|
|
19
|
+
argumentLabel = argPosition + 'rd';
|
|
20
|
+
} else {
|
|
21
|
+
argumentLabel = argPosition + 'th';
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
25
|
+
}
|
|
26
|
+
const path =
|
|
27
|
+
keyPath.length > 1
|
|
28
|
+
? keyPath
|
|
29
|
+
.slice(1)
|
|
30
|
+
.map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))
|
|
31
|
+
.join('.')
|
|
32
|
+
: undefined;
|
|
33
|
+
const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
34
|
+
argumentLabel,
|
|
35
|
+
keyPath: keyPath as readonly (number | string | symbol)[],
|
|
36
|
+
methodName,
|
|
37
|
+
optionalPathLabel: path ? ` at path \`${path}\`` : '',
|
|
38
|
+
value,
|
|
39
|
+
...(path !== undefined ? { path } : undefined),
|
|
40
|
+
});
|
|
41
|
+
safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);
|
|
42
|
+
return error;
|
|
43
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { AbortController } from '@solana/event-target-impl';
|
|
2
|
+
import type { RpcTransport } from '@solana/rpc-spec';
|
|
3
|
+
import type { RpcResponse } from '@solana/rpc-spec-types';
|
|
4
|
+
|
|
5
|
+
type CoalescedRequest = {
|
|
6
|
+
readonly abortController: AbortController;
|
|
7
|
+
numConsumers: number;
|
|
8
|
+
readonly responsePromise: Promise<RpcResponse>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type GetDeduplicationKeyFn = (payload: unknown) => string | undefined;
|
|
12
|
+
|
|
13
|
+
// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes
|
|
14
|
+
// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first
|
|
15
|
+
// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.
|
|
16
|
+
// See https://github.com/nodejs/undici/pull/2597
|
|
17
|
+
let EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;
|
|
18
|
+
function createExplicitAbortToken() {
|
|
19
|
+
// This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at
|
|
20
|
+
// the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.
|
|
21
|
+
return __DEV__
|
|
22
|
+
? {
|
|
23
|
+
EXPLICIT_ABORT_TOKEN:
|
|
24
|
+
'This object is thrown from the request that underlies a series of coalesced ' +
|
|
25
|
+
'requests when the last request in that series aborts',
|
|
26
|
+
}
|
|
27
|
+
: {};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(
|
|
31
|
+
transport: TTransport,
|
|
32
|
+
getDeduplicationKey: GetDeduplicationKeyFn,
|
|
33
|
+
): TTransport {
|
|
34
|
+
let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;
|
|
35
|
+
return async function makeCoalescedHttpRequest<TResponse>(
|
|
36
|
+
request: Parameters<RpcTransport>[0],
|
|
37
|
+
): Promise<RpcResponse<TResponse>> {
|
|
38
|
+
const { payload, signal } = request;
|
|
39
|
+
const deduplicationKey = getDeduplicationKey(payload);
|
|
40
|
+
if (deduplicationKey === undefined) {
|
|
41
|
+
return await transport(request);
|
|
42
|
+
}
|
|
43
|
+
if (!coalescedRequestsByDeduplicationKey) {
|
|
44
|
+
queueMicrotask(() => {
|
|
45
|
+
coalescedRequestsByDeduplicationKey = undefined;
|
|
46
|
+
});
|
|
47
|
+
coalescedRequestsByDeduplicationKey = {};
|
|
48
|
+
}
|
|
49
|
+
if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {
|
|
50
|
+
const abortController = new AbortController();
|
|
51
|
+
const responsePromise = (async () => {
|
|
52
|
+
try {
|
|
53
|
+
return await transport<TResponse>({
|
|
54
|
+
...request,
|
|
55
|
+
signal: abortController.signal,
|
|
56
|
+
});
|
|
57
|
+
} catch (e) {
|
|
58
|
+
if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {
|
|
59
|
+
// We triggered this error when the last subscriber aborted. Letting this
|
|
60
|
+
// error bubble up from here would cause runtime fatals where there should
|
|
61
|
+
// be none.
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
throw e;
|
|
65
|
+
}
|
|
66
|
+
})();
|
|
67
|
+
coalescedRequestsByDeduplicationKey[deduplicationKey] = {
|
|
68
|
+
abortController,
|
|
69
|
+
numConsumers: 0,
|
|
70
|
+
responsePromise,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];
|
|
74
|
+
coalescedRequest.numConsumers++;
|
|
75
|
+
if (signal) {
|
|
76
|
+
const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;
|
|
77
|
+
return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {
|
|
78
|
+
const handleAbort = (e: AbortSignalEventMap['abort']) => {
|
|
79
|
+
signal.removeEventListener('abort', handleAbort);
|
|
80
|
+
coalescedRequest.numConsumers -= 1;
|
|
81
|
+
queueMicrotask(() => {
|
|
82
|
+
if (coalescedRequest.numConsumers === 0) {
|
|
83
|
+
const abortController = coalescedRequest.abortController;
|
|
84
|
+
abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
88
|
+
reject((e.target as AbortSignal).reason);
|
|
89
|
+
};
|
|
90
|
+
signal.addEventListener('abort', handleAbort);
|
|
91
|
+
responsePromise
|
|
92
|
+
.then(resolve)
|
|
93
|
+
.catch(reject)
|
|
94
|
+
.finally(() => {
|
|
95
|
+
signal.removeEventListener('abort', handleAbort);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
} else {
|
|
99
|
+
return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;
|
|
100
|
+
}
|
|
101
|
+
} as TTransport;
|
|
102
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import fastStableStringify from '@solana/fast-stable-stringify';
|
|
2
|
+
import { isJsonRpcPayload } from '@solana/rpc-spec';
|
|
3
|
+
|
|
4
|
+
export function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {
|
|
5
|
+
return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;
|
|
6
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { pipe } from '@solana/functional';
|
|
2
|
+
import { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';
|
|
3
|
+
import type { ClusterUrl } from '@solana/rpc-types';
|
|
4
|
+
|
|
5
|
+
import { RpcTransportFromClusterUrl } from './rpc-clusters';
|
|
6
|
+
import { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';
|
|
7
|
+
import { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';
|
|
8
|
+
|
|
9
|
+
type RpcTransportConfig = Parameters<typeof createHttpTransport>[0];
|
|
10
|
+
interface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {
|
|
11
|
+
url: TClusterUrl;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function normalizeHeaders<T extends Record<string, string>>(
|
|
15
|
+
headers: T,
|
|
16
|
+
): { [K in string & keyof T as Lowercase<K>]: T[K] } {
|
|
17
|
+
const out: Record<string, string> = {};
|
|
18
|
+
for (const headerName in headers) {
|
|
19
|
+
// Lowercasing header names makes it easier to override user-supplied headers.
|
|
20
|
+
out[headerName.toLowerCase()] = headers[headerName];
|
|
21
|
+
}
|
|
22
|
+
return out as { [K in string & keyof T as Lowercase<K>]: T[K] };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a {@link RpcTransport} with some default behaviours.
|
|
27
|
+
*
|
|
28
|
+
* The default behaviours include:
|
|
29
|
+
* - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`
|
|
30
|
+
* - Logic that coalesces multiple calls in the same runloop, for the same methods with the same
|
|
31
|
+
* arguments, into a single network request.
|
|
32
|
+
* - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress
|
|
33
|
+
* responses
|
|
34
|
+
*
|
|
35
|
+
* @param config
|
|
36
|
+
*/
|
|
37
|
+
export function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(
|
|
38
|
+
config: DefaultRpcTransportConfig<TClusterUrl>,
|
|
39
|
+
): RpcTransportFromClusterUrl<TClusterUrl> {
|
|
40
|
+
return pipe(
|
|
41
|
+
createHttpTransportForSolanaRpc({
|
|
42
|
+
...config,
|
|
43
|
+
headers: {
|
|
44
|
+
...(__NODEJS__ &&
|
|
45
|
+
({
|
|
46
|
+
// Keep these headers lowercase so they will be overridden by any user-supplied headers below.
|
|
47
|
+
'accept-encoding':
|
|
48
|
+
// Natively supported by Node LTS v20.18.0 and above.
|
|
49
|
+
'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.
|
|
50
|
+
} as { [overrideHeader: string]: string })),
|
|
51
|
+
...(config.headers ? normalizeHeaders(config.headers) : undefined),
|
|
52
|
+
...({
|
|
53
|
+
// Keep these headers lowercase so they will override any user-supplied headers above.
|
|
54
|
+
'solana-client': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',
|
|
55
|
+
} as { [overrideHeader: string]: string }),
|
|
56
|
+
},
|
|
57
|
+
}) as RpcTransportFromClusterUrl<TClusterUrl>,
|
|
58
|
+
transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),
|
|
59
|
+
);
|
|
60
|
+
}
|
package/src/rpc.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createSolanaRpcApi } from '@solana/rpc-api';
|
|
2
|
+
import { createRpc, RpcTransport } from '@solana/rpc-spec';
|
|
3
|
+
import { ClusterUrl } from '@solana/rpc-types';
|
|
4
|
+
|
|
5
|
+
import type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';
|
|
6
|
+
import { DEFAULT_RPC_CONFIG } from './rpc-default-config';
|
|
7
|
+
import { createDefaultRpcTransport } from './rpc-transport';
|
|
8
|
+
|
|
9
|
+
type DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<
|
|
10
|
+
typeof createDefaultRpcTransport<TClusterUrl>
|
|
11
|
+
>[0];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some
|
|
15
|
+
* optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport
|
|
16
|
+
* config.
|
|
17
|
+
*/
|
|
18
|
+
export function createSolanaRpc<TClusterUrl extends ClusterUrl>(
|
|
19
|
+
clusterUrl: TClusterUrl,
|
|
20
|
+
config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,
|
|
21
|
+
) {
|
|
22
|
+
return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied
|
|
27
|
+
* {@link RpcTransport}.
|
|
28
|
+
*/
|
|
29
|
+
export function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {
|
|
30
|
+
return createRpc({
|
|
31
|
+
api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),
|
|
32
|
+
transport,
|
|
33
|
+
}) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;
|
|
34
|
+
}
|