{"version":3,"sources":["../src/rpc.ts","../src/rpc-api.ts","../src/rpc-transport.ts"],"names":["SolanaError","SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD","createRpcMessage"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD, SolanaError } from '@solana/errors';\nimport { Callable, Flatten, OverloadImplementations, UnionToIntersection } from '@solana/rpc-spec-types';\n\nimport { RpcApi, RpcPlan } from './rpc-api';\nimport { RpcTransport } from './rpc-transport';\n\nexport type RpcConfig<TRpcMethods, TRpcTransport extends RpcTransport> = Readonly<{\n    api: RpcApi<TRpcMethods>;\n    transport: TRpcTransport;\n}>;\n\n/**\n * An object that exposes all of the functions described by `TRpcMethods`.\n *\n * Calling each method returns a {@link PendingRpcRequest | PendingRpcRequest<TResponse>} where\n * `TResponse` is that method's response type.\n */\nexport type Rpc<TRpcMethods> = {\n    [TMethodName in keyof TRpcMethods]: PendingRpcRequestBuilder<OverloadImplementations<TRpcMethods, TMethodName>>;\n};\n\n/**\n * Pending requests are the result of calling a supported method on a {@link Rpc} object. They\n * encapsulate all of the information necessary to make the request without actually making it.\n *\n * Calling the {@link PendingRpcRequest.send | `send(options)`} method on a\n * {@link PendingRpcRequest | PendingRpcRequest<TResponse>} will trigger the request and return a\n * promise for `TResponse`.\n */\nexport type PendingRpcRequest<TResponse> = {\n    send(options?: RpcSendOptions): Promise<TResponse>;\n};\n\nexport type RpcSendOptions = Readonly<{\n    /**\n     * An optional signal that you can supply when triggering a {@link PendingRpcRequest} that you\n     * might later need to abort.\n     */\n    abortSignal?: AbortSignal;\n}>;\n\ntype PendingRpcRequestBuilder<TMethodImplementations> = UnionToIntersection<\n    Flatten<{\n        [P in keyof TMethodImplementations]: PendingRpcRequestReturnTypeMapper<TMethodImplementations[P]>;\n    }>\n>;\n\ntype PendingRpcRequestReturnTypeMapper<TMethodImplementation> =\n    // Check that this property of the TRpcMethods interface is, in fact, a function.\n    TMethodImplementation extends Callable\n        ? (...args: Parameters<TMethodImplementation>) => PendingRpcRequest<ReturnType<TMethodImplementation>>\n        : never;\n\n/**\n * Creates a {@link Rpc} instance given a {@link RpcApi | RpcApi<TRpcMethods>} and a\n * {@link RpcTransport} capable of fulfilling them.\n */\nexport function createRpc<TRpcMethods, TRpcTransport extends RpcTransport>(\n    rpcConfig: RpcConfig<TRpcMethods, TRpcTransport>,\n): Rpc<TRpcMethods> {\n    return makeProxy(rpcConfig);\n}\n\nfunction makeProxy<TRpcMethods, TRpcTransport extends RpcTransport>(\n    rpcConfig: RpcConfig<TRpcMethods, TRpcTransport>,\n): Rpc<TRpcMethods> {\n    return new Proxy(rpcConfig.api, {\n        defineProperty() {\n            return false;\n        },\n        deleteProperty() {\n            return false;\n        },\n        get(target, p, receiver) {\n            return function (...rawParams: unknown[]) {\n                const methodName = p.toString();\n                const getApiPlan = Reflect.get(target, methodName, receiver);\n                if (!getApiPlan) {\n                    throw new SolanaError(SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD, {\n                        method: methodName,\n                        params: rawParams,\n                    });\n                }\n                const apiPlan = getApiPlan(...rawParams);\n                return createPendingRpcRequest(rpcConfig, apiPlan);\n            };\n        },\n    }) as Rpc<TRpcMethods>;\n}\n\nfunction createPendingRpcRequest<TRpcMethods, TRpcTransport extends RpcTransport, TResponse>(\n    { transport }: RpcConfig<TRpcMethods, TRpcTransport>,\n    plan: RpcPlan<TResponse>,\n): PendingRpcRequest<TResponse> {\n    return {\n        async send(options?: RpcSendOptions): Promise<TResponse> {\n            return await plan.execute({ signal: options?.abortSignal, transport });\n        },\n    };\n}\n","import {\n    Callable,\n    createRpcMessage,\n    RpcRequestTransformer,\n    RpcResponse,\n    RpcResponseTransformer,\n} from '@solana/rpc-spec-types';\n\nimport type { RpcTransport } from './rpc-transport';\n\nexport type RpcApiConfig = Readonly<{\n    /**\n     * An optional function that transforms the {@link RpcRequest} before it is sent to the JSON RPC\n     * server.\n     *\n     * This is useful when the params supplied by the caller need to be transformed before\n     * forwarding the message to the server. Use cases for this include applying defaults,\n     * forwarding calls to renamed methods, and serializing complex values.\n     */\n    requestTransformer?: RpcRequestTransformer;\n    /**\n     * An optional function that transforms the {@link RpcResponse} before it is returned to the\n     * caller.\n     *\n     * Use cases for this include constructing complex data types from serialized data, and throwing\n     * exceptions.\n     */\n    responseTransformer?: RpcResponseTransformer;\n}>;\n\n/**\n * This type allows an {@link RpcApi} to describe how a particular request should be issued to the\n * JSON RPC server.\n *\n * Given a function that was called on a {@link Rpc}, this object exposes an `execute` function that\n * dictates which request will be sent, how the underlying transport will be used, and how the\n * responses will be transformed.\n *\n * This function accepts a {@link RpcTransport} and an `AbortSignal` and asynchronously returns a\n * {@link RpcResponse}. This gives us the opportunity to:\n *\n * - define the `payload` from the requested method name and parameters before passing it to the\n *   transport.\n * - call the underlying transport zero, one or multiple times depending on the use-case (e.g.\n *   caching or aggregating multiple responses).\n * - transform the response from the JSON RPC server, in case it does not match the `TResponse`\n *   specified by the {@link PendingRpcRequest | PendingRpcRequest<TResponse>} returned from that\n *   function.\n */\nexport type RpcPlan<TResponse> = {\n    execute: (\n        config: Readonly<{\n            signal?: AbortSignal;\n            transport: RpcTransport;\n        }>,\n    ) => Promise<RpcResponse<TResponse>>;\n};\n\n/**\n * For each of `TRpcMethods`, this object exposes a method with the same name that maps between its\n * input arguments and a {@link RpcPlan | RpcPlan<TResponse>} that implements the execution of a\n * JSON RPC request to fetch `TResponse`.\n */\nexport type RpcApi<TRpcMethods> = {\n    [MethodName in keyof TRpcMethods]: RpcReturnTypeMapper<TRpcMethods[MethodName]>;\n};\n\ntype RpcReturnTypeMapper<TRpcMethod> = TRpcMethod extends Callable\n    ? (...rawParams: unknown[]) => RpcPlan<ReturnType<TRpcMethod>>\n    : never;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype RpcApiMethod = (...args: any) => any;\ninterface RpcApiMethods {\n    [methodName: string]: RpcApiMethod;\n}\n\n/**\n * Creates a JavaScript proxy that converts _any_ function call called on it to a {@link RpcPlan} by\n * creating an `execute` function that:\n *\n * - sets the transport payload to a JSON RPC v2 payload object with the requested `methodName` and\n *   `params` properties, optionally transformed by {@link RpcApiConfig.requestTransformer}.\n * - transforms the transport's response using the {@link RpcApiConfig.responseTransformer}\n *   function, if provided.\n *\n * @example\n * ```ts\n * // For example, given this `RpcApi`:\n * const rpcApi = createJsonRpcApi({\n *     requestTransformer: (...rawParams) => rawParams.reverse(),\n *     responseTransformer: response => response.result,\n * });\n *\n * // ...the following function call:\n * rpcApi.foo('bar', { baz: 'bat' });\n *\n * // ...will produce a `RpcPlan` that:\n * // -   Uses the following payload: { id: 1, jsonrpc: '2.0', method: 'foo', params: [{ baz: 'bat' }, 'bar'] }.\n * // -   Returns the \"result\" property of the RPC response.\n * ```\n */\nexport function createJsonRpcApi<TRpcMethods extends RpcApiMethods>(config?: RpcApiConfig): RpcApi<TRpcMethods> {\n    return new Proxy({} as RpcApi<TRpcMethods>, {\n        defineProperty() {\n            return false;\n        },\n        deleteProperty() {\n            return false;\n        },\n        get<TMethodName extends keyof RpcApi<TRpcMethods>>(\n            ...args: Parameters<NonNullable<ProxyHandler<RpcApi<TRpcMethods>>['get']>>\n        ) {\n            const [_, p] = args;\n            const methodName = p.toString() as keyof TRpcMethods as string;\n            return function (\n                ...rawParams: Parameters<\n                    TRpcMethods[TMethodName] extends CallableFunction ? TRpcMethods[TMethodName] : never\n                >\n            ): RpcPlan<ReturnType<TRpcMethods[TMethodName]>> {\n                const rawRequest = Object.freeze({ methodName, params: rawParams });\n                const request = config?.requestTransformer ? config?.requestTransformer(rawRequest) : rawRequest;\n                return Object.freeze(<RpcPlan<ReturnType<TRpcMethods[TMethodName]>>>{\n                    execute: async ({ signal, transport }) => {\n                        const payload = createRpcMessage(request);\n                        const response = await transport({ payload, signal });\n                        if (!config?.responseTransformer) {\n                            return response;\n                        }\n                        return config.responseTransformer(response, request);\n                    },\n                });\n            };\n        },\n    });\n}\n","import { RpcResponse } from '@solana/rpc-spec-types';\n\ntype Config = Readonly<{\n    /** A value of arbitrary type to be sent to a RPC server */\n    payload: unknown;\n    /**\n     * An optional `AbortSignal` on which the `'abort'` event will be fired if the request should be\n     * cancelled.\n     */\n    signal?: AbortSignal;\n}>;\n\n/**\n * A function that can act as a transport for a {@link Rpc}. It need only return a promise for a\n * response given the supplied config.\n */\nexport type RpcTransport = {\n    <TResponse>(config: Config): Promise<RpcResponse<TResponse>>;\n};\n\n/**\n * Returns `true` if the given payload is a JSON RPC v2 payload.\n *\n * This means, the payload is an object such that:\n *\n * - It has a `jsonrpc` property with a value of `'2.0'`.\n * - It has a `method` property that is a string.\n * - It has a `params` property of any type.\n *\n * @example\n * ```ts\n * import { isJsonRpcPayload } from '@solana/rpc-spec';\n *\n * if (isJsonRpcPayload(payload)) {\n *     const payloadMethod: string = payload.method;\n *     const payloadParams: unknown = payload.params;\n * }\n * ```\n */\nexport function isJsonRpcPayload(payload: unknown): payload is Readonly<{\n    jsonrpc: '2.0';\n    method: string;\n    params: unknown;\n}> {\n    if (payload == null || typeof payload !== 'object' || Array.isArray(payload)) {\n        return false;\n    }\n    return (\n        'jsonrpc' in payload &&\n        payload.jsonrpc === '2.0' &&\n        'method' in payload &&\n        typeof payload.method === 'string' &&\n        'params' in payload\n    );\n}\n"]}