@solana/plugin-core 0.0.0 → 5.2.0-canary-20251219213520
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +14 -0
- package/dist/index.browser.cjs +35 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.mjs +33 -0
- package/dist/index.browser.mjs.map +1 -0
- package/dist/index.native.mjs +33 -0
- package/dist/index.native.mjs.map +1 -0
- package/dist/index.node.cjs +35 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.mjs +33 -0
- package/dist/index.node.mjs.map +1 -0
- package/dist/types/client.d.ts +164 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +77 -8
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2023 Solana Labs, Inc
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[![npm][npm-image]][npm-url]
|
|
2
|
+
[![npm-downloads][npm-downloads-image]][npm-url]
|
|
3
|
+
<br />
|
|
4
|
+
[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]
|
|
5
|
+
|
|
6
|
+
[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square
|
|
7
|
+
[code-style-prettier-url]: https://github.com/prettier/prettier
|
|
8
|
+
[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/plugin-core?style=flat
|
|
9
|
+
[npm-image]: https://img.shields.io/npm/v/@solana/plugin-core?style=flat
|
|
10
|
+
[npm-url]: https://www.npmjs.com/package/@solana/plugin-core
|
|
11
|
+
|
|
12
|
+
# @solana/plugin-core
|
|
13
|
+
|
|
14
|
+
This package contains utilities for creating modular Kit clients that can be extended with plugins. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/client.ts
|
|
4
|
+
function createEmptyClient() {
|
|
5
|
+
return addUse({});
|
|
6
|
+
}
|
|
7
|
+
function addUse(value) {
|
|
8
|
+
return Object.freeze({
|
|
9
|
+
...value,
|
|
10
|
+
use(plugin) {
|
|
11
|
+
const result = plugin(value);
|
|
12
|
+
return result instanceof Promise ? createAsyncClient(result) : addUse(result);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function createAsyncClient(promise) {
|
|
17
|
+
return Object.freeze({
|
|
18
|
+
catch(onrejected) {
|
|
19
|
+
return promise.then((v) => addUse(v)).catch(onrejected);
|
|
20
|
+
},
|
|
21
|
+
finally(onfinally) {
|
|
22
|
+
return promise.then((v) => addUse(v)).finally(onfinally);
|
|
23
|
+
},
|
|
24
|
+
then(onfulfilled, onrejected) {
|
|
25
|
+
return promise.then((v) => addUse(v)).then(onfulfilled, onrejected);
|
|
26
|
+
},
|
|
27
|
+
use(plugin) {
|
|
28
|
+
return createAsyncClient(promise.then(plugin));
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.createEmptyClient = createEmptyClient;
|
|
34
|
+
//# sourceMappingURL=index.browser.cjs.map
|
|
35
|
+
//# sourceMappingURL=index.browser.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;AA2KO,SAAS,iBAAA,GAAoC;AAChD,EAAA,OAAO,MAAA,CAAO,EAAE,CAAA;AACpB;AAEA,SAAS,OAA6B,KAAA,EAA6B;AAC/D,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,GAAG,KAAA;AAAA,IACH,IAA8C,MAAA,EAAsC;AAChF,MAAA,MAAM,MAAA,GAAS,OAAO,KAAK,CAAA;AAC3B,MAAA,OAAO,kBAAkB,OAAA,GAAU,iBAAA,CAAkB,MAAM,CAAA,GAAI,OAAO,MAAM,CAAA;AAAA,IAChF;AAAA,GACc,CAAA;AACtB;AAEA,SAAS,kBAAwC,OAAA,EAA6C;AAC1F,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,MAAM,UAAA,EAAY;AACd,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,MAAM,UAAU,CAAA;AAAA,IACxD,CAAA;AAAA,IACA,QAAQ,SAAA,EAAW;AACf,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,QAAQ,SAAS,CAAA;AAAA,IACzD,CAAA;AAAA,IACA,IAAA,CAAK,aAAa,UAAA,EAAY;AAC1B,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,WAAA,EAAa,UAAU,CAAA;AAAA,IACpE,CAAA;AAAA,IACA,IAA8C,MAAA,EAAsC;AAChF,MAAA,OAAO,iBAAA,CAAkB,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,IACjD;AAAA,GACmB,CAAA;AAC3B","file":"index.browser.cjs","sourcesContent":["/**\n * Defines a plugin that transforms or extends a client with additional functionality.\n *\n * For instance, plugins may add RPC capabilities, wallet integration, transaction building,\n * or other features necessary for interacting with the Solana blockchain.\n *\n * Plugins are functions that take a client object as input and return a new client object\n * or a promise that resolves to a new client object. This allows for both synchronous\n * and asynchronous transformations and extensions of the client.\n *\n * Plugins are usually applied using the `use` method on a {@link Client} or {@link AsyncClient}\n * instance, which {@link createEmptyClient} provides as a starting point.\n *\n * @typeParam TInput - The input client object type that this plugin accepts.\n * @typeParam TOutput - The output type. Either a new client object or a promise resolving to one.\n *\n * @example Basic RPC plugin\n * Given an RPC endpoint, this plugin adds an `rpc` property to the client.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc } from '@solana/kit';\n *\n * // Define a simple RPC plugin.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n *\n * // Use the plugin.\n * const client = createEmptyClient().use(rpcPlugin('https://api.mainnet-beta.solana.com'));\n * await client.rpc.getLatestBlockhash().send();\n * ```\n *\n * @example Async plugin that generates a payer wallet\n * The following plugin shows how to create an asynchronous plugin that generates a new keypair signer.\n *\n * ```ts\n * import { createEmptyClient, generateKeypairSigner } from '@solana/kit';\n *\n * // Define a plugin that generates a new keypair signer.\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n *\n * // Use the plugin.\n * const client = await createEmptyClient().use(generatedPayerPlugin());\n * console.log(client.payer.address);\n * ```\n *\n * @example Plugins with input requirements\n * A plugin can specify required properties on the input client. The example below requires the\n * client to already have a `payer` signer attached to the client in order to perform an airdrop.\n *\n * ```ts\n * import { createEmptyClient, TransactionSigner, Lamports, lamports } from '@solana/kit';\n *\n * // Define a plugin that airdrops lamports to the payer set on the client.\n * function airdropPayerPlugin(lamports: Lamports) {\n * return async <T extends { payer: TransactionSigner }>(client: T) => {\n * await myAirdropFunction(client.payer, lamports);\n * return client;\n * };\n * }\n *\n * // Use the plugins.\n * const client = await createEmptyClient()\n * .use(generatedPayerPlugin()) // This is required before using the airdrop plugin.\n * .use(airdropPayerPlugin(lamports(1_000_000_000n)));\n * ```\n *\n * @example Chaining plugins\n * Multiple plugins — asynchronous or not — can be chained together to build up complex clients.\n * The example below demonstrates how to gradually build a client with multiple plugins.\n * Notice how, despite having multiple asynchronous plugins, we only need to `await` the final result.\n * This is because the `use` method on `AsyncClient` returns another `AsyncClient`, allowing for seamless chaining.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc, createSolanaRpcSubscriptions, generateKeypairSigner } from '@solana/kit';\n *\n * // Define multiple plugins.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n * function rpcSubscriptionsPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpcSubscriptions(endpoint) });\n * }\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n * function generatedAuthorityPlugin() {\n * return async <T extends object>(client: T) => ({...client, authority: await generateKeypairSigner() });\n * }\n *\n * // Chain plugins together.\n * const client = await createEmptyClient()\n * .use(rpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(rpcSubscriptionsPlugin('wss://api.mainnet-beta.solana.com'))\n * .use(generatedPayerPlugin())\n * .use(generatedAuthorityPlugin());\n * ```\n */\nexport type ClientPlugin<TInput extends object, TOutput extends Promise<object> | object> = (input: TInput) => TOutput;\n\n/**\n * A client that can be extended with plugins.\n *\n * The `Client` type represents a client object that can be built up through\n * the application of one or more plugins. It provides a `use` method to\n * apply plugins, either synchronously (returning a new `Client`) or\n * asynchronously (returning an {@link AsyncClient}).\n *\n * @typeParam TSelf - The current shape of the client object including all applied plugins.\n */\nexport type Client<TSelf extends object> = TSelf & {\n /**\n * Applies a plugin to extend or transform the client.\n *\n * @param plugin The plugin function to apply to this client.\n * @returns Either a new `Client` (for sync plugins) or {@link AsyncClient} (for async plugins).\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => TOutput extends Promise<infer U> ? AsyncClient<U extends object ? U : never> : Client<TOutput>;\n};\n\n/**\n * An asynchronous wrapper that represents a promise of a client.\n *\n * The `AsyncClient` type is returned when an async plugin is applied to a client.\n * It behaves like a `Promise<Client<TSelf>>` but with an additional `use` method\n * that allows chaining more plugins before the promise resolves.\n *\n * This enables fluent chaining of both synchronous and asynchronous plugins\n * without having to await intermediate promises.\n *\n * @typeParam TSelf - The shape of the client object that this async client will resolve to.\n */\nexport type AsyncClient<TSelf extends object> = Promise<Client<TSelf>> & {\n /**\n * Applies a plugin to the client once it resolves.\n *\n * @param plugin The plugin function to apply to the resolved client.\n * @returns A new `AsyncClient` representing the result of applying the plugin.\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => AsyncClient<TOutput extends Promise<infer U> ? (U extends object ? U : never) : TOutput>;\n};\n\n// TODO(loris): Add examples in this docblock using real plugins once they have been published.\n\n/**\n * Creates a new empty client that can be extended with plugins.\n *\n * This serves as an entry point for building Solana clients.\n * Start with an empty client and chain the `.use()` method\n * to apply plugins that add various functionalities such as RPC\n * connectivity, wallet integration, transaction building, and more.\n *\n * See {@link ClientPlugin} for detailed examples on creating and using plugins.\n *\n * @returns An empty client object with only the `use` method available.\n *\n * @example Basic client setup\n * ```ts\n * import { createEmptyClient } from '@solana/client';\n *\n * const client = createEmptyClient()\n * .use(myRpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(myWalletPlugin());\n * ```\n */\nexport function createEmptyClient(): Client<object> {\n return addUse({});\n}\n\nfunction addUse<TSelf extends object>(value: TSelf): Client<TSelf> {\n return Object.freeze({\n ...value,\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n const result = plugin(value);\n return result instanceof Promise ? createAsyncClient(result) : addUse(result);\n },\n } as Client<TSelf>);\n}\n\nfunction createAsyncClient<TSelf extends object>(promise: Promise<TSelf>): AsyncClient<TSelf> {\n return Object.freeze({\n catch(onrejected) {\n return promise.then(v => addUse(v)).catch(onrejected);\n },\n finally(onfinally) {\n return promise.then(v => addUse(v)).finally(onfinally);\n },\n then(onfulfilled, onrejected) {\n return promise.then(v => addUse(v)).then(onfulfilled, onrejected);\n },\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n return createAsyncClient(promise.then(plugin));\n },\n } as AsyncClient<TSelf>);\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
function createEmptyClient() {
|
|
3
|
+
return addUse({});
|
|
4
|
+
}
|
|
5
|
+
function addUse(value) {
|
|
6
|
+
return Object.freeze({
|
|
7
|
+
...value,
|
|
8
|
+
use(plugin) {
|
|
9
|
+
const result = plugin(value);
|
|
10
|
+
return result instanceof Promise ? createAsyncClient(result) : addUse(result);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function createAsyncClient(promise) {
|
|
15
|
+
return Object.freeze({
|
|
16
|
+
catch(onrejected) {
|
|
17
|
+
return promise.then((v) => addUse(v)).catch(onrejected);
|
|
18
|
+
},
|
|
19
|
+
finally(onfinally) {
|
|
20
|
+
return promise.then((v) => addUse(v)).finally(onfinally);
|
|
21
|
+
},
|
|
22
|
+
then(onfulfilled, onrejected) {
|
|
23
|
+
return promise.then((v) => addUse(v)).then(onfulfilled, onrejected);
|
|
24
|
+
},
|
|
25
|
+
use(plugin) {
|
|
26
|
+
return createAsyncClient(promise.then(plugin));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { createEmptyClient };
|
|
32
|
+
//# sourceMappingURL=index.browser.mjs.map
|
|
33
|
+
//# sourceMappingURL=index.browser.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";AA2KO,SAAS,iBAAA,GAAoC;AAChD,EAAA,OAAO,MAAA,CAAO,EAAE,CAAA;AACpB;AAEA,SAAS,OAA6B,KAAA,EAA6B;AAC/D,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,GAAG,KAAA;AAAA,IACH,IAA8C,MAAA,EAAsC;AAChF,MAAA,MAAM,MAAA,GAAS,OAAO,KAAK,CAAA;AAC3B,MAAA,OAAO,kBAAkB,OAAA,GAAU,iBAAA,CAAkB,MAAM,CAAA,GAAI,OAAO,MAAM,CAAA;AAAA,IAChF;AAAA,GACc,CAAA;AACtB;AAEA,SAAS,kBAAwC,OAAA,EAA6C;AAC1F,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,MAAM,UAAA,EAAY;AACd,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,MAAM,UAAU,CAAA;AAAA,IACxD,CAAA;AAAA,IACA,QAAQ,SAAA,EAAW;AACf,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,QAAQ,SAAS,CAAA;AAAA,IACzD,CAAA;AAAA,IACA,IAAA,CAAK,aAAa,UAAA,EAAY;AAC1B,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,WAAA,EAAa,UAAU,CAAA;AAAA,IACpE,CAAA;AAAA,IACA,IAA8C,MAAA,EAAsC;AAChF,MAAA,OAAO,iBAAA,CAAkB,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,IACjD;AAAA,GACmB,CAAA;AAC3B","file":"index.browser.mjs","sourcesContent":["/**\n * Defines a plugin that transforms or extends a client with additional functionality.\n *\n * For instance, plugins may add RPC capabilities, wallet integration, transaction building,\n * or other features necessary for interacting with the Solana blockchain.\n *\n * Plugins are functions that take a client object as input and return a new client object\n * or a promise that resolves to a new client object. This allows for both synchronous\n * and asynchronous transformations and extensions of the client.\n *\n * Plugins are usually applied using the `use` method on a {@link Client} or {@link AsyncClient}\n * instance, which {@link createEmptyClient} provides as a starting point.\n *\n * @typeParam TInput - The input client object type that this plugin accepts.\n * @typeParam TOutput - The output type. Either a new client object or a promise resolving to one.\n *\n * @example Basic RPC plugin\n * Given an RPC endpoint, this plugin adds an `rpc` property to the client.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc } from '@solana/kit';\n *\n * // Define a simple RPC plugin.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n *\n * // Use the plugin.\n * const client = createEmptyClient().use(rpcPlugin('https://api.mainnet-beta.solana.com'));\n * await client.rpc.getLatestBlockhash().send();\n * ```\n *\n * @example Async plugin that generates a payer wallet\n * The following plugin shows how to create an asynchronous plugin that generates a new keypair signer.\n *\n * ```ts\n * import { createEmptyClient, generateKeypairSigner } from '@solana/kit';\n *\n * // Define a plugin that generates a new keypair signer.\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n *\n * // Use the plugin.\n * const client = await createEmptyClient().use(generatedPayerPlugin());\n * console.log(client.payer.address);\n * ```\n *\n * @example Plugins with input requirements\n * A plugin can specify required properties on the input client. The example below requires the\n * client to already have a `payer` signer attached to the client in order to perform an airdrop.\n *\n * ```ts\n * import { createEmptyClient, TransactionSigner, Lamports, lamports } from '@solana/kit';\n *\n * // Define a plugin that airdrops lamports to the payer set on the client.\n * function airdropPayerPlugin(lamports: Lamports) {\n * return async <T extends { payer: TransactionSigner }>(client: T) => {\n * await myAirdropFunction(client.payer, lamports);\n * return client;\n * };\n * }\n *\n * // Use the plugins.\n * const client = await createEmptyClient()\n * .use(generatedPayerPlugin()) // This is required before using the airdrop plugin.\n * .use(airdropPayerPlugin(lamports(1_000_000_000n)));\n * ```\n *\n * @example Chaining plugins\n * Multiple plugins — asynchronous or not — can be chained together to build up complex clients.\n * The example below demonstrates how to gradually build a client with multiple plugins.\n * Notice how, despite having multiple asynchronous plugins, we only need to `await` the final result.\n * This is because the `use` method on `AsyncClient` returns another `AsyncClient`, allowing for seamless chaining.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc, createSolanaRpcSubscriptions, generateKeypairSigner } from '@solana/kit';\n *\n * // Define multiple plugins.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n * function rpcSubscriptionsPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpcSubscriptions(endpoint) });\n * }\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n * function generatedAuthorityPlugin() {\n * return async <T extends object>(client: T) => ({...client, authority: await generateKeypairSigner() });\n * }\n *\n * // Chain plugins together.\n * const client = await createEmptyClient()\n * .use(rpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(rpcSubscriptionsPlugin('wss://api.mainnet-beta.solana.com'))\n * .use(generatedPayerPlugin())\n * .use(generatedAuthorityPlugin());\n * ```\n */\nexport type ClientPlugin<TInput extends object, TOutput extends Promise<object> | object> = (input: TInput) => TOutput;\n\n/**\n * A client that can be extended with plugins.\n *\n * The `Client` type represents a client object that can be built up through\n * the application of one or more plugins. It provides a `use` method to\n * apply plugins, either synchronously (returning a new `Client`) or\n * asynchronously (returning an {@link AsyncClient}).\n *\n * @typeParam TSelf - The current shape of the client object including all applied plugins.\n */\nexport type Client<TSelf extends object> = TSelf & {\n /**\n * Applies a plugin to extend or transform the client.\n *\n * @param plugin The plugin function to apply to this client.\n * @returns Either a new `Client` (for sync plugins) or {@link AsyncClient} (for async plugins).\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => TOutput extends Promise<infer U> ? AsyncClient<U extends object ? U : never> : Client<TOutput>;\n};\n\n/**\n * An asynchronous wrapper that represents a promise of a client.\n *\n * The `AsyncClient` type is returned when an async plugin is applied to a client.\n * It behaves like a `Promise<Client<TSelf>>` but with an additional `use` method\n * that allows chaining more plugins before the promise resolves.\n *\n * This enables fluent chaining of both synchronous and asynchronous plugins\n * without having to await intermediate promises.\n *\n * @typeParam TSelf - The shape of the client object that this async client will resolve to.\n */\nexport type AsyncClient<TSelf extends object> = Promise<Client<TSelf>> & {\n /**\n * Applies a plugin to the client once it resolves.\n *\n * @param plugin The plugin function to apply to the resolved client.\n * @returns A new `AsyncClient` representing the result of applying the plugin.\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => AsyncClient<TOutput extends Promise<infer U> ? (U extends object ? U : never) : TOutput>;\n};\n\n// TODO(loris): Add examples in this docblock using real plugins once they have been published.\n\n/**\n * Creates a new empty client that can be extended with plugins.\n *\n * This serves as an entry point for building Solana clients.\n * Start with an empty client and chain the `.use()` method\n * to apply plugins that add various functionalities such as RPC\n * connectivity, wallet integration, transaction building, and more.\n *\n * See {@link ClientPlugin} for detailed examples on creating and using plugins.\n *\n * @returns An empty client object with only the `use` method available.\n *\n * @example Basic client setup\n * ```ts\n * import { createEmptyClient } from '@solana/client';\n *\n * const client = createEmptyClient()\n * .use(myRpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(myWalletPlugin());\n * ```\n */\nexport function createEmptyClient(): Client<object> {\n return addUse({});\n}\n\nfunction addUse<TSelf extends object>(value: TSelf): Client<TSelf> {\n return Object.freeze({\n ...value,\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n const result = plugin(value);\n return result instanceof Promise ? createAsyncClient(result) : addUse(result);\n },\n } as Client<TSelf>);\n}\n\nfunction createAsyncClient<TSelf extends object>(promise: Promise<TSelf>): AsyncClient<TSelf> {\n return Object.freeze({\n catch(onrejected) {\n return promise.then(v => addUse(v)).catch(onrejected);\n },\n finally(onfinally) {\n return promise.then(v => addUse(v)).finally(onfinally);\n },\n then(onfulfilled, onrejected) {\n return promise.then(v => addUse(v)).then(onfulfilled, onrejected);\n },\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n return createAsyncClient(promise.then(plugin));\n },\n } as AsyncClient<TSelf>);\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
function createEmptyClient() {
|
|
3
|
+
return addUse({});
|
|
4
|
+
}
|
|
5
|
+
function addUse(value) {
|
|
6
|
+
return Object.freeze({
|
|
7
|
+
...value,
|
|
8
|
+
use(plugin) {
|
|
9
|
+
const result = plugin(value);
|
|
10
|
+
return result instanceof Promise ? createAsyncClient(result) : addUse(result);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function createAsyncClient(promise) {
|
|
15
|
+
return Object.freeze({
|
|
16
|
+
catch(onrejected) {
|
|
17
|
+
return promise.then((v) => addUse(v)).catch(onrejected);
|
|
18
|
+
},
|
|
19
|
+
finally(onfinally) {
|
|
20
|
+
return promise.then((v) => addUse(v)).finally(onfinally);
|
|
21
|
+
},
|
|
22
|
+
then(onfulfilled, onrejected) {
|
|
23
|
+
return promise.then((v) => addUse(v)).then(onfulfilled, onrejected);
|
|
24
|
+
},
|
|
25
|
+
use(plugin) {
|
|
26
|
+
return createAsyncClient(promise.then(plugin));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { createEmptyClient };
|
|
32
|
+
//# sourceMappingURL=index.native.mjs.map
|
|
33
|
+
//# sourceMappingURL=index.native.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";AA2KO,SAAS,iBAAA,GAAoC;AAChD,EAAA,OAAO,MAAA,CAAO,EAAE,CAAA;AACpB;AAEA,SAAS,OAA6B,KAAA,EAA6B;AAC/D,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,GAAG,KAAA;AAAA,IACH,IAA8C,MAAA,EAAsC;AAChF,MAAA,MAAM,MAAA,GAAS,OAAO,KAAK,CAAA;AAC3B,MAAA,OAAO,kBAAkB,OAAA,GAAU,iBAAA,CAAkB,MAAM,CAAA,GAAI,OAAO,MAAM,CAAA;AAAA,IAChF;AAAA,GACc,CAAA;AACtB;AAEA,SAAS,kBAAwC,OAAA,EAA6C;AAC1F,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,MAAM,UAAA,EAAY;AACd,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,MAAM,UAAU,CAAA;AAAA,IACxD,CAAA;AAAA,IACA,QAAQ,SAAA,EAAW;AACf,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,QAAQ,SAAS,CAAA;AAAA,IACzD,CAAA;AAAA,IACA,IAAA,CAAK,aAAa,UAAA,EAAY;AAC1B,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,WAAA,EAAa,UAAU,CAAA;AAAA,IACpE,CAAA;AAAA,IACA,IAA8C,MAAA,EAAsC;AAChF,MAAA,OAAO,iBAAA,CAAkB,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,IACjD;AAAA,GACmB,CAAA;AAC3B","file":"index.native.mjs","sourcesContent":["/**\n * Defines a plugin that transforms or extends a client with additional functionality.\n *\n * For instance, plugins may add RPC capabilities, wallet integration, transaction building,\n * or other features necessary for interacting with the Solana blockchain.\n *\n * Plugins are functions that take a client object as input and return a new client object\n * or a promise that resolves to a new client object. This allows for both synchronous\n * and asynchronous transformations and extensions of the client.\n *\n * Plugins are usually applied using the `use` method on a {@link Client} or {@link AsyncClient}\n * instance, which {@link createEmptyClient} provides as a starting point.\n *\n * @typeParam TInput - The input client object type that this plugin accepts.\n * @typeParam TOutput - The output type. Either a new client object or a promise resolving to one.\n *\n * @example Basic RPC plugin\n * Given an RPC endpoint, this plugin adds an `rpc` property to the client.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc } from '@solana/kit';\n *\n * // Define a simple RPC plugin.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n *\n * // Use the plugin.\n * const client = createEmptyClient().use(rpcPlugin('https://api.mainnet-beta.solana.com'));\n * await client.rpc.getLatestBlockhash().send();\n * ```\n *\n * @example Async plugin that generates a payer wallet\n * The following plugin shows how to create an asynchronous plugin that generates a new keypair signer.\n *\n * ```ts\n * import { createEmptyClient, generateKeypairSigner } from '@solana/kit';\n *\n * // Define a plugin that generates a new keypair signer.\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n *\n * // Use the plugin.\n * const client = await createEmptyClient().use(generatedPayerPlugin());\n * console.log(client.payer.address);\n * ```\n *\n * @example Plugins with input requirements\n * A plugin can specify required properties on the input client. The example below requires the\n * client to already have a `payer` signer attached to the client in order to perform an airdrop.\n *\n * ```ts\n * import { createEmptyClient, TransactionSigner, Lamports, lamports } from '@solana/kit';\n *\n * // Define a plugin that airdrops lamports to the payer set on the client.\n * function airdropPayerPlugin(lamports: Lamports) {\n * return async <T extends { payer: TransactionSigner }>(client: T) => {\n * await myAirdropFunction(client.payer, lamports);\n * return client;\n * };\n * }\n *\n * // Use the plugins.\n * const client = await createEmptyClient()\n * .use(generatedPayerPlugin()) // This is required before using the airdrop plugin.\n * .use(airdropPayerPlugin(lamports(1_000_000_000n)));\n * ```\n *\n * @example Chaining plugins\n * Multiple plugins — asynchronous or not — can be chained together to build up complex clients.\n * The example below demonstrates how to gradually build a client with multiple plugins.\n * Notice how, despite having multiple asynchronous plugins, we only need to `await` the final result.\n * This is because the `use` method on `AsyncClient` returns another `AsyncClient`, allowing for seamless chaining.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc, createSolanaRpcSubscriptions, generateKeypairSigner } from '@solana/kit';\n *\n * // Define multiple plugins.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n * function rpcSubscriptionsPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpcSubscriptions(endpoint) });\n * }\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n * function generatedAuthorityPlugin() {\n * return async <T extends object>(client: T) => ({...client, authority: await generateKeypairSigner() });\n * }\n *\n * // Chain plugins together.\n * const client = await createEmptyClient()\n * .use(rpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(rpcSubscriptionsPlugin('wss://api.mainnet-beta.solana.com'))\n * .use(generatedPayerPlugin())\n * .use(generatedAuthorityPlugin());\n * ```\n */\nexport type ClientPlugin<TInput extends object, TOutput extends Promise<object> | object> = (input: TInput) => TOutput;\n\n/**\n * A client that can be extended with plugins.\n *\n * The `Client` type represents a client object that can be built up through\n * the application of one or more plugins. It provides a `use` method to\n * apply plugins, either synchronously (returning a new `Client`) or\n * asynchronously (returning an {@link AsyncClient}).\n *\n * @typeParam TSelf - The current shape of the client object including all applied plugins.\n */\nexport type Client<TSelf extends object> = TSelf & {\n /**\n * Applies a plugin to extend or transform the client.\n *\n * @param plugin The plugin function to apply to this client.\n * @returns Either a new `Client` (for sync plugins) or {@link AsyncClient} (for async plugins).\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => TOutput extends Promise<infer U> ? AsyncClient<U extends object ? U : never> : Client<TOutput>;\n};\n\n/**\n * An asynchronous wrapper that represents a promise of a client.\n *\n * The `AsyncClient` type is returned when an async plugin is applied to a client.\n * It behaves like a `Promise<Client<TSelf>>` but with an additional `use` method\n * that allows chaining more plugins before the promise resolves.\n *\n * This enables fluent chaining of both synchronous and asynchronous plugins\n * without having to await intermediate promises.\n *\n * @typeParam TSelf - The shape of the client object that this async client will resolve to.\n */\nexport type AsyncClient<TSelf extends object> = Promise<Client<TSelf>> & {\n /**\n * Applies a plugin to the client once it resolves.\n *\n * @param plugin The plugin function to apply to the resolved client.\n * @returns A new `AsyncClient` representing the result of applying the plugin.\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => AsyncClient<TOutput extends Promise<infer U> ? (U extends object ? U : never) : TOutput>;\n};\n\n// TODO(loris): Add examples in this docblock using real plugins once they have been published.\n\n/**\n * Creates a new empty client that can be extended with plugins.\n *\n * This serves as an entry point for building Solana clients.\n * Start with an empty client and chain the `.use()` method\n * to apply plugins that add various functionalities such as RPC\n * connectivity, wallet integration, transaction building, and more.\n *\n * See {@link ClientPlugin} for detailed examples on creating and using plugins.\n *\n * @returns An empty client object with only the `use` method available.\n *\n * @example Basic client setup\n * ```ts\n * import { createEmptyClient } from '@solana/client';\n *\n * const client = createEmptyClient()\n * .use(myRpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(myWalletPlugin());\n * ```\n */\nexport function createEmptyClient(): Client<object> {\n return addUse({});\n}\n\nfunction addUse<TSelf extends object>(value: TSelf): Client<TSelf> {\n return Object.freeze({\n ...value,\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n const result = plugin(value);\n return result instanceof Promise ? createAsyncClient(result) : addUse(result);\n },\n } as Client<TSelf>);\n}\n\nfunction createAsyncClient<TSelf extends object>(promise: Promise<TSelf>): AsyncClient<TSelf> {\n return Object.freeze({\n catch(onrejected) {\n return promise.then(v => addUse(v)).catch(onrejected);\n },\n finally(onfinally) {\n return promise.then(v => addUse(v)).finally(onfinally);\n },\n then(onfulfilled, onrejected) {\n return promise.then(v => addUse(v)).then(onfulfilled, onrejected);\n },\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n return createAsyncClient(promise.then(plugin));\n },\n } as AsyncClient<TSelf>);\n}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/client.ts
|
|
4
|
+
function createEmptyClient() {
|
|
5
|
+
return addUse({});
|
|
6
|
+
}
|
|
7
|
+
function addUse(value) {
|
|
8
|
+
return Object.freeze({
|
|
9
|
+
...value,
|
|
10
|
+
use(plugin) {
|
|
11
|
+
const result = plugin(value);
|
|
12
|
+
return result instanceof Promise ? createAsyncClient(result) : addUse(result);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function createAsyncClient(promise) {
|
|
17
|
+
return Object.freeze({
|
|
18
|
+
catch(onrejected) {
|
|
19
|
+
return promise.then((v) => addUse(v)).catch(onrejected);
|
|
20
|
+
},
|
|
21
|
+
finally(onfinally) {
|
|
22
|
+
return promise.then((v) => addUse(v)).finally(onfinally);
|
|
23
|
+
},
|
|
24
|
+
then(onfulfilled, onrejected) {
|
|
25
|
+
return promise.then((v) => addUse(v)).then(onfulfilled, onrejected);
|
|
26
|
+
},
|
|
27
|
+
use(plugin) {
|
|
28
|
+
return createAsyncClient(promise.then(plugin));
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.createEmptyClient = createEmptyClient;
|
|
34
|
+
//# sourceMappingURL=index.node.cjs.map
|
|
35
|
+
//# sourceMappingURL=index.node.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;AA2KO,SAAS,iBAAA,GAAoC;AAChD,EAAA,OAAO,MAAA,CAAO,EAAE,CAAA;AACpB;AAEA,SAAS,OAA6B,KAAA,EAA6B;AAC/D,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,GAAG,KAAA;AAAA,IACH,IAA8C,MAAA,EAAsC;AAChF,MAAA,MAAM,MAAA,GAAS,OAAO,KAAK,CAAA;AAC3B,MAAA,OAAO,kBAAkB,OAAA,GAAU,iBAAA,CAAkB,MAAM,CAAA,GAAI,OAAO,MAAM,CAAA;AAAA,IAChF;AAAA,GACc,CAAA;AACtB;AAEA,SAAS,kBAAwC,OAAA,EAA6C;AAC1F,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,MAAM,UAAA,EAAY;AACd,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,MAAM,UAAU,CAAA;AAAA,IACxD,CAAA;AAAA,IACA,QAAQ,SAAA,EAAW;AACf,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,QAAQ,SAAS,CAAA;AAAA,IACzD,CAAA;AAAA,IACA,IAAA,CAAK,aAAa,UAAA,EAAY;AAC1B,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,WAAA,EAAa,UAAU,CAAA;AAAA,IACpE,CAAA;AAAA,IACA,IAA8C,MAAA,EAAsC;AAChF,MAAA,OAAO,iBAAA,CAAkB,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,IACjD;AAAA,GACmB,CAAA;AAC3B","file":"index.node.cjs","sourcesContent":["/**\n * Defines a plugin that transforms or extends a client with additional functionality.\n *\n * For instance, plugins may add RPC capabilities, wallet integration, transaction building,\n * or other features necessary for interacting with the Solana blockchain.\n *\n * Plugins are functions that take a client object as input and return a new client object\n * or a promise that resolves to a new client object. This allows for both synchronous\n * and asynchronous transformations and extensions of the client.\n *\n * Plugins are usually applied using the `use` method on a {@link Client} or {@link AsyncClient}\n * instance, which {@link createEmptyClient} provides as a starting point.\n *\n * @typeParam TInput - The input client object type that this plugin accepts.\n * @typeParam TOutput - The output type. Either a new client object or a promise resolving to one.\n *\n * @example Basic RPC plugin\n * Given an RPC endpoint, this plugin adds an `rpc` property to the client.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc } from '@solana/kit';\n *\n * // Define a simple RPC plugin.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n *\n * // Use the plugin.\n * const client = createEmptyClient().use(rpcPlugin('https://api.mainnet-beta.solana.com'));\n * await client.rpc.getLatestBlockhash().send();\n * ```\n *\n * @example Async plugin that generates a payer wallet\n * The following plugin shows how to create an asynchronous plugin that generates a new keypair signer.\n *\n * ```ts\n * import { createEmptyClient, generateKeypairSigner } from '@solana/kit';\n *\n * // Define a plugin that generates a new keypair signer.\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n *\n * // Use the plugin.\n * const client = await createEmptyClient().use(generatedPayerPlugin());\n * console.log(client.payer.address);\n * ```\n *\n * @example Plugins with input requirements\n * A plugin can specify required properties on the input client. The example below requires the\n * client to already have a `payer` signer attached to the client in order to perform an airdrop.\n *\n * ```ts\n * import { createEmptyClient, TransactionSigner, Lamports, lamports } from '@solana/kit';\n *\n * // Define a plugin that airdrops lamports to the payer set on the client.\n * function airdropPayerPlugin(lamports: Lamports) {\n * return async <T extends { payer: TransactionSigner }>(client: T) => {\n * await myAirdropFunction(client.payer, lamports);\n * return client;\n * };\n * }\n *\n * // Use the plugins.\n * const client = await createEmptyClient()\n * .use(generatedPayerPlugin()) // This is required before using the airdrop plugin.\n * .use(airdropPayerPlugin(lamports(1_000_000_000n)));\n * ```\n *\n * @example Chaining plugins\n * Multiple plugins — asynchronous or not — can be chained together to build up complex clients.\n * The example below demonstrates how to gradually build a client with multiple plugins.\n * Notice how, despite having multiple asynchronous plugins, we only need to `await` the final result.\n * This is because the `use` method on `AsyncClient` returns another `AsyncClient`, allowing for seamless chaining.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc, createSolanaRpcSubscriptions, generateKeypairSigner } from '@solana/kit';\n *\n * // Define multiple plugins.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n * function rpcSubscriptionsPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpcSubscriptions(endpoint) });\n * }\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n * function generatedAuthorityPlugin() {\n * return async <T extends object>(client: T) => ({...client, authority: await generateKeypairSigner() });\n * }\n *\n * // Chain plugins together.\n * const client = await createEmptyClient()\n * .use(rpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(rpcSubscriptionsPlugin('wss://api.mainnet-beta.solana.com'))\n * .use(generatedPayerPlugin())\n * .use(generatedAuthorityPlugin());\n * ```\n */\nexport type ClientPlugin<TInput extends object, TOutput extends Promise<object> | object> = (input: TInput) => TOutput;\n\n/**\n * A client that can be extended with plugins.\n *\n * The `Client` type represents a client object that can be built up through\n * the application of one or more plugins. It provides a `use` method to\n * apply plugins, either synchronously (returning a new `Client`) or\n * asynchronously (returning an {@link AsyncClient}).\n *\n * @typeParam TSelf - The current shape of the client object including all applied plugins.\n */\nexport type Client<TSelf extends object> = TSelf & {\n /**\n * Applies a plugin to extend or transform the client.\n *\n * @param plugin The plugin function to apply to this client.\n * @returns Either a new `Client` (for sync plugins) or {@link AsyncClient} (for async plugins).\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => TOutput extends Promise<infer U> ? AsyncClient<U extends object ? U : never> : Client<TOutput>;\n};\n\n/**\n * An asynchronous wrapper that represents a promise of a client.\n *\n * The `AsyncClient` type is returned when an async plugin is applied to a client.\n * It behaves like a `Promise<Client<TSelf>>` but with an additional `use` method\n * that allows chaining more plugins before the promise resolves.\n *\n * This enables fluent chaining of both synchronous and asynchronous plugins\n * without having to await intermediate promises.\n *\n * @typeParam TSelf - The shape of the client object that this async client will resolve to.\n */\nexport type AsyncClient<TSelf extends object> = Promise<Client<TSelf>> & {\n /**\n * Applies a plugin to the client once it resolves.\n *\n * @param plugin The plugin function to apply to the resolved client.\n * @returns A new `AsyncClient` representing the result of applying the plugin.\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => AsyncClient<TOutput extends Promise<infer U> ? (U extends object ? U : never) : TOutput>;\n};\n\n// TODO(loris): Add examples in this docblock using real plugins once they have been published.\n\n/**\n * Creates a new empty client that can be extended with plugins.\n *\n * This serves as an entry point for building Solana clients.\n * Start with an empty client and chain the `.use()` method\n * to apply plugins that add various functionalities such as RPC\n * connectivity, wallet integration, transaction building, and more.\n *\n * See {@link ClientPlugin} for detailed examples on creating and using plugins.\n *\n * @returns An empty client object with only the `use` method available.\n *\n * @example Basic client setup\n * ```ts\n * import { createEmptyClient } from '@solana/client';\n *\n * const client = createEmptyClient()\n * .use(myRpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(myWalletPlugin());\n * ```\n */\nexport function createEmptyClient(): Client<object> {\n return addUse({});\n}\n\nfunction addUse<TSelf extends object>(value: TSelf): Client<TSelf> {\n return Object.freeze({\n ...value,\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n const result = plugin(value);\n return result instanceof Promise ? createAsyncClient(result) : addUse(result);\n },\n } as Client<TSelf>);\n}\n\nfunction createAsyncClient<TSelf extends object>(promise: Promise<TSelf>): AsyncClient<TSelf> {\n return Object.freeze({\n catch(onrejected) {\n return promise.then(v => addUse(v)).catch(onrejected);\n },\n finally(onfinally) {\n return promise.then(v => addUse(v)).finally(onfinally);\n },\n then(onfulfilled, onrejected) {\n return promise.then(v => addUse(v)).then(onfulfilled, onrejected);\n },\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n return createAsyncClient(promise.then(plugin));\n },\n } as AsyncClient<TSelf>);\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
function createEmptyClient() {
|
|
3
|
+
return addUse({});
|
|
4
|
+
}
|
|
5
|
+
function addUse(value) {
|
|
6
|
+
return Object.freeze({
|
|
7
|
+
...value,
|
|
8
|
+
use(plugin) {
|
|
9
|
+
const result = plugin(value);
|
|
10
|
+
return result instanceof Promise ? createAsyncClient(result) : addUse(result);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function createAsyncClient(promise) {
|
|
15
|
+
return Object.freeze({
|
|
16
|
+
catch(onrejected) {
|
|
17
|
+
return promise.then((v) => addUse(v)).catch(onrejected);
|
|
18
|
+
},
|
|
19
|
+
finally(onfinally) {
|
|
20
|
+
return promise.then((v) => addUse(v)).finally(onfinally);
|
|
21
|
+
},
|
|
22
|
+
then(onfulfilled, onrejected) {
|
|
23
|
+
return promise.then((v) => addUse(v)).then(onfulfilled, onrejected);
|
|
24
|
+
},
|
|
25
|
+
use(plugin) {
|
|
26
|
+
return createAsyncClient(promise.then(plugin));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { createEmptyClient };
|
|
32
|
+
//# sourceMappingURL=index.node.mjs.map
|
|
33
|
+
//# sourceMappingURL=index.node.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";AA2KO,SAAS,iBAAA,GAAoC;AAChD,EAAA,OAAO,MAAA,CAAO,EAAE,CAAA;AACpB;AAEA,SAAS,OAA6B,KAAA,EAA6B;AAC/D,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,GAAG,KAAA;AAAA,IACH,IAA8C,MAAA,EAAsC;AAChF,MAAA,MAAM,MAAA,GAAS,OAAO,KAAK,CAAA;AAC3B,MAAA,OAAO,kBAAkB,OAAA,GAAU,iBAAA,CAAkB,MAAM,CAAA,GAAI,OAAO,MAAM,CAAA;AAAA,IAChF;AAAA,GACc,CAAA;AACtB;AAEA,SAAS,kBAAwC,OAAA,EAA6C;AAC1F,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,MAAM,UAAA,EAAY;AACd,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,MAAM,UAAU,CAAA;AAAA,IACxD,CAAA;AAAA,IACA,QAAQ,SAAA,EAAW;AACf,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,QAAQ,SAAS,CAAA;AAAA,IACzD,CAAA;AAAA,IACA,IAAA,CAAK,aAAa,UAAA,EAAY;AAC1B,MAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,WAAA,EAAa,UAAU,CAAA;AAAA,IACpE,CAAA;AAAA,IACA,IAA8C,MAAA,EAAsC;AAChF,MAAA,OAAO,iBAAA,CAAkB,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,IACjD;AAAA,GACmB,CAAA;AAC3B","file":"index.node.mjs","sourcesContent":["/**\n * Defines a plugin that transforms or extends a client with additional functionality.\n *\n * For instance, plugins may add RPC capabilities, wallet integration, transaction building,\n * or other features necessary for interacting with the Solana blockchain.\n *\n * Plugins are functions that take a client object as input and return a new client object\n * or a promise that resolves to a new client object. This allows for both synchronous\n * and asynchronous transformations and extensions of the client.\n *\n * Plugins are usually applied using the `use` method on a {@link Client} or {@link AsyncClient}\n * instance, which {@link createEmptyClient} provides as a starting point.\n *\n * @typeParam TInput - The input client object type that this plugin accepts.\n * @typeParam TOutput - The output type. Either a new client object or a promise resolving to one.\n *\n * @example Basic RPC plugin\n * Given an RPC endpoint, this plugin adds an `rpc` property to the client.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc } from '@solana/kit';\n *\n * // Define a simple RPC plugin.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n *\n * // Use the plugin.\n * const client = createEmptyClient().use(rpcPlugin('https://api.mainnet-beta.solana.com'));\n * await client.rpc.getLatestBlockhash().send();\n * ```\n *\n * @example Async plugin that generates a payer wallet\n * The following plugin shows how to create an asynchronous plugin that generates a new keypair signer.\n *\n * ```ts\n * import { createEmptyClient, generateKeypairSigner } from '@solana/kit';\n *\n * // Define a plugin that generates a new keypair signer.\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n *\n * // Use the plugin.\n * const client = await createEmptyClient().use(generatedPayerPlugin());\n * console.log(client.payer.address);\n * ```\n *\n * @example Plugins with input requirements\n * A plugin can specify required properties on the input client. The example below requires the\n * client to already have a `payer` signer attached to the client in order to perform an airdrop.\n *\n * ```ts\n * import { createEmptyClient, TransactionSigner, Lamports, lamports } from '@solana/kit';\n *\n * // Define a plugin that airdrops lamports to the payer set on the client.\n * function airdropPayerPlugin(lamports: Lamports) {\n * return async <T extends { payer: TransactionSigner }>(client: T) => {\n * await myAirdropFunction(client.payer, lamports);\n * return client;\n * };\n * }\n *\n * // Use the plugins.\n * const client = await createEmptyClient()\n * .use(generatedPayerPlugin()) // This is required before using the airdrop plugin.\n * .use(airdropPayerPlugin(lamports(1_000_000_000n)));\n * ```\n *\n * @example Chaining plugins\n * Multiple plugins — asynchronous or not — can be chained together to build up complex clients.\n * The example below demonstrates how to gradually build a client with multiple plugins.\n * Notice how, despite having multiple asynchronous plugins, we only need to `await` the final result.\n * This is because the `use` method on `AsyncClient` returns another `AsyncClient`, allowing for seamless chaining.\n *\n * ```ts\n * import { createEmptyClient, createSolanaRpc, createSolanaRpcSubscriptions, generateKeypairSigner } from '@solana/kit';\n *\n * // Define multiple plugins.\n * function rpcPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n * function rpcSubscriptionsPlugin(endpoint: string) {\n * return <T extends object>(client: T) => ({...client, rpc: createSolanaRpcSubscriptions(endpoint) });\n * }\n * function generatedPayerPlugin() {\n * return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n * function generatedAuthorityPlugin() {\n * return async <T extends object>(client: T) => ({...client, authority: await generateKeypairSigner() });\n * }\n *\n * // Chain plugins together.\n * const client = await createEmptyClient()\n * .use(rpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(rpcSubscriptionsPlugin('wss://api.mainnet-beta.solana.com'))\n * .use(generatedPayerPlugin())\n * .use(generatedAuthorityPlugin());\n * ```\n */\nexport type ClientPlugin<TInput extends object, TOutput extends Promise<object> | object> = (input: TInput) => TOutput;\n\n/**\n * A client that can be extended with plugins.\n *\n * The `Client` type represents a client object that can be built up through\n * the application of one or more plugins. It provides a `use` method to\n * apply plugins, either synchronously (returning a new `Client`) or\n * asynchronously (returning an {@link AsyncClient}).\n *\n * @typeParam TSelf - The current shape of the client object including all applied plugins.\n */\nexport type Client<TSelf extends object> = TSelf & {\n /**\n * Applies a plugin to extend or transform the client.\n *\n * @param plugin The plugin function to apply to this client.\n * @returns Either a new `Client` (for sync plugins) or {@link AsyncClient} (for async plugins).\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => TOutput extends Promise<infer U> ? AsyncClient<U extends object ? U : never> : Client<TOutput>;\n};\n\n/**\n * An asynchronous wrapper that represents a promise of a client.\n *\n * The `AsyncClient` type is returned when an async plugin is applied to a client.\n * It behaves like a `Promise<Client<TSelf>>` but with an additional `use` method\n * that allows chaining more plugins before the promise resolves.\n *\n * This enables fluent chaining of both synchronous and asynchronous plugins\n * without having to await intermediate promises.\n *\n * @typeParam TSelf - The shape of the client object that this async client will resolve to.\n */\nexport type AsyncClient<TSelf extends object> = Promise<Client<TSelf>> & {\n /**\n * Applies a plugin to the client once it resolves.\n *\n * @param plugin The plugin function to apply to the resolved client.\n * @returns A new `AsyncClient` representing the result of applying the plugin.\n */\n readonly use: <TOutput extends Promise<object> | object>(\n plugin: ClientPlugin<TSelf, TOutput>,\n ) => AsyncClient<TOutput extends Promise<infer U> ? (U extends object ? U : never) : TOutput>;\n};\n\n// TODO(loris): Add examples in this docblock using real plugins once they have been published.\n\n/**\n * Creates a new empty client that can be extended with plugins.\n *\n * This serves as an entry point for building Solana clients.\n * Start with an empty client and chain the `.use()` method\n * to apply plugins that add various functionalities such as RPC\n * connectivity, wallet integration, transaction building, and more.\n *\n * See {@link ClientPlugin} for detailed examples on creating and using plugins.\n *\n * @returns An empty client object with only the `use` method available.\n *\n * @example Basic client setup\n * ```ts\n * import { createEmptyClient } from '@solana/client';\n *\n * const client = createEmptyClient()\n * .use(myRpcPlugin('https://api.mainnet-beta.solana.com'))\n * .use(myWalletPlugin());\n * ```\n */\nexport function createEmptyClient(): Client<object> {\n return addUse({});\n}\n\nfunction addUse<TSelf extends object>(value: TSelf): Client<TSelf> {\n return Object.freeze({\n ...value,\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n const result = plugin(value);\n return result instanceof Promise ? createAsyncClient(result) : addUse(result);\n },\n } as Client<TSelf>);\n}\n\nfunction createAsyncClient<TSelf extends object>(promise: Promise<TSelf>): AsyncClient<TSelf> {\n return Object.freeze({\n catch(onrejected) {\n return promise.then(v => addUse(v)).catch(onrejected);\n },\n finally(onfinally) {\n return promise.then(v => addUse(v)).finally(onfinally);\n },\n then(onfulfilled, onrejected) {\n return promise.then(v => addUse(v)).then(onfulfilled, onrejected);\n },\n use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n return createAsyncClient(promise.then(plugin));\n },\n } as AsyncClient<TSelf>);\n}\n"]}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines a plugin that transforms or extends a client with additional functionality.
|
|
3
|
+
*
|
|
4
|
+
* For instance, plugins may add RPC capabilities, wallet integration, transaction building,
|
|
5
|
+
* or other features necessary for interacting with the Solana blockchain.
|
|
6
|
+
*
|
|
7
|
+
* Plugins are functions that take a client object as input and return a new client object
|
|
8
|
+
* or a promise that resolves to a new client object. This allows for both synchronous
|
|
9
|
+
* and asynchronous transformations and extensions of the client.
|
|
10
|
+
*
|
|
11
|
+
* Plugins are usually applied using the `use` method on a {@link Client} or {@link AsyncClient}
|
|
12
|
+
* instance, which {@link createEmptyClient} provides as a starting point.
|
|
13
|
+
*
|
|
14
|
+
* @typeParam TInput - The input client object type that this plugin accepts.
|
|
15
|
+
* @typeParam TOutput - The output type. Either a new client object or a promise resolving to one.
|
|
16
|
+
*
|
|
17
|
+
* @example Basic RPC plugin
|
|
18
|
+
* Given an RPC endpoint, this plugin adds an `rpc` property to the client.
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { createEmptyClient, createSolanaRpc } from '@solana/kit';
|
|
22
|
+
*
|
|
23
|
+
* // Define a simple RPC plugin.
|
|
24
|
+
* function rpcPlugin(endpoint: string) {
|
|
25
|
+
* return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* // Use the plugin.
|
|
29
|
+
* const client = createEmptyClient().use(rpcPlugin('https://api.mainnet-beta.solana.com'));
|
|
30
|
+
* await client.rpc.getLatestBlockhash().send();
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example Async plugin that generates a payer wallet
|
|
34
|
+
* The following plugin shows how to create an asynchronous plugin that generates a new keypair signer.
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { createEmptyClient, generateKeypairSigner } from '@solana/kit';
|
|
38
|
+
*
|
|
39
|
+
* // Define a plugin that generates a new keypair signer.
|
|
40
|
+
* function generatedPayerPlugin() {
|
|
41
|
+
* return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* // Use the plugin.
|
|
45
|
+
* const client = await createEmptyClient().use(generatedPayerPlugin());
|
|
46
|
+
* console.log(client.payer.address);
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @example Plugins with input requirements
|
|
50
|
+
* A plugin can specify required properties on the input client. The example below requires the
|
|
51
|
+
* client to already have a `payer` signer attached to the client in order to perform an airdrop.
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { createEmptyClient, TransactionSigner, Lamports, lamports } from '@solana/kit';
|
|
55
|
+
*
|
|
56
|
+
* // Define a plugin that airdrops lamports to the payer set on the client.
|
|
57
|
+
* function airdropPayerPlugin(lamports: Lamports) {
|
|
58
|
+
* return async <T extends { payer: TransactionSigner }>(client: T) => {
|
|
59
|
+
* await myAirdropFunction(client.payer, lamports);
|
|
60
|
+
* return client;
|
|
61
|
+
* };
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* // Use the plugins.
|
|
65
|
+
* const client = await createEmptyClient()
|
|
66
|
+
* .use(generatedPayerPlugin()) // This is required before using the airdrop plugin.
|
|
67
|
+
* .use(airdropPayerPlugin(lamports(1_000_000_000n)));
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example Chaining plugins
|
|
71
|
+
* Multiple plugins — asynchronous or not — can be chained together to build up complex clients.
|
|
72
|
+
* The example below demonstrates how to gradually build a client with multiple plugins.
|
|
73
|
+
* Notice how, despite having multiple asynchronous plugins, we only need to `await` the final result.
|
|
74
|
+
* This is because the `use` method on `AsyncClient` returns another `AsyncClient`, allowing for seamless chaining.
|
|
75
|
+
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* import { createEmptyClient, createSolanaRpc, createSolanaRpcSubscriptions, generateKeypairSigner } from '@solana/kit';
|
|
78
|
+
*
|
|
79
|
+
* // Define multiple plugins.
|
|
80
|
+
* function rpcPlugin(endpoint: string) {
|
|
81
|
+
* return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });
|
|
82
|
+
* }
|
|
83
|
+
* function rpcSubscriptionsPlugin(endpoint: string) {
|
|
84
|
+
* return <T extends object>(client: T) => ({...client, rpc: createSolanaRpcSubscriptions(endpoint) });
|
|
85
|
+
* }
|
|
86
|
+
* function generatedPayerPlugin() {
|
|
87
|
+
* return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });
|
|
88
|
+
* }
|
|
89
|
+
* function generatedAuthorityPlugin() {
|
|
90
|
+
* return async <T extends object>(client: T) => ({...client, authority: await generateKeypairSigner() });
|
|
91
|
+
* }
|
|
92
|
+
*
|
|
93
|
+
* // Chain plugins together.
|
|
94
|
+
* const client = await createEmptyClient()
|
|
95
|
+
* .use(rpcPlugin('https://api.mainnet-beta.solana.com'))
|
|
96
|
+
* .use(rpcSubscriptionsPlugin('wss://api.mainnet-beta.solana.com'))
|
|
97
|
+
* .use(generatedPayerPlugin())
|
|
98
|
+
* .use(generatedAuthorityPlugin());
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export type ClientPlugin<TInput extends object, TOutput extends Promise<object> | object> = (input: TInput) => TOutput;
|
|
102
|
+
/**
|
|
103
|
+
* A client that can be extended with plugins.
|
|
104
|
+
*
|
|
105
|
+
* The `Client` type represents a client object that can be built up through
|
|
106
|
+
* the application of one or more plugins. It provides a `use` method to
|
|
107
|
+
* apply plugins, either synchronously (returning a new `Client`) or
|
|
108
|
+
* asynchronously (returning an {@link AsyncClient}).
|
|
109
|
+
*
|
|
110
|
+
* @typeParam TSelf - The current shape of the client object including all applied plugins.
|
|
111
|
+
*/
|
|
112
|
+
export type Client<TSelf extends object> = TSelf & {
|
|
113
|
+
/**
|
|
114
|
+
* Applies a plugin to extend or transform the client.
|
|
115
|
+
*
|
|
116
|
+
* @param plugin The plugin function to apply to this client.
|
|
117
|
+
* @returns Either a new `Client` (for sync plugins) or {@link AsyncClient} (for async plugins).
|
|
118
|
+
*/
|
|
119
|
+
readonly use: <TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) => TOutput extends Promise<infer U> ? AsyncClient<U extends object ? U : never> : Client<TOutput>;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* An asynchronous wrapper that represents a promise of a client.
|
|
123
|
+
*
|
|
124
|
+
* The `AsyncClient` type is returned when an async plugin is applied to a client.
|
|
125
|
+
* It behaves like a `Promise<Client<TSelf>>` but with an additional `use` method
|
|
126
|
+
* that allows chaining more plugins before the promise resolves.
|
|
127
|
+
*
|
|
128
|
+
* This enables fluent chaining of both synchronous and asynchronous plugins
|
|
129
|
+
* without having to await intermediate promises.
|
|
130
|
+
*
|
|
131
|
+
* @typeParam TSelf - The shape of the client object that this async client will resolve to.
|
|
132
|
+
*/
|
|
133
|
+
export type AsyncClient<TSelf extends object> = Promise<Client<TSelf>> & {
|
|
134
|
+
/**
|
|
135
|
+
* Applies a plugin to the client once it resolves.
|
|
136
|
+
*
|
|
137
|
+
* @param plugin The plugin function to apply to the resolved client.
|
|
138
|
+
* @returns A new `AsyncClient` representing the result of applying the plugin.
|
|
139
|
+
*/
|
|
140
|
+
readonly use: <TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) => AsyncClient<TOutput extends Promise<infer U> ? (U extends object ? U : never) : TOutput>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Creates a new empty client that can be extended with plugins.
|
|
144
|
+
*
|
|
145
|
+
* This serves as an entry point for building Solana clients.
|
|
146
|
+
* Start with an empty client and chain the `.use()` method
|
|
147
|
+
* to apply plugins that add various functionalities such as RPC
|
|
148
|
+
* connectivity, wallet integration, transaction building, and more.
|
|
149
|
+
*
|
|
150
|
+
* See {@link ClientPlugin} for detailed examples on creating and using plugins.
|
|
151
|
+
*
|
|
152
|
+
* @returns An empty client object with only the `use` method available.
|
|
153
|
+
*
|
|
154
|
+
* @example Basic client setup
|
|
155
|
+
* ```ts
|
|
156
|
+
* import { createEmptyClient } from '@solana/client';
|
|
157
|
+
*
|
|
158
|
+
* const client = createEmptyClient()
|
|
159
|
+
* .use(myRpcPlugin('https://api.mainnet-beta.solana.com'))
|
|
160
|
+
* .use(myWalletPlugin());
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
export declare function createEmptyClient(): Client<object>;
|
|
164
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmGG;AACH,MAAM,MAAM,YAAY,CAAC,MAAM,SAAS,MAAM,EAAE,OAAO,SAAS,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;AAEvH;;;;;;;;;GASG;AACH,MAAM,MAAM,MAAM,CAAC,KAAK,SAAS,MAAM,IAAI,KAAK,GAAG;IAC/C;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,SAAS,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,EACnD,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,KACnC,OAAO,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;CACvG,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,CAAC,KAAK,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG;IACrE;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,SAAS,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,EACnD,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,KACnC,WAAW,CAAC,OAAO,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC;CACjG,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,MAAM,CAAC,CAElD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This package contains utilities for creating modular Kit clients that can be extended
|
|
3
|
+
* with plugins. It can be used standalone, but it is also exported as part of Kit
|
|
4
|
+
* [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export * from './client';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,80 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/plugin-core",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "5.2.0-canary-20251219213520",
|
|
4
|
+
"description": "Core helpers for creating and extending Kit clients with plugins",
|
|
5
|
+
"homepage": "https://www.solanakit.com/api#solanaplugin-core",
|
|
6
|
+
"exports": {
|
|
7
|
+
"edge-light": {
|
|
8
|
+
"import": "./dist/index.node.mjs",
|
|
9
|
+
"require": "./dist/index.node.cjs"
|
|
10
|
+
},
|
|
11
|
+
"workerd": {
|
|
12
|
+
"import": "./dist/index.node.mjs",
|
|
13
|
+
"require": "./dist/index.node.cjs"
|
|
14
|
+
},
|
|
15
|
+
"browser": {
|
|
16
|
+
"import": "./dist/index.browser.mjs",
|
|
17
|
+
"require": "./dist/index.browser.cjs"
|
|
18
|
+
},
|
|
19
|
+
"node": {
|
|
20
|
+
"import": "./dist/index.node.mjs",
|
|
21
|
+
"require": "./dist/index.node.cjs"
|
|
22
|
+
},
|
|
23
|
+
"react-native": "./dist/index.native.mjs",
|
|
24
|
+
"types": "./dist/types/index.d.ts"
|
|
25
|
+
},
|
|
26
|
+
"browser": {
|
|
27
|
+
"./dist/index.node.cjs": "./dist/index.browser.cjs",
|
|
28
|
+
"./dist/index.node.mjs": "./dist/index.browser.mjs"
|
|
29
|
+
},
|
|
30
|
+
"main": "./dist/index.node.cjs",
|
|
31
|
+
"module": "./dist/index.node.mjs",
|
|
32
|
+
"react-native": "./dist/index.native.mjs",
|
|
33
|
+
"types": "./dist/types/index.d.ts",
|
|
34
|
+
"type": "commonjs",
|
|
35
|
+
"files": [
|
|
36
|
+
"./dist/"
|
|
37
|
+
],
|
|
38
|
+
"sideEffects": false,
|
|
39
|
+
"keywords": [
|
|
40
|
+
"blockchain",
|
|
41
|
+
"solana",
|
|
42
|
+
"web3"
|
|
43
|
+
],
|
|
44
|
+
"author": "Solana Labs Maintainers <maintainers@solanalabs.com>",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/anza-xyz/kit"
|
|
49
|
+
},
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/anza-xyz/kit/issues"
|
|
7
52
|
},
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
53
|
+
"browserslist": [
|
|
54
|
+
"supports bigint and not dead",
|
|
55
|
+
"maintained node versions"
|
|
56
|
+
],
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"typescript": ">=5.3.3"
|
|
59
|
+
},
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=20.18.0"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"compile:docs": "typedoc",
|
|
65
|
+
"compile:js": "tsup --config build-scripts/tsup.config.package.ts",
|
|
66
|
+
"compile:typedefs": "tsc -p ./tsconfig.declarations.json",
|
|
67
|
+
"dev": "NODE_OPTIONS=\"--localstorage-file=$(mktemp)\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.ts --rootDir . --watch",
|
|
68
|
+
"publish-impl": "npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \"${GITHUB_OUTPUT:-}\" ] && echo 'published=true' >> \"$GITHUB_OUTPUT\") || true) && (([ \"$PUBLISH_TAG\" != \"canary\" ] && ../build-scripts/maybe-tag-latest.ts --token \"$GITHUB_TOKEN\" $npm_package_name@$npm_package_version) || true))",
|
|
69
|
+
"publish-packages": "pnpm prepublishOnly && pnpm publish-impl",
|
|
70
|
+
"style:fix": "pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*",
|
|
71
|
+
"test:lint": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.ts --rootDir . --silent",
|
|
72
|
+
"test:prettier": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.ts --rootDir . --silent",
|
|
73
|
+
"test:treeshakability:browser": "agadoo dist/index.browser.mjs",
|
|
74
|
+
"test:treeshakability:native": "agadoo dist/index.native.mjs",
|
|
75
|
+
"test:treeshakability:node": "agadoo dist/index.node.mjs",
|
|
76
|
+
"test:typecheck": "tsc --noEmit",
|
|
77
|
+
"test:unit:browser": "NODE_OPTIONS=\"--localstorage-file=$(mktemp)\" TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.ts --rootDir . --silent",
|
|
78
|
+
"test:unit:node": "NODE_OPTIONS=\"--localstorage-file=$(mktemp)\" TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.ts --rootDir . --silent"
|
|
79
|
+
}
|
|
80
|
+
}
|