@solana/kora 0.2.0-beta.2 → 0.2.0-beta.3
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 +3 -27
- package/dist/src/client.js +26 -57
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/plugin.d.ts +85 -0
- package/dist/src/plugin.js +175 -0
- package/dist/src/types/index.d.ts +257 -145
- package/dist/src/utils/transaction.js +1 -1
- package/dist/test/auth-setup.js +4 -4
- package/dist/test/integration.test.js +112 -131
- package/dist/test/plugin.test.d.ts +1 -0
- package/dist/test/plugin.test.js +442 -0
- package/dist/test/setup.d.ts +9 -9
- package/dist/test/setup.js +38 -35
- package/dist/test/unit.test.js +123 -140
- package/package.json +4 -3
package/dist/src/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Config,
|
|
1
|
+
import { Config, EstimateBundleFeeRequest, EstimateBundleFeeResponse, EstimateTransactionFeeRequest, EstimateTransactionFeeResponse, GetBlockhashResponse, GetPayerSignerResponse, GetPaymentInstructionRequest, GetPaymentInstructionResponse, GetSupportedTokensResponse, GetVersionResponse, KoraClientOptions, SignAndSendBundleRequest, SignAndSendBundleResponse, SignAndSendTransactionRequest, SignAndSendTransactionResponse, SignBundleRequest, SignBundleResponse, SignTransactionRequest, SignTransactionResponse } from './types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Kora RPC client for interacting with the Kora paymaster service.
|
|
4
4
|
*
|
|
@@ -169,6 +169,7 @@ export declare class KoraClient {
|
|
|
169
169
|
* @param request.transactions - Array of base64-encoded transactions to sign
|
|
170
170
|
* @param request.signer_key - Optional signer address for the transactions
|
|
171
171
|
* @param request.sig_verify - Optional signature verification (defaults to false)
|
|
172
|
+
* @param request.sign_only_indices - Optional indices of transactions to sign (defaults to all)
|
|
172
173
|
* @returns Array of signed transactions and signer public key
|
|
173
174
|
* @throws {Error} When the RPC call fails or validation fails
|
|
174
175
|
*
|
|
@@ -188,6 +189,7 @@ export declare class KoraClient {
|
|
|
188
189
|
* @param request.transactions - Array of base64-encoded transactions to sign and send
|
|
189
190
|
* @param request.signer_key - Optional signer address for the transactions
|
|
190
191
|
* @param request.sig_verify - Optional signature verification (defaults to false)
|
|
192
|
+
* @param request.sign_only_indices - Optional indices of transactions to sign (defaults to all)
|
|
191
193
|
* @returns Array of signed transactions, signer public key, and Jito bundle UUID
|
|
192
194
|
* @throws {Error} When the RPC call fails, validation fails, or Jito submission fails
|
|
193
195
|
*
|
|
@@ -201,32 +203,6 @@ export declare class KoraClient {
|
|
|
201
203
|
* ```
|
|
202
204
|
*/
|
|
203
205
|
signAndSendBundle(request: SignAndSendBundleRequest): Promise<SignAndSendBundleResponse>;
|
|
204
|
-
/**
|
|
205
|
-
* Creates an unsigned transfer transaction.
|
|
206
|
-
*
|
|
207
|
-
* @deprecated Use `getPaymentInstruction` instead for fee payment flows.
|
|
208
|
-
*
|
|
209
|
-
* @param request - Transfer request parameters
|
|
210
|
-
* @param request.amount - Amount to transfer (in token's smallest unit)
|
|
211
|
-
* @param request.token - Mint address of the token to transfer
|
|
212
|
-
* @param request.source - Source wallet public key
|
|
213
|
-
* @param request.destination - Destination wallet public key
|
|
214
|
-
* @param request.signer_key - Optional signer key to select specific Kora signer
|
|
215
|
-
* @returns Unsigned transaction, message, blockhash, and signer info
|
|
216
|
-
* @throws {Error} When the RPC call fails or token is not supported
|
|
217
|
-
*
|
|
218
|
-
* @example
|
|
219
|
-
* ```typescript
|
|
220
|
-
* const transfer = await client.transferTransaction({
|
|
221
|
-
* amount: 1000000, // 1 USDC (6 decimals)
|
|
222
|
-
* token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
223
|
-
* source: 'sourceWalletPublicKey',
|
|
224
|
-
* destination: 'destinationWalletPublicKey',
|
|
225
|
-
* });
|
|
226
|
-
* console.log('Signer:', transfer.signer_pubkey);
|
|
227
|
-
* ```
|
|
228
|
-
*/
|
|
229
|
-
transferTransaction(request: TransferTransactionRequest): Promise<TransferTransactionResponse>;
|
|
230
206
|
/**
|
|
231
207
|
* Creates a payment instruction to append to a transaction for fee payment to the Kora paymaster.
|
|
232
208
|
*
|
package/dist/src/client.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { assertIsAddress, createNoopSigner } from '@solana/kit';
|
|
2
|
+
import { findAssociatedTokenPda, getTransferInstruction, TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';
|
|
2
3
|
import crypto from 'crypto';
|
|
3
|
-
import { findAssociatedTokenPda, TOKEN_PROGRAM_ADDRESS, getTransferInstruction } from '@solana-program/token';
|
|
4
|
-
import { getInstructionsFromBase64Message } from './utils/transaction.js';
|
|
5
4
|
/**
|
|
6
5
|
* Kora RPC client for interacting with the Kora paymaster service.
|
|
7
6
|
*
|
|
@@ -52,7 +51,7 @@ export class KoraClient {
|
|
|
52
51
|
}
|
|
53
52
|
if (this.hmacSecret) {
|
|
54
53
|
const timestamp = Math.floor(Date.now() / 1000).toString();
|
|
55
|
-
const signature = this.getHmacSignature({
|
|
54
|
+
const signature = this.getHmacSignature({ body, timestamp });
|
|
56
55
|
headers['x-timestamp'] = timestamp;
|
|
57
56
|
headers['x-hmac-signature'] = signature;
|
|
58
57
|
}
|
|
@@ -60,16 +59,16 @@ export class KoraClient {
|
|
|
60
59
|
}
|
|
61
60
|
async rpcRequest(method, params) {
|
|
62
61
|
const body = JSON.stringify({
|
|
63
|
-
jsonrpc: '2.0',
|
|
64
62
|
id: 1,
|
|
63
|
+
jsonrpc: '2.0',
|
|
65
64
|
method,
|
|
66
65
|
params,
|
|
67
66
|
});
|
|
68
67
|
const headers = this.getHeaders({ body });
|
|
69
68
|
const response = await fetch(this.rpcUrl, {
|
|
70
|
-
method: 'POST',
|
|
71
|
-
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
72
69
|
body,
|
|
70
|
+
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
71
|
+
method: 'POST',
|
|
73
72
|
});
|
|
74
73
|
const json = (await response.json());
|
|
75
74
|
if (json.error) {
|
|
@@ -91,7 +90,7 @@ export class KoraClient {
|
|
|
91
90
|
* ```
|
|
92
91
|
*/
|
|
93
92
|
async getConfig() {
|
|
94
|
-
return this.rpcRequest('getConfig', undefined);
|
|
93
|
+
return await this.rpcRequest('getConfig', undefined);
|
|
95
94
|
}
|
|
96
95
|
/**
|
|
97
96
|
* Retrieves the payer signer and payment destination from the Kora server.
|
|
@@ -101,7 +100,7 @@ export class KoraClient {
|
|
|
101
100
|
* @example
|
|
102
101
|
*/
|
|
103
102
|
async getPayerSigner() {
|
|
104
|
-
return this.rpcRequest('getPayerSigner', undefined);
|
|
103
|
+
return await this.rpcRequest('getPayerSigner', undefined);
|
|
105
104
|
}
|
|
106
105
|
/**
|
|
107
106
|
* Gets the latest blockhash from the Solana RPC that the Kora server is connected to.
|
|
@@ -115,7 +114,7 @@ export class KoraClient {
|
|
|
115
114
|
* ```
|
|
116
115
|
*/
|
|
117
116
|
async getBlockhash() {
|
|
118
|
-
return this.rpcRequest('getBlockhash', undefined);
|
|
117
|
+
return await this.rpcRequest('getBlockhash', undefined);
|
|
119
118
|
}
|
|
120
119
|
/**
|
|
121
120
|
* Gets the version of the Kora server.
|
|
@@ -129,7 +128,7 @@ export class KoraClient {
|
|
|
129
128
|
* ```
|
|
130
129
|
*/
|
|
131
130
|
async getVersion() {
|
|
132
|
-
return this.rpcRequest('getVersion', undefined);
|
|
131
|
+
return await this.rpcRequest('getVersion', undefined);
|
|
133
132
|
}
|
|
134
133
|
/**
|
|
135
134
|
* Retrieves the list of tokens supported for fee payment.
|
|
@@ -144,7 +143,7 @@ export class KoraClient {
|
|
|
144
143
|
* ```
|
|
145
144
|
*/
|
|
146
145
|
async getSupportedTokens() {
|
|
147
|
-
return this.rpcRequest('getSupportedTokens', undefined);
|
|
146
|
+
return await this.rpcRequest('getSupportedTokens', undefined);
|
|
148
147
|
}
|
|
149
148
|
/**
|
|
150
149
|
* Estimates the transaction fee in both lamports and the specified token.
|
|
@@ -165,7 +164,7 @@ export class KoraClient {
|
|
|
165
164
|
* ```
|
|
166
165
|
*/
|
|
167
166
|
async estimateTransactionFee(request) {
|
|
168
|
-
return this.rpcRequest('estimateTransactionFee', request);
|
|
167
|
+
return await this.rpcRequest('estimateTransactionFee', request);
|
|
169
168
|
}
|
|
170
169
|
/**
|
|
171
170
|
* Estimates the bundle fee in both lamports and the specified token.
|
|
@@ -186,7 +185,7 @@ export class KoraClient {
|
|
|
186
185
|
* ```
|
|
187
186
|
*/
|
|
188
187
|
async estimateBundleFee(request) {
|
|
189
|
-
return this.rpcRequest('estimateBundleFee', request);
|
|
188
|
+
return await this.rpcRequest('estimateBundleFee', request);
|
|
190
189
|
}
|
|
191
190
|
/**
|
|
192
191
|
* Signs a transaction with the Kora fee payer without broadcasting it.
|
|
@@ -205,7 +204,7 @@ export class KoraClient {
|
|
|
205
204
|
* ```
|
|
206
205
|
*/
|
|
207
206
|
async signTransaction(request) {
|
|
208
|
-
return this.rpcRequest('signTransaction', request);
|
|
207
|
+
return await this.rpcRequest('signTransaction', request);
|
|
209
208
|
}
|
|
210
209
|
/**
|
|
211
210
|
* Signs a transaction and immediately broadcasts it to the Solana network.
|
|
@@ -223,7 +222,7 @@ export class KoraClient {
|
|
|
223
222
|
* ```
|
|
224
223
|
*/
|
|
225
224
|
async signAndSendTransaction(request) {
|
|
226
|
-
return this.rpcRequest('signAndSendTransaction', request);
|
|
225
|
+
return await this.rpcRequest('signAndSendTransaction', request);
|
|
227
226
|
}
|
|
228
227
|
/**
|
|
229
228
|
* Signs a bundle of transactions with the Kora fee payer without broadcasting.
|
|
@@ -231,6 +230,7 @@ export class KoraClient {
|
|
|
231
230
|
* @param request.transactions - Array of base64-encoded transactions to sign
|
|
232
231
|
* @param request.signer_key - Optional signer address for the transactions
|
|
233
232
|
* @param request.sig_verify - Optional signature verification (defaults to false)
|
|
233
|
+
* @param request.sign_only_indices - Optional indices of transactions to sign (defaults to all)
|
|
234
234
|
* @returns Array of signed transactions and signer public key
|
|
235
235
|
* @throws {Error} When the RPC call fails or validation fails
|
|
236
236
|
*
|
|
@@ -244,7 +244,7 @@ export class KoraClient {
|
|
|
244
244
|
* ```
|
|
245
245
|
*/
|
|
246
246
|
async signBundle(request) {
|
|
247
|
-
return this.rpcRequest('signBundle', request);
|
|
247
|
+
return await this.rpcRequest('signBundle', request);
|
|
248
248
|
}
|
|
249
249
|
/**
|
|
250
250
|
* Signs a bundle of transactions and sends them to Jito block engine.
|
|
@@ -252,6 +252,7 @@ export class KoraClient {
|
|
|
252
252
|
* @param request.transactions - Array of base64-encoded transactions to sign and send
|
|
253
253
|
* @param request.signer_key - Optional signer address for the transactions
|
|
254
254
|
* @param request.sig_verify - Optional signature verification (defaults to false)
|
|
255
|
+
* @param request.sign_only_indices - Optional indices of transactions to sign (defaults to all)
|
|
255
256
|
* @returns Array of signed transactions, signer public key, and Jito bundle UUID
|
|
256
257
|
* @throws {Error} When the RPC call fails, validation fails, or Jito submission fails
|
|
257
258
|
*
|
|
@@ -265,39 +266,7 @@ export class KoraClient {
|
|
|
265
266
|
* ```
|
|
266
267
|
*/
|
|
267
268
|
async signAndSendBundle(request) {
|
|
268
|
-
return this.rpcRequest('signAndSendBundle', request);
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Creates an unsigned transfer transaction.
|
|
272
|
-
*
|
|
273
|
-
* @deprecated Use `getPaymentInstruction` instead for fee payment flows.
|
|
274
|
-
*
|
|
275
|
-
* @param request - Transfer request parameters
|
|
276
|
-
* @param request.amount - Amount to transfer (in token's smallest unit)
|
|
277
|
-
* @param request.token - Mint address of the token to transfer
|
|
278
|
-
* @param request.source - Source wallet public key
|
|
279
|
-
* @param request.destination - Destination wallet public key
|
|
280
|
-
* @param request.signer_key - Optional signer key to select specific Kora signer
|
|
281
|
-
* @returns Unsigned transaction, message, blockhash, and signer info
|
|
282
|
-
* @throws {Error} When the RPC call fails or token is not supported
|
|
283
|
-
*
|
|
284
|
-
* @example
|
|
285
|
-
* ```typescript
|
|
286
|
-
* const transfer = await client.transferTransaction({
|
|
287
|
-
* amount: 1000000, // 1 USDC (6 decimals)
|
|
288
|
-
* token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
289
|
-
* source: 'sourceWalletPublicKey',
|
|
290
|
-
* destination: 'destinationWalletPublicKey',
|
|
291
|
-
* });
|
|
292
|
-
* console.log('Signer:', transfer.signer_pubkey);
|
|
293
|
-
* ```
|
|
294
|
-
*/
|
|
295
|
-
async transferTransaction(request) {
|
|
296
|
-
const response = await this.rpcRequest('transferTransaction', request);
|
|
297
|
-
// Parse instructions from the message to enhance developer experience
|
|
298
|
-
// Always set instructions, even for empty messages (for consistency)
|
|
299
|
-
response.instructions = getInstructionsFromBase64Message(response.message || '');
|
|
300
|
-
return response;
|
|
269
|
+
return await this.rpcRequest('signAndSendBundle', request);
|
|
301
270
|
}
|
|
302
271
|
/**
|
|
303
272
|
* Creates a payment instruction to append to a transaction for fee payment to the Kora paymaster.
|
|
@@ -331,37 +300,37 @@ export class KoraClient {
|
|
|
331
300
|
assertIsAddress(fee_token);
|
|
332
301
|
assertIsAddress(token_program_id);
|
|
333
302
|
const { fee_in_token, payment_address, signer_pubkey } = await this.estimateTransactionFee({
|
|
334
|
-
transaction,
|
|
335
303
|
fee_token,
|
|
336
304
|
sig_verify,
|
|
337
305
|
signer_key,
|
|
306
|
+
transaction,
|
|
338
307
|
});
|
|
339
308
|
assertIsAddress(payment_address);
|
|
340
309
|
const [sourceTokenAccount] = await findAssociatedTokenPda({
|
|
310
|
+
mint: fee_token,
|
|
341
311
|
owner: source_wallet,
|
|
342
312
|
tokenProgram: token_program_id,
|
|
343
|
-
mint: fee_token,
|
|
344
313
|
});
|
|
345
314
|
const [destinationTokenAccount] = await findAssociatedTokenPda({
|
|
315
|
+
mint: fee_token,
|
|
346
316
|
owner: payment_address,
|
|
347
317
|
tokenProgram: token_program_id,
|
|
348
|
-
mint: fee_token,
|
|
349
318
|
});
|
|
350
319
|
if (fee_in_token === undefined) {
|
|
351
320
|
throw new Error('Fee token was specified but fee_in_token was not returned from server');
|
|
352
321
|
}
|
|
353
322
|
const paymentInstruction = getTransferInstruction({
|
|
354
|
-
source: sourceTokenAccount,
|
|
355
|
-
destination: destinationTokenAccount,
|
|
356
|
-
authority: createNoopSigner(source_wallet),
|
|
357
323
|
amount: fee_in_token,
|
|
324
|
+
authority: createNoopSigner(source_wallet),
|
|
325
|
+
destination: destinationTokenAccount,
|
|
326
|
+
source: sourceTokenAccount,
|
|
358
327
|
});
|
|
359
328
|
return {
|
|
360
329
|
original_transaction: transaction,
|
|
361
|
-
|
|
330
|
+
payment_address,
|
|
362
331
|
payment_amount: fee_in_token,
|
|
332
|
+
payment_instruction: paymentInstruction,
|
|
363
333
|
payment_token: fee_token,
|
|
364
|
-
payment_address,
|
|
365
334
|
signer_address: signer_pubkey,
|
|
366
335
|
};
|
|
367
336
|
}
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -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'];
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { address, blockhash, signature } from '@solana/kit';
|
|
2
|
+
import { KoraClient } from './client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a Kora Kit plugin that adds Kora paymaster functionality to a Kit client.
|
|
5
|
+
*
|
|
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
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { createEmptyClient } from '@solana/kit';
|
|
20
|
+
* import { koraPlugin } from '@solana/kora';
|
|
21
|
+
*
|
|
22
|
+
* const client = createEmptyClient()
|
|
23
|
+
* .use(koraPlugin({ endpoint: 'https://kora.example.com' }));
|
|
24
|
+
*
|
|
25
|
+
* // All responses have Kit-typed fields
|
|
26
|
+
* const config = await client.kora.getConfig();
|
|
27
|
+
* // config.fee_payers is Address[] not string[]
|
|
28
|
+
*
|
|
29
|
+
* const { signer_pubkey } = await client.kora.signTransaction({ transaction: tx });
|
|
30
|
+
* // signer_pubkey is Address not string
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function koraPlugin(config) {
|
|
34
|
+
const client = new KoraClient({
|
|
35
|
+
apiKey: config.apiKey,
|
|
36
|
+
hmacSecret: config.hmacSecret,
|
|
37
|
+
rpcUrl: config.endpoint,
|
|
38
|
+
});
|
|
39
|
+
return (c) => ({
|
|
40
|
+
...c,
|
|
41
|
+
kora: {
|
|
42
|
+
/**
|
|
43
|
+
* Estimates the bundle fee with Kit-typed addresses.
|
|
44
|
+
*/
|
|
45
|
+
async estimateBundleFee(request) {
|
|
46
|
+
const result = await client.estimateBundleFee(request);
|
|
47
|
+
return {
|
|
48
|
+
fee_in_lamports: result.fee_in_lamports,
|
|
49
|
+
fee_in_token: result.fee_in_token,
|
|
50
|
+
payment_address: address(result.payment_address),
|
|
51
|
+
signer_pubkey: address(result.signer_pubkey),
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
/**
|
|
55
|
+
* Estimates the transaction fee with Kit-typed addresses.
|
|
56
|
+
*/
|
|
57
|
+
async estimateTransactionFee(request) {
|
|
58
|
+
const result = await client.estimateTransactionFee(request);
|
|
59
|
+
return {
|
|
60
|
+
fee_in_lamports: result.fee_in_lamports,
|
|
61
|
+
fee_in_token: result.fee_in_token,
|
|
62
|
+
payment_address: address(result.payment_address),
|
|
63
|
+
signer_pubkey: address(result.signer_pubkey),
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* Gets the latest blockhash with Kit Blockhash type.
|
|
68
|
+
*/
|
|
69
|
+
async getBlockhash() {
|
|
70
|
+
const result = await client.getBlockhash();
|
|
71
|
+
return {
|
|
72
|
+
blockhash: blockhash(result.blockhash),
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Retrieves the current Kora server configuration with Kit-typed addresses.
|
|
77
|
+
*/
|
|
78
|
+
async getConfig() {
|
|
79
|
+
const result = await client.getConfig();
|
|
80
|
+
return {
|
|
81
|
+
enabled_methods: result.enabled_methods,
|
|
82
|
+
fee_payers: result.fee_payers.map(addr => address(addr)),
|
|
83
|
+
validation_config: {
|
|
84
|
+
...result.validation_config,
|
|
85
|
+
allowed_programs: result.validation_config.allowed_programs.map(addr => address(addr)),
|
|
86
|
+
allowed_spl_paid_tokens: result.validation_config.allowed_spl_paid_tokens.map(addr => address(addr)),
|
|
87
|
+
allowed_tokens: result.validation_config.allowed_tokens.map(addr => address(addr)),
|
|
88
|
+
disallowed_accounts: result.validation_config.disallowed_accounts.map(addr => address(addr)),
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* Retrieves the payer signer and payment destination with Kit-typed addresses.
|
|
94
|
+
*/
|
|
95
|
+
async getPayerSigner() {
|
|
96
|
+
const result = await client.getPayerSigner();
|
|
97
|
+
return {
|
|
98
|
+
payment_address: address(result.payment_address),
|
|
99
|
+
signer_address: address(result.signer_address),
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
/**
|
|
103
|
+
* Creates a payment instruction with Kit-typed response.
|
|
104
|
+
*/
|
|
105
|
+
async getPaymentInstruction(request) {
|
|
106
|
+
const result = await client.getPaymentInstruction(request);
|
|
107
|
+
return {
|
|
108
|
+
original_transaction: result.original_transaction,
|
|
109
|
+
payment_address: address(result.payment_address),
|
|
110
|
+
payment_amount: result.payment_amount,
|
|
111
|
+
payment_instruction: result.payment_instruction,
|
|
112
|
+
payment_token: address(result.payment_token),
|
|
113
|
+
signer_address: address(result.signer_address),
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
/**
|
|
117
|
+
* Retrieves the list of tokens supported for fee payment with Kit-typed addresses.
|
|
118
|
+
*/
|
|
119
|
+
async getSupportedTokens() {
|
|
120
|
+
const result = await client.getSupportedTokens();
|
|
121
|
+
return {
|
|
122
|
+
tokens: result.tokens.map(addr => address(addr)),
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* Gets the version of the Kora server.
|
|
127
|
+
*/
|
|
128
|
+
async getVersion() {
|
|
129
|
+
return await client.getVersion();
|
|
130
|
+
},
|
|
131
|
+
/**
|
|
132
|
+
* Signs and sends a bundle of transactions via Jito with Kit-typed response.
|
|
133
|
+
*/
|
|
134
|
+
async signAndSendBundle(request) {
|
|
135
|
+
const result = await client.signAndSendBundle(request);
|
|
136
|
+
return {
|
|
137
|
+
bundle_uuid: result.bundle_uuid,
|
|
138
|
+
signed_transactions: result.signed_transactions,
|
|
139
|
+
signer_pubkey: address(result.signer_pubkey),
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
/**
|
|
143
|
+
* Signs and sends a transaction with Kit-typed response.
|
|
144
|
+
*/
|
|
145
|
+
async signAndSendTransaction(request) {
|
|
146
|
+
const result = await client.signAndSendTransaction(request);
|
|
147
|
+
return {
|
|
148
|
+
signature: signature(result.signature),
|
|
149
|
+
signed_transaction: result.signed_transaction,
|
|
150
|
+
signer_pubkey: address(result.signer_pubkey),
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
/**
|
|
154
|
+
* Signs a bundle of transactions with Kit-typed response.
|
|
155
|
+
*/
|
|
156
|
+
async signBundle(request) {
|
|
157
|
+
const result = await client.signBundle(request);
|
|
158
|
+
return {
|
|
159
|
+
signed_transactions: result.signed_transactions,
|
|
160
|
+
signer_pubkey: address(result.signer_pubkey),
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
/**
|
|
164
|
+
* Signs a transaction with Kit-typed response.
|
|
165
|
+
*/
|
|
166
|
+
async signTransaction(request) {
|
|
167
|
+
const result = await client.signTransaction(request);
|
|
168
|
+
return {
|
|
169
|
+
signed_transaction: result.signed_transaction,
|
|
170
|
+
signer_pubkey: address(result.signer_pubkey),
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
}
|