@solana/kora 0.2.0 → 0.3.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/client.d.ts +201 -7
- package/dist/src/client.js +223 -18
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/kit/executor.js +18 -5
- package/dist/src/kit/index.d.ts +4 -1
- package/dist/src/kit/index.js +10 -2
- package/dist/src/kit/payment.js +3 -2
- package/dist/src/plugin.d.ts +85 -0
- package/dist/src/{kit/plugin.js → plugin.js} +88 -18
- package/dist/src/types/index.d.ts +173 -78
- package/dist/test/auth-setup.js +4 -4
- package/dist/test/integration.test.js +168 -291
- package/dist/test/kit-client.test.js +18 -0
- package/dist/test/plugin.test.js +126 -71
- package/dist/test/setup.d.ts +8 -15
- package/dist/test/setup.js +52 -152
- package/dist/test/unit.test.js +318 -166
- package/package.json +8 -16
- package/dist/src/kit/plugin.d.ts +0 -31
package/dist/src/kit/index.js
CHANGED
|
@@ -4,10 +4,10 @@ import { payer } from '@solana/kit-plugin-payer';
|
|
|
4
4
|
import { rpc } from '@solana/kit-plugin-rpc';
|
|
5
5
|
import { estimateAndUpdateProvisoryComputeUnitLimitFactory, estimateComputeUnitLimitFactory, } from '@solana-program/compute-budget';
|
|
6
6
|
import { KoraClient } from '../client.js';
|
|
7
|
+
import { koraPlugin } from '../plugin.js';
|
|
7
8
|
import { createKoraTransactionPlanExecutor } from './executor.js';
|
|
8
9
|
import { buildPlaceholderPaymentInstruction, koraPaymentAddress } from './payment.js';
|
|
9
10
|
import { buildComputeBudgetInstructions, createKoraTransactionPlanner } from './planner.js';
|
|
10
|
-
import { koraPlugin } from './plugin.js';
|
|
11
11
|
/**
|
|
12
12
|
* Creates a Kora Kit client composed from Kit plugins.
|
|
13
13
|
*
|
|
@@ -31,9 +31,14 @@ import { koraPlugin } from './plugin.js';
|
|
|
31
31
|
* const result = await client.sendTransaction([myInstruction]);
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
|
+
// TODO: Bundle support — the plan/execute pipeline currently handles single transactions only.
|
|
35
|
+
// For Jito bundles, users must manually encode transactions and call `client.kora.signAndSendBundle()`.
|
|
36
|
+
// A future `createKitKoraBundleClient` (or a bundle-aware executor plugin) could extend this to
|
|
37
|
+
// plan multiple transaction messages and submit them as a single bundle.
|
|
34
38
|
export async function createKitKoraClient(config) {
|
|
35
39
|
const koraClient = new KoraClient({
|
|
36
40
|
apiKey: config.apiKey,
|
|
41
|
+
getRecaptchaToken: config.getRecaptchaToken,
|
|
37
42
|
hmacSecret: config.hmacSecret,
|
|
38
43
|
rpcUrl: config.endpoint,
|
|
39
44
|
});
|
|
@@ -58,7 +63,10 @@ export async function createKitKoraClient(config) {
|
|
|
58
63
|
: undefined, resolveProvisoryComputeUnitLimit);
|
|
59
64
|
return createEmptyClient()
|
|
60
65
|
.use(rpc(config.rpcUrl))
|
|
61
|
-
.use(koraPlugin({
|
|
66
|
+
.use(koraPlugin({
|
|
67
|
+
endpoint: config.endpoint,
|
|
68
|
+
koraClient,
|
|
69
|
+
}))
|
|
62
70
|
.use(payer(payerSigner))
|
|
63
71
|
.use(koraPaymentAddress(paymentAddr))
|
|
64
72
|
.use(transactionPlannerPlugin(koraTransactionPlanner))
|
package/dist/src/kit/payment.js
CHANGED
|
@@ -27,7 +27,7 @@ export async function buildPlaceholderPaymentInstruction(feePayerWallet, payment
|
|
|
27
27
|
authority: feePayerWallet,
|
|
28
28
|
destination: destinationTokenAccount,
|
|
29
29
|
source: sourceTokenAccount,
|
|
30
|
-
});
|
|
30
|
+
}, { programAddress: tokenProgram });
|
|
31
31
|
return { destinationTokenAccount, instruction, sourceTokenAccount };
|
|
32
32
|
}
|
|
33
33
|
function isPlaceholderPaymentInstruction(ix, sourceTokenAccount, destinationTokenAccount, feePayerWallet, tokenProgramId) {
|
|
@@ -50,12 +50,13 @@ export function updatePaymentInstructionAmount(instructions, feePayerWallet, sou
|
|
|
50
50
|
return ix;
|
|
51
51
|
}
|
|
52
52
|
replaced = true;
|
|
53
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ADDRESS;
|
|
53
54
|
return getTransferInstruction({
|
|
54
55
|
amount,
|
|
55
56
|
authority: feePayerWallet,
|
|
56
57
|
destination: destinationTokenAccount,
|
|
57
58
|
source: sourceTokenAccount,
|
|
58
|
-
});
|
|
59
|
+
}, { programAddress: tokenProgram });
|
|
59
60
|
});
|
|
60
61
|
if (!replaced) {
|
|
61
62
|
throw new Error('Failed to update payment instruction: no matching placeholder transfer instruction found. ' +
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { EstimateBundleFeeRequest, EstimateTransactionFeeRequest, GetPaymentInstructionRequest, GetVersionResponse, KitBlockhashResponse, KitConfigResponse, KitEstimateBundleFeeResponse, KitEstimateFeeResponse, KitPayerSignerResponse, KitPaymentInstructionResponse, KitSignAndSendBundleResponse, KitSignAndSendTransactionResponse, KitSignBundleResponse, KitSignTransactionResponse, KitSupportedTokensResponse, KoraPluginConfig, SignAndSendBundleRequest, SignAndSendTransactionRequest, SignBundleRequest, SignTransactionRequest } from './types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a Kora Kit plugin that adds Kora paymaster functionality to a Kit client.
|
|
4
|
+
*
|
|
5
|
+
* The plugin exposes all Kora RPC methods with Kit-typed responses (Address, Blockhash).
|
|
6
|
+
*
|
|
7
|
+
* **Note:** The plugin pattern with `createEmptyClient().use()` requires `@solana/kit` v5.4.0+.
|
|
8
|
+
* For older kit versions, use `KoraClient` directly instead.
|
|
9
|
+
*
|
|
10
|
+
* @param config - Plugin configuration
|
|
11
|
+
* @param config.endpoint - Kora RPC endpoint URL
|
|
12
|
+
* @param config.apiKey - Optional API key for authentication
|
|
13
|
+
* @param config.hmacSecret - Optional HMAC secret for signature-based authentication
|
|
14
|
+
* @returns A Kit plugin function that adds `.kora` to the client
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { createEmptyClient } from '@solana/kit';
|
|
19
|
+
* import { koraPlugin } from '@solana/kora';
|
|
20
|
+
*
|
|
21
|
+
* const client = createEmptyClient()
|
|
22
|
+
* .use(koraPlugin({ endpoint: 'https://kora.example.com' }));
|
|
23
|
+
*
|
|
24
|
+
* // All responses have Kit-typed fields
|
|
25
|
+
* const config = await client.kora.getConfig();
|
|
26
|
+
* // config.fee_payers is Address[] not string[]
|
|
27
|
+
*
|
|
28
|
+
* const { signer_pubkey } = await client.kora.signTransaction({ transaction: tx });
|
|
29
|
+
* // signer_pubkey is Address not string
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function koraPlugin(config: KoraPluginConfig): <T extends object>(c: T) => T & {
|
|
33
|
+
kora: {
|
|
34
|
+
/**
|
|
35
|
+
* Estimates the bundle fee with Kit-typed addresses.
|
|
36
|
+
*/
|
|
37
|
+
estimateBundleFee(request: EstimateBundleFeeRequest): Promise<KitEstimateBundleFeeResponse>;
|
|
38
|
+
/**
|
|
39
|
+
* Estimates the transaction fee with Kit-typed addresses.
|
|
40
|
+
*/
|
|
41
|
+
estimateTransactionFee(request: EstimateTransactionFeeRequest): Promise<KitEstimateFeeResponse>;
|
|
42
|
+
/**
|
|
43
|
+
* Gets the latest blockhash with Kit Blockhash type.
|
|
44
|
+
*/
|
|
45
|
+
getBlockhash(): Promise<KitBlockhashResponse>;
|
|
46
|
+
/**
|
|
47
|
+
* Retrieves the current Kora server configuration with Kit-typed addresses.
|
|
48
|
+
*/
|
|
49
|
+
getConfig(): Promise<KitConfigResponse>;
|
|
50
|
+
/**
|
|
51
|
+
* Retrieves the payer signer and payment destination with Kit-typed addresses.
|
|
52
|
+
*/
|
|
53
|
+
getPayerSigner(): Promise<KitPayerSignerResponse>;
|
|
54
|
+
/**
|
|
55
|
+
* Creates a payment instruction with Kit-typed response.
|
|
56
|
+
*/
|
|
57
|
+
getPaymentInstruction(request: GetPaymentInstructionRequest): Promise<KitPaymentInstructionResponse>;
|
|
58
|
+
/**
|
|
59
|
+
* Retrieves the list of tokens supported for fee payment with Kit-typed addresses.
|
|
60
|
+
*/
|
|
61
|
+
getSupportedTokens(): Promise<KitSupportedTokensResponse>;
|
|
62
|
+
/**
|
|
63
|
+
* Gets the version of the Kora server.
|
|
64
|
+
*/
|
|
65
|
+
getVersion(): Promise<GetVersionResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Signs and sends a bundle of transactions via Jito with Kit-typed response.
|
|
68
|
+
*/
|
|
69
|
+
signAndSendBundle(request: SignAndSendBundleRequest): Promise<KitSignAndSendBundleResponse>;
|
|
70
|
+
/**
|
|
71
|
+
* Signs and sends a transaction with Kit-typed response.
|
|
72
|
+
*/
|
|
73
|
+
signAndSendTransaction(request: SignAndSendTransactionRequest): Promise<KitSignAndSendTransactionResponse>;
|
|
74
|
+
/**
|
|
75
|
+
* Signs a bundle of transactions with Kit-typed response.
|
|
76
|
+
*/
|
|
77
|
+
signBundle(request: SignBundleRequest): Promise<KitSignBundleResponse>;
|
|
78
|
+
/**
|
|
79
|
+
* Signs a transaction with Kit-typed response.
|
|
80
|
+
*/
|
|
81
|
+
signTransaction(request: SignTransactionRequest): Promise<KitSignTransactionResponse>;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
/** Type representing the Kora API exposed by the plugin */
|
|
85
|
+
export type KoraApi = ReturnType<ReturnType<typeof koraPlugin>>['kora'];
|
|
@@ -1,29 +1,61 @@
|
|
|
1
1
|
import { address, blockhash, signature } from '@solana/kit';
|
|
2
|
-
import { KoraClient } from '
|
|
2
|
+
import { KoraClient } from './client.js';
|
|
3
3
|
/**
|
|
4
|
-
* Kit plugin that adds
|
|
5
|
-
* Responses are cast to Kit types (Address, Blockhash, Signature).
|
|
4
|
+
* Creates a Kora Kit plugin that adds Kora paymaster functionality to a Kit client.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
6
|
+
* The plugin exposes all Kora RPC methods with Kit-typed responses (Address, Blockhash).
|
|
7
|
+
*
|
|
8
|
+
* **Note:** The plugin pattern with `createEmptyClient().use()` requires `@solana/kit` v5.4.0+.
|
|
9
|
+
* For older kit versions, use `KoraClient` directly instead.
|
|
10
|
+
*
|
|
11
|
+
* @param config - Plugin configuration
|
|
12
|
+
* @param config.endpoint - Kora RPC endpoint URL
|
|
13
|
+
* @param config.apiKey - Optional API key for authentication
|
|
14
|
+
* @param config.hmacSecret - Optional HMAC secret for signature-based authentication
|
|
15
|
+
* @returns A Kit plugin function that adds `.kora` to the client
|
|
8
16
|
*
|
|
9
17
|
* @example
|
|
10
18
|
* ```typescript
|
|
19
|
+
* import { createEmptyClient } from '@solana/kit';
|
|
20
|
+
* import { koraPlugin } from '@solana/kora';
|
|
21
|
+
*
|
|
11
22
|
* const client = createEmptyClient()
|
|
12
23
|
* .use(koraPlugin({ endpoint: 'https://kora.example.com' }));
|
|
13
24
|
*
|
|
25
|
+
* // All responses have Kit-typed fields
|
|
14
26
|
* const config = await client.kora.getConfig();
|
|
27
|
+
* // config.fee_payers is Address[] not string[]
|
|
28
|
+
*
|
|
15
29
|
* const { signer_pubkey } = await client.kora.signTransaction({ transaction: tx });
|
|
30
|
+
* // signer_pubkey is Address not string
|
|
16
31
|
* ```
|
|
17
32
|
*/
|
|
18
33
|
export function koraPlugin(config) {
|
|
19
|
-
const client =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
34
|
+
const client = config.koraClient ??
|
|
35
|
+
new KoraClient({
|
|
36
|
+
apiKey: config.apiKey,
|
|
37
|
+
getRecaptchaToken: config.getRecaptchaToken,
|
|
38
|
+
hmacSecret: config.hmacSecret,
|
|
39
|
+
rpcUrl: config.endpoint,
|
|
40
|
+
});
|
|
24
41
|
return (c) => ({
|
|
25
42
|
...c,
|
|
26
43
|
kora: {
|
|
44
|
+
/**
|
|
45
|
+
* Estimates the bundle fee with Kit-typed addresses.
|
|
46
|
+
*/
|
|
47
|
+
async estimateBundleFee(request) {
|
|
48
|
+
const result = await client.estimateBundleFee(request);
|
|
49
|
+
return {
|
|
50
|
+
fee_in_lamports: result.fee_in_lamports,
|
|
51
|
+
fee_in_token: result.fee_in_token,
|
|
52
|
+
payment_address: address(result.payment_address),
|
|
53
|
+
signer_pubkey: address(result.signer_pubkey),
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Estimates the transaction fee with Kit-typed addresses.
|
|
58
|
+
*/
|
|
27
59
|
async estimateTransactionFee(request) {
|
|
28
60
|
const result = await client.estimateTransactionFee(request);
|
|
29
61
|
return {
|
|
@@ -33,12 +65,18 @@ export function koraPlugin(config) {
|
|
|
33
65
|
signer_pubkey: address(result.signer_pubkey),
|
|
34
66
|
};
|
|
35
67
|
},
|
|
68
|
+
/**
|
|
69
|
+
* Gets the latest blockhash with Kit Blockhash type.
|
|
70
|
+
*/
|
|
36
71
|
async getBlockhash() {
|
|
37
72
|
const result = await client.getBlockhash();
|
|
38
73
|
return {
|
|
39
74
|
blockhash: blockhash(result.blockhash),
|
|
40
75
|
};
|
|
41
76
|
},
|
|
77
|
+
/**
|
|
78
|
+
* Retrieves the current Kora server configuration with Kit-typed addresses.
|
|
79
|
+
*/
|
|
42
80
|
async getConfig() {
|
|
43
81
|
const result = await client.getConfig();
|
|
44
82
|
return {
|
|
@@ -53,6 +91,9 @@ export function koraPlugin(config) {
|
|
|
53
91
|
},
|
|
54
92
|
};
|
|
55
93
|
},
|
|
94
|
+
/**
|
|
95
|
+
* Retrieves the payer signer and payment destination with Kit-typed addresses.
|
|
96
|
+
*/
|
|
56
97
|
async getPayerSigner() {
|
|
57
98
|
const result = await client.getPayerSigner();
|
|
58
99
|
return {
|
|
@@ -60,6 +101,9 @@ export function koraPlugin(config) {
|
|
|
60
101
|
signer_address: address(result.signer_address),
|
|
61
102
|
};
|
|
62
103
|
},
|
|
104
|
+
/**
|
|
105
|
+
* Creates a payment instruction with Kit-typed response.
|
|
106
|
+
*/
|
|
63
107
|
async getPaymentInstruction(request) {
|
|
64
108
|
const result = await client.getPaymentInstruction(request);
|
|
65
109
|
return {
|
|
@@ -71,12 +115,35 @@ export function koraPlugin(config) {
|
|
|
71
115
|
signer_address: address(result.signer_address),
|
|
72
116
|
};
|
|
73
117
|
},
|
|
118
|
+
/**
|
|
119
|
+
* Retrieves the list of tokens supported for fee payment with Kit-typed addresses.
|
|
120
|
+
*/
|
|
74
121
|
async getSupportedTokens() {
|
|
75
122
|
const result = await client.getSupportedTokens();
|
|
76
123
|
return {
|
|
77
124
|
tokens: result.tokens.map(addr => address(addr)),
|
|
78
125
|
};
|
|
79
126
|
},
|
|
127
|
+
/**
|
|
128
|
+
* Gets the version of the Kora server.
|
|
129
|
+
*/
|
|
130
|
+
async getVersion() {
|
|
131
|
+
return await client.getVersion();
|
|
132
|
+
},
|
|
133
|
+
/**
|
|
134
|
+
* Signs and sends a bundle of transactions via Jito with Kit-typed response.
|
|
135
|
+
*/
|
|
136
|
+
async signAndSendBundle(request) {
|
|
137
|
+
const result = await client.signAndSendBundle(request);
|
|
138
|
+
return {
|
|
139
|
+
bundle_uuid: result.bundle_uuid,
|
|
140
|
+
signed_transactions: result.signed_transactions,
|
|
141
|
+
signer_pubkey: address(result.signer_pubkey),
|
|
142
|
+
};
|
|
143
|
+
},
|
|
144
|
+
/**
|
|
145
|
+
* Signs and sends a transaction with Kit-typed response.
|
|
146
|
+
*/
|
|
80
147
|
async signAndSendTransaction(request) {
|
|
81
148
|
const result = await client.signAndSendTransaction(request);
|
|
82
149
|
return {
|
|
@@ -85,21 +152,24 @@ export function koraPlugin(config) {
|
|
|
85
152
|
signer_pubkey: address(result.signer_pubkey),
|
|
86
153
|
};
|
|
87
154
|
},
|
|
88
|
-
|
|
89
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Signs a bundle of transactions with Kit-typed response.
|
|
157
|
+
*/
|
|
158
|
+
async signBundle(request) {
|
|
159
|
+
const result = await client.signBundle(request);
|
|
90
160
|
return {
|
|
91
|
-
|
|
161
|
+
signed_transactions: result.signed_transactions,
|
|
92
162
|
signer_pubkey: address(result.signer_pubkey),
|
|
93
163
|
};
|
|
94
164
|
},
|
|
95
|
-
|
|
96
|
-
|
|
165
|
+
/**
|
|
166
|
+
* Signs a transaction with Kit-typed response.
|
|
167
|
+
*/
|
|
168
|
+
async signTransaction(request) {
|
|
169
|
+
const result = await client.signTransaction(request);
|
|
97
170
|
return {
|
|
98
|
-
|
|
99
|
-
instructions: result.instructions,
|
|
100
|
-
message: result.message,
|
|
171
|
+
signed_transaction: result.signed_transaction,
|
|
101
172
|
signer_pubkey: address(result.signer_pubkey),
|
|
102
|
-
transaction: result.transaction,
|
|
103
173
|
};
|
|
104
174
|
},
|
|
105
175
|
},
|