@solana/rpc-spec 5.1.0-canary-20251202173138 → 5.1.0-canary-20251202174830

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.
@@ -1 +1 @@
1
- {"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.browser.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 if (p === 'then') {\n return undefined;\n }\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"]}
1
+ {"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.browser.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 if (p === 'then') {\n return undefined;\n }\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"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/rpc.ts","../src/rpc-api.ts","../src/rpc-transport.ts"],"names":[],"mappings":"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","file":"index.browser.mjs","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 if (p === 'then') {\n return undefined;\n }\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"]}
1
+ {"version":3,"sources":["../src/rpc.ts","../src/rpc-api.ts","../src/rpc-transport.ts"],"names":[],"mappings":"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","file":"index.browser.mjs","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 if (p === 'then') {\n return undefined;\n }\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"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/rpc.ts","../src/rpc-api.ts","../src/rpc-transport.ts"],"names":[],"mappings":";;;;AAyDO,SAAS,UACZ,SACgB,EAAA;AAChB,EAAA,OAAO,UAAU,SAAS,CAAA;AAC9B;AAEA,SAAS,UACL,SACgB,EAAA;AAChB,EAAO,OAAA,IAAI,KAAM,CAAA,SAAA,CAAU,GAAK,EAAA;AAAA,IAC5B,cAAiB,GAAA;AACb,MAAO,OAAA,KAAA;AAAA,KACX;AAAA,IACA,cAAiB,GAAA;AACb,MAAO,OAAA,KAAA;AAAA,KACX;AAAA,IACA,GAAA,CAAI,MAAQ,EAAA,CAAA,EAAG,QAAU,EAAA;AACrB,MAAA,IAAI,MAAM,MAAQ,EAAA;AACd,QAAO,OAAA,MAAA;AAAA;AAEX,MAAA,OAAO,YAAa,SAAsB,EAAA;AACtC,QAAM,MAAA,UAAA,GAAa,EAAE,QAAS,EAAA;AAC9B,QAAA,MAAM,UAAa,GAAA,OAAA,CAAQ,GAAI,CAAA,MAAA,EAAQ,YAAY,QAAQ,CAAA;AAC3D,QAAA,IAAI,CAAC,UAAY,EAAA;AACb,UAAM,MAAA,IAAI,YAAY,kDAAoD,EAAA;AAAA,YACtE,MAAQ,EAAA,UAAA;AAAA,YACR,MAAQ,EAAA;AAAA,WACX,CAAA;AAAA;AAEL,QAAM,MAAA,OAAA,GAAU,UAAW,CAAA,GAAG,SAAS,CAAA;AACvC,QAAO,OAAA,uBAAA,CAAwB,WAAW,OAAO,CAAA;AAAA,OACrD;AAAA;AACJ,GACH,CAAA;AACL;AAEA,SAAS,uBACL,CAAA,EAAE,SAAU,EAAA,EACZ,IAC4B,EAAA;AAC5B,EAAO,OAAA;AAAA,IACH,MAAM,KAAK,OAA8C,EAAA;AACrD,MAAO,OAAA,MAAM,KAAK,OAAQ,CAAA,EAAE,QAAQ,OAAS,EAAA,WAAA,EAAa,WAAW,CAAA;AAAA;AACzE,GACJ;AACJ;ACAO,SAAS,iBAAoD,MAA4C,EAAA;AAC5G,EAAO,OAAA,IAAI,KAAM,CAAA,EAA2B,EAAA;AAAA,IACxC,cAAiB,GAAA;AACb,MAAO,OAAA,KAAA;AAAA,KACX;AAAA,IACA,cAAiB,GAAA;AACb,MAAO,OAAA,KAAA;AAAA,KACX;AAAA,IACA,OACO,IACL,EAAA;AACE,MAAM,MAAA,CAAC,CAAG,EAAA,CAAC,CAAI,GAAA,IAAA;AACf,MAAM,MAAA,UAAA,GAAa,EAAE,QAAS,EAAA;AAC9B,MAAA,OAAO,YACA,SAG0C,EAAA;AAC7C,QAAA,MAAM,aAAa,MAAO,CAAA,MAAA,CAAO,EAAE,UAAY,EAAA,MAAA,EAAQ,WAAW,CAAA;AAClE,QAAA,MAAM,UAAU,MAAQ,EAAA,kBAAA,GAAqB,MAAQ,EAAA,kBAAA,CAAmB,UAAU,CAAI,GAAA,UAAA;AACtF,QAAA,OAAO,OAAO,MAAsD,CAAA;AAAA,UAChE,OAAS,EAAA,OAAO,EAAE,MAAA,EAAQ,WAAgB,KAAA;AACtC,YAAM,MAAA,OAAA,GAAU,iBAAiB,OAAO,CAAA;AACxC,YAAA,MAAM,WAAW,MAAM,SAAA,CAAU,EAAE,OAAA,EAAS,QAAQ,CAAA;AACpD,YAAI,IAAA,CAAC,QAAQ,mBAAqB,EAAA;AAC9B,cAAO,OAAA,QAAA;AAAA;AAEX,YAAO,OAAA,MAAA,CAAO,mBAAoB,CAAA,QAAA,EAAU,OAAO,CAAA;AAAA;AACvD,SACH,CAAA;AAAA,OACL;AAAA;AACJ,GACH,CAAA;AACL;;;AChGO,SAAS,iBAAiB,OAI9B,EAAA;AACC,EAAI,IAAA,OAAA,IAAW,QAAQ,OAAO,OAAA,KAAY,YAAY,KAAM,CAAA,OAAA,CAAQ,OAAO,CAAG,EAAA;AAC1E,IAAO,OAAA,KAAA;AAAA;AAEX,EACI,OAAA,SAAA,IAAa,OACb,IAAA,OAAA,CAAQ,OAAY,KAAA,KAAA,IACpB,QAAY,IAAA,OAAA,IACZ,OAAO,OAAA,CAAQ,MAAW,KAAA,QAAA,IAC1B,QAAY,IAAA,OAAA;AAEpB","file":"index.native.mjs","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 if (p === 'then') {\n return undefined;\n }\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"]}
1
+ {"version":3,"sources":["../src/rpc.ts","../src/rpc-api.ts","../src/rpc-transport.ts"],"names":[],"mappings":"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","file":"index.native.mjs","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 if (p === 'then') {\n return undefined;\n }\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"]}
@@ -1 +1 @@
1
- {"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 if (p === 'then') {\n return undefined;\n }\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"]}
1
+ {"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 if (p === 'then') {\n return undefined;\n }\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"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/rpc.ts","../src/rpc-api.ts","../src/rpc-transport.ts"],"names":[],"mappings":";;;;AAyDO,SAAS,UACZ,SACgB,EAAA;AAChB,EAAA,OAAO,UAAU,SAAS,CAAA;AAC9B;AAEA,SAAS,UACL,SACgB,EAAA;AAChB,EAAO,OAAA,IAAI,KAAM,CAAA,SAAA,CAAU,GAAK,EAAA;AAAA,IAC5B,cAAiB,GAAA;AACb,MAAO,OAAA,KAAA;AAAA,KACX;AAAA,IACA,cAAiB,GAAA;AACb,MAAO,OAAA,KAAA;AAAA,KACX;AAAA,IACA,GAAA,CAAI,MAAQ,EAAA,CAAA,EAAG,QAAU,EAAA;AACrB,MAAA,IAAI,MAAM,MAAQ,EAAA;AACd,QAAO,OAAA,MAAA;AAAA;AAEX,MAAA,OAAO,YAAa,SAAsB,EAAA;AACtC,QAAM,MAAA,UAAA,GAAa,EAAE,QAAS,EAAA;AAC9B,QAAA,MAAM,UAAa,GAAA,OAAA,CAAQ,GAAI,CAAA,MAAA,EAAQ,YAAY,QAAQ,CAAA;AAC3D,QAAA,IAAI,CAAC,UAAY,EAAA;AACb,UAAM,MAAA,IAAI,YAAY,kDAAoD,EAAA;AAAA,YACtE,MAAQ,EAAA,UAAA;AAAA,YACR,MAAQ,EAAA;AAAA,WACX,CAAA;AAAA;AAEL,QAAM,MAAA,OAAA,GAAU,UAAW,CAAA,GAAG,SAAS,CAAA;AACvC,QAAO,OAAA,uBAAA,CAAwB,WAAW,OAAO,CAAA;AAAA,OACrD;AAAA;AACJ,GACH,CAAA;AACL;AAEA,SAAS,uBACL,CAAA,EAAE,SAAU,EAAA,EACZ,IAC4B,EAAA;AAC5B,EAAO,OAAA;AAAA,IACH,MAAM,KAAK,OAA8C,EAAA;AACrD,MAAO,OAAA,MAAM,KAAK,OAAQ,CAAA,EAAE,QAAQ,OAAS,EAAA,WAAA,EAAa,WAAW,CAAA;AAAA;AACzE,GACJ;AACJ;ACAO,SAAS,iBAAoD,MAA4C,EAAA;AAC5G,EAAO,OAAA,IAAI,KAAM,CAAA,EAA2B,EAAA;AAAA,IACxC,cAAiB,GAAA;AACb,MAAO,OAAA,KAAA;AAAA,KACX;AAAA,IACA,cAAiB,GAAA;AACb,MAAO,OAAA,KAAA;AAAA,KACX;AAAA,IACA,OACO,IACL,EAAA;AACE,MAAM,MAAA,CAAC,CAAG,EAAA,CAAC,CAAI,GAAA,IAAA;AACf,MAAM,MAAA,UAAA,GAAa,EAAE,QAAS,EAAA;AAC9B,MAAA,OAAO,YACA,SAG0C,EAAA;AAC7C,QAAA,MAAM,aAAa,MAAO,CAAA,MAAA,CAAO,EAAE,UAAY,EAAA,MAAA,EAAQ,WAAW,CAAA;AAClE,QAAA,MAAM,UAAU,MAAQ,EAAA,kBAAA,GAAqB,MAAQ,EAAA,kBAAA,CAAmB,UAAU,CAAI,GAAA,UAAA;AACtF,QAAA,OAAO,OAAO,MAAsD,CAAA;AAAA,UAChE,OAAS,EAAA,OAAO,EAAE,MAAA,EAAQ,WAAgB,KAAA;AACtC,YAAM,MAAA,OAAA,GAAU,iBAAiB,OAAO,CAAA;AACxC,YAAA,MAAM,WAAW,MAAM,SAAA,CAAU,EAAE,OAAA,EAAS,QAAQ,CAAA;AACpD,YAAI,IAAA,CAAC,QAAQ,mBAAqB,EAAA;AAC9B,cAAO,OAAA,QAAA;AAAA;AAEX,YAAO,OAAA,MAAA,CAAO,mBAAoB,CAAA,QAAA,EAAU,OAAO,CAAA;AAAA;AACvD,SACH,CAAA;AAAA,OACL;AAAA;AACJ,GACH,CAAA;AACL;;;AChGO,SAAS,iBAAiB,OAI9B,EAAA;AACC,EAAI,IAAA,OAAA,IAAW,QAAQ,OAAO,OAAA,KAAY,YAAY,KAAM,CAAA,OAAA,CAAQ,OAAO,CAAG,EAAA;AAC1E,IAAO,OAAA,KAAA;AAAA;AAEX,EACI,OAAA,SAAA,IAAa,OACb,IAAA,OAAA,CAAQ,OAAY,KAAA,KAAA,IACpB,QAAY,IAAA,OAAA,IACZ,OAAO,OAAA,CAAQ,MAAW,KAAA,QAAA,IAC1B,QAAY,IAAA,OAAA;AAEpB","file":"index.node.mjs","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 if (p === 'then') {\n return undefined;\n }\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"]}
1
+ {"version":3,"sources":["../src/rpc.ts","../src/rpc-api.ts","../src/rpc-transport.ts"],"names":[],"mappings":"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","file":"index.node.mjs","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 if (p === 'then') {\n return undefined;\n }\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solana/rpc-spec",
3
- "version": "5.1.0-canary-20251202173138",
3
+ "version": "5.1.0-canary-20251202174830",
4
4
  "description": "A generic implementation of JSON RPCs using proxies",
5
5
  "homepage": "https://www.solanakit.com/api#solanarpc-spec",
6
6
  "exports": {
@@ -55,8 +55,8 @@
55
55
  "maintained node versions"
56
56
  ],
57
57
  "dependencies": {
58
- "@solana/errors": "5.1.0-canary-20251202173138",
59
- "@solana/rpc-spec-types": "5.1.0-canary-20251202173138"
58
+ "@solana/errors": "5.1.0-canary-20251202174830",
59
+ "@solana/rpc-spec-types": "5.1.0-canary-20251202174830"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "typescript": ">=5.3.3"