{"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"]}