@solana/kora 0.2.1 → 0.3.0-beta.2

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.
@@ -0,0 +1,179 @@
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 `createClient().use()` requires `@solana/kit` v6.8.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 { createClient } from '@solana/kit';
20
+ * import { koraPlugin } from '@solana/kora';
21
+ *
22
+ * const client = createClient()
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 = config.koraClient ??
35
+ new KoraClient({
36
+ apiKey: config.apiKey,
37
+ getRecaptchaToken: config.getRecaptchaToken,
38
+ hmacSecret: config.hmacSecret,
39
+ rpcUrl: config.endpoint,
40
+ });
41
+ return (c) => ({
42
+ ...c,
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
+ */
59
+ async estimateTransactionFee(request) {
60
+ const result = await client.estimateTransactionFee(request);
61
+ return {
62
+ fee_in_lamports: result.fee_in_lamports,
63
+ fee_in_token: result.fee_in_token,
64
+ payment_address: address(result.payment_address),
65
+ signer_pubkey: address(result.signer_pubkey),
66
+ };
67
+ },
68
+ /**
69
+ * Gets the latest blockhash with Kit Blockhash type.
70
+ */
71
+ async getBlockhash() {
72
+ const result = await client.getBlockhash();
73
+ return {
74
+ blockhash: blockhash(result.blockhash),
75
+ };
76
+ },
77
+ /**
78
+ * Retrieves the current Kora server configuration with Kit-typed addresses.
79
+ */
80
+ async getConfig() {
81
+ const result = await client.getConfig();
82
+ return {
83
+ enabled_methods: result.enabled_methods,
84
+ fee_payers: result.fee_payers.map(addr => address(addr)),
85
+ validation_config: {
86
+ ...result.validation_config,
87
+ allowed_programs: Array.isArray(result.validation_config.allowed_programs)
88
+ ? result.validation_config.allowed_programs.map(addr => address(addr))
89
+ : result.validation_config.allowed_programs,
90
+ allowed_spl_paid_tokens: result.validation_config.allowed_spl_paid_tokens.map(addr => address(addr)),
91
+ allowed_tokens: result.validation_config.allowed_tokens.map(addr => address(addr)),
92
+ disallowed_accounts: result.validation_config.disallowed_accounts.map(addr => address(addr)),
93
+ },
94
+ };
95
+ },
96
+ /**
97
+ * Retrieves the payer signer and payment destination with Kit-typed addresses.
98
+ */
99
+ async getPayerSigner() {
100
+ const result = await client.getPayerSigner();
101
+ return {
102
+ payment_address: address(result.payment_address),
103
+ signer_address: address(result.signer_address),
104
+ };
105
+ },
106
+ /**
107
+ * Creates a payment instruction with Kit-typed response.
108
+ */
109
+ async getPaymentInstruction(request) {
110
+ const result = await client.getPaymentInstruction(request);
111
+ return {
112
+ original_transaction: result.original_transaction,
113
+ payment_address: address(result.payment_address),
114
+ payment_amount: result.payment_amount,
115
+ payment_instruction: result.payment_instruction,
116
+ payment_token: address(result.payment_token),
117
+ signer_address: address(result.signer_address),
118
+ };
119
+ },
120
+ /**
121
+ * Retrieves the list of tokens supported for fee payment with Kit-typed addresses.
122
+ */
123
+ async getSupportedTokens() {
124
+ const result = await client.getSupportedTokens();
125
+ return {
126
+ tokens: result.tokens.map(addr => address(addr)),
127
+ };
128
+ },
129
+ /**
130
+ * Gets the version of the Kora server.
131
+ */
132
+ async getVersion() {
133
+ return await client.getVersion();
134
+ },
135
+ /**
136
+ * Signs and sends a bundle of transactions via Jito with Kit-typed response.
137
+ */
138
+ async signAndSendBundle(request) {
139
+ const result = await client.signAndSendBundle(request);
140
+ return {
141
+ bundle_uuid: result.bundle_uuid,
142
+ signed_transactions: result.signed_transactions,
143
+ signer_pubkey: address(result.signer_pubkey),
144
+ };
145
+ },
146
+ /**
147
+ * Signs and sends a transaction with Kit-typed response.
148
+ */
149
+ async signAndSendTransaction(request) {
150
+ const result = await client.signAndSendTransaction(request);
151
+ return {
152
+ signature: signature(result.signature),
153
+ signed_transaction: result.signed_transaction,
154
+ signer_pubkey: address(result.signer_pubkey),
155
+ };
156
+ },
157
+ /**
158
+ * Signs a bundle of transactions with Kit-typed response.
159
+ */
160
+ async signBundle(request) {
161
+ const result = await client.signBundle(request);
162
+ return {
163
+ signed_transactions: result.signed_transactions,
164
+ signer_pubkey: address(result.signer_pubkey),
165
+ };
166
+ },
167
+ /**
168
+ * Signs a transaction with Kit-typed response.
169
+ */
170
+ async signTransaction(request) {
171
+ const result = await client.signTransaction(request);
172
+ return {
173
+ signed_transaction: result.signed_transaction,
174
+ signer_pubkey: address(result.signer_pubkey),
175
+ };
176
+ },
177
+ },
178
+ });
179
+ }
@@ -1,22 +1,7 @@
1
- import { Instruction, TransactionSigner } from '@solana/kit';
1
+ import { Instruction, type MicroLamports, type TransactionSigner } from '@solana/kit';
2
2
  /**
3
3
  * Request Types
4
4
  */
5
- /**
6
- * Parameters for creating a token transfer transaction.
7
- */
8
- export interface TransferTransactionRequest {
9
- /** Amount to transfer in the token's smallest unit (e.g., lamports for SOL) */
10
- amount: number;
11
- /** Public key of the destination wallet (not token account) */
12
- destination: string;
13
- /** Optional signer address for the transaction */
14
- signer_key?: string;
15
- /** Public key of the source wallet (not token account) */
16
- source: string;
17
- /** Mint address of the token to transfer */
18
- token: string;
19
- }
20
5
  /**
21
6
  * Parameters for signing a transaction.
22
7
  */
@@ -27,24 +12,68 @@ export interface SignTransactionRequest {
27
12
  signer_key?: string;
28
13
  /** Base64-encoded transaction to sign */
29
14
  transaction: string;
15
+ /** Optional user ID for usage tracking (required when pricing is free and usage tracking is enabled) */
16
+ user_id?: string;
30
17
  }
18
+ /**
19
+ * The transaction lifecycle milestone the server waits for before responding,
20
+ * ordered by increasing assurance: `signed` < `sent` < `confirmed`:
21
+ * - `confirmed`: wait for on-chain confirmation (default)
22
+ * - `sent`: return once the RPC node accepts the transaction
23
+ * - `signed`: return as soon as signing completes and broadcast in the background
24
+ */
25
+ export type RespondAfter = 'confirmed' | 'sent' | 'signed';
31
26
  /**
32
27
  * Parameters for signing and sending a transaction.
33
28
  */
34
29
  export interface SignAndSendTransactionRequest {
30
+ /** Optional milestone to wait for before responding (defaults to "confirmed") */
31
+ respond_after?: RespondAfter;
35
32
  /** Optional signer verification during transaction simulation (defaults to false) */
36
33
  sig_verify?: boolean;
37
34
  /** Optional signer address for the transaction */
38
35
  signer_key?: string;
39
36
  /** Base64-encoded transaction to sign and send */
40
37
  transaction: string;
38
+ /** Optional user ID for usage tracking (required when pricing is free and usage tracking is enabled) */
39
+ user_id?: string;
40
+ }
41
+ /**
42
+ * Parameters for signing a bundle of transactions.
43
+ */
44
+ export interface SignBundleRequest {
45
+ /** Optional signer verification during transaction simulation (defaults to false) */
46
+ sig_verify?: boolean;
47
+ /** Optional indices of transactions to sign (defaults to all if not specified) */
48
+ sign_only_indices?: number[];
49
+ /** Optional signer address for the transactions */
50
+ signer_key?: string;
51
+ /** Array of base64-encoded transactions to sign */
52
+ transactions: string[];
53
+ /** Optional user ID for usage tracking (required when pricing is free and usage tracking is enabled) */
54
+ user_id?: string;
55
+ }
56
+ /**
57
+ * Parameters for signing and sending a bundle of transactions via Jito.
58
+ */
59
+ export interface SignAndSendBundleRequest {
60
+ /** Optional signer verification during transaction simulation (defaults to false) */
61
+ sig_verify?: boolean;
62
+ /** Optional indices of transactions to sign (defaults to all if not specified) */
63
+ sign_only_indices?: number[];
64
+ /** Optional signer address for the transactions */
65
+ signer_key?: string;
66
+ /** Array of base64-encoded transactions to sign and send */
67
+ transactions: string[];
68
+ /** Optional user ID for usage tracking (required when pricing is free and usage tracking is enabled) */
69
+ user_id?: string;
41
70
  }
42
71
  /**
43
72
  * Parameters for estimating transaction fees.
44
73
  */
45
74
  export interface EstimateTransactionFeeRequest {
46
75
  /** Mint address of the token to calculate fees in */
47
- fee_token: string;
76
+ fee_token?: string;
48
77
  /** Optional signer verification during transaction simulation (defaults to false) */
49
78
  sig_verify?: boolean;
50
79
  /** Optional signer address for the transaction */
@@ -52,6 +81,21 @@ export interface EstimateTransactionFeeRequest {
52
81
  /** Base64-encoded transaction to estimate fees for */
53
82
  transaction: string;
54
83
  }
84
+ /**
85
+ * Parameters for estimating bundle fees.
86
+ */
87
+ export interface EstimateBundleFeeRequest {
88
+ /** Mint address of the token to calculate fees in */
89
+ fee_token?: string;
90
+ /** Optional signer verification during transaction simulation (defaults to false) */
91
+ sig_verify?: boolean;
92
+ /** Optional indices of transactions to estimate fees for (defaults to all if not specified) */
93
+ sign_only_indices?: number[];
94
+ /** Optional signer address for the transactions */
95
+ signer_key?: string;
96
+ /** Array of base64-encoded transactions to estimate fees for */
97
+ transactions: string[];
98
+ }
55
99
  /**
56
100
  * Parameters for getting a payment instruction.
57
101
  */
@@ -75,21 +119,6 @@ export interface GetPaymentInstructionRequest {
75
119
  /**
76
120
  * Response Types
77
121
  */
78
- /**
79
- * Response from creating a transfer transaction.
80
- */
81
- export interface TransferTransactionResponse {
82
- /** Recent blockhash used in the transaction */
83
- blockhash: string;
84
- /** Parsed instructions from the transaction message */
85
- instructions: Instruction[];
86
- /** Base64-encoded message */
87
- message: string;
88
- /** Public key of the signer used to send the transaction */
89
- signer_pubkey: string;
90
- /** Base64-encoded signed transaction */
91
- transaction: string;
92
- }
93
122
  /**
94
123
  * Response from signing a transaction.
95
124
  */
@@ -110,6 +139,26 @@ export interface SignAndSendTransactionResponse {
110
139
  /** Public key of the signer used to send the transaction */
111
140
  signer_pubkey: string;
112
141
  }
142
+ /**
143
+ * Response from signing a bundle of transactions.
144
+ */
145
+ export interface SignBundleResponse {
146
+ /** Array of base64-encoded signed transactions */
147
+ signed_transactions: string[];
148
+ /** Public key of the signer used to sign the transactions */
149
+ signer_pubkey: string;
150
+ }
151
+ /**
152
+ * Response from signing and sending a bundle of transactions via Jito.
153
+ */
154
+ export interface SignAndSendBundleResponse {
155
+ /** UUID of the submitted Jito bundle */
156
+ bundle_uuid: string;
157
+ /** Array of base64-encoded signed transactions */
158
+ signed_transactions: string[];
159
+ /** Public key of the signer used to sign the transactions */
160
+ signer_pubkey: string;
161
+ }
113
162
  /**
114
163
  * Response containing the latest blockhash.
115
164
  */
@@ -117,6 +166,13 @@ export interface GetBlockhashResponse {
117
166
  /** Base58-encoded blockhash */
118
167
  blockhash: string;
119
168
  }
169
+ /**
170
+ * Response containing the server version.
171
+ */
172
+ export interface GetVersionResponse {
173
+ /** Server version string */
174
+ version: string;
175
+ }
120
176
  /**
121
177
  * Response containing supported token mint addresses.
122
178
  */
@@ -133,7 +189,22 @@ export interface EstimateTransactionFeeResponse {
133
189
  /**
134
190
  * Transaction fee in the requested token (in decimals value of the token, e.g. 10^6 for USDC)
135
191
  */
136
- fee_in_token: number;
192
+ fee_in_token?: number;
193
+ /** Public key of the payment destination */
194
+ payment_address: string;
195
+ /** Public key of the signer used to estimate the fee */
196
+ signer_pubkey: string;
197
+ }
198
+ /**
199
+ * Response containing estimated bundle fees.
200
+ */
201
+ export interface EstimateBundleFeeResponse {
202
+ /** Total bundle fee in lamports across all transactions */
203
+ fee_in_lamports: number;
204
+ /**
205
+ * Total bundle fee in the requested token (in decimals value of the token, e.g. 10^6 for USDC)
206
+ */
207
+ fee_in_token?: number;
137
208
  /** Public key of the payment destination */
138
209
  payment_address: string;
139
210
  /** Public key of the signer used to estimate the fee */
@@ -173,8 +244,8 @@ export type PriceSource = 'Jupiter' | 'Mock';
173
244
  * Validation configuration for the Kora server.
174
245
  */
175
246
  export interface ValidationConfig {
176
- /** List of allowed Solana program IDs */
177
- allowed_programs: string[];
247
+ /** List of allowed Solana program IDs, or "All" to allow any program. */
248
+ allowed_programs: 'All' | string[];
178
249
  /** List of SPL tokens accepted for paid transactions */
179
250
  allowed_spl_paid_tokens: string[];
180
251
  /** List of allowed token mint addresses for fee payment */
@@ -225,18 +296,28 @@ export type PriceConfig = PriceModel;
225
296
  * Enabled status for methods for the Kora server.
226
297
  */
227
298
  export interface EnabledMethods {
299
+ /** Whether the estimate_bundle_fee method is enabled (requires bundle.enabled = true) */
300
+ estimate_bundle_fee: boolean;
228
301
  /** Whether the estimate_transaction_fee method is enabled */
229
302
  estimate_transaction_fee: boolean;
230
303
  /** Whether the get_blockhash method is enabled */
231
304
  get_blockhash: boolean;
232
305
  /** Whether the get_config method is enabled */
233
306
  get_config: boolean;
307
+ /** Whether the get_payer_signer method is enabled */
308
+ get_payer_signer: boolean;
234
309
  /** Whether the get_supported_tokens method is enabled */
235
310
  get_supported_tokens: boolean;
311
+ /** Whether the get_version method is enabled */
312
+ get_version: boolean;
236
313
  /** Whether the liveness method is enabled */
237
314
  liveness: boolean;
315
+ /** Whether the sign_and_send_bundle method is enabled (requires bundle.enabled = true) */
316
+ sign_and_send_bundle: boolean;
238
317
  /** Whether the sign_and_send_transaction method is enabled */
239
318
  sign_and_send_transaction: boolean;
319
+ /** Whether the sign_bundle method is enabled (requires bundle.enabled = true) */
320
+ sign_bundle: boolean;
240
321
  /** Whether the sign_transaction method is enabled */
241
322
  sign_transaction: boolean;
242
323
  /** Whether the transfer_transaction method is enabled */
@@ -293,6 +374,12 @@ export interface SplTokenInstructionPolicy {
293
374
  allow_close_account: boolean;
294
375
  /** Allow fee payer to freeze SPL token accounts */
295
376
  allow_freeze_account: boolean;
377
+ /** Allow fee payer to initialize SPL token accounts */
378
+ allow_initialize_account: boolean;
379
+ /** Allow fee payer to initialize SPL token mints */
380
+ allow_initialize_mint: boolean;
381
+ /** Allow fee payer to initialize SPL multisig accounts */
382
+ allow_initialize_multisig: boolean;
296
383
  /** Allow fee payer to mint SPL tokens */
297
384
  allow_mint_to: boolean;
298
385
  /** Allow fee payer to revoke SPL token delegates */
@@ -316,6 +403,12 @@ export interface Token2022InstructionPolicy {
316
403
  allow_close_account: boolean;
317
404
  /** Allow fee payer to freeze Token2022 accounts */
318
405
  allow_freeze_account: boolean;
406
+ /** Allow fee payer to initialize Token2022 accounts */
407
+ allow_initialize_account: boolean;
408
+ /** Allow fee payer to initialize Token2022 mints */
409
+ allow_initialize_mint: boolean;
410
+ /** Allow fee payer to initialize Token2022 multisig accounts */
411
+ allow_initialize_multisig: boolean;
319
412
  /** Allow fee payer to mint Token2022 tokens */
320
413
  allow_mint_to: boolean;
321
414
  /** Allow fee payer to revoke Token2022 delegates */
@@ -347,6 +440,10 @@ export interface FeePayerPolicy {
347
440
  export interface RpcError {
348
441
  /** Error code */
349
442
  code: number;
443
+ /** Optional structured data about the error */
444
+ data?: {
445
+ error_type: string;
446
+ };
350
447
  /** Human-readable error message */
351
448
  message: string;
352
449
  }
@@ -372,6 +469,8 @@ export interface AuthenticationHeaders {
372
469
  'x-api-key'?: string;
373
470
  /** HMAC SHA256 signature of timestamp + body */
374
471
  'x-hmac-signature'?: string;
472
+ /** reCAPTCHA v3 token for bot protection */
473
+ 'x-recaptcha-token'?: string;
375
474
  /** Unix timestamp for HMAC authentication */
376
475
  'x-timestamp'?: string;
377
476
  }
@@ -381,6 +480,13 @@ export interface AuthenticationHeaders {
381
480
  export interface KoraClientOptions {
382
481
  /** Optional API key for authentication */
383
482
  apiKey?: string;
483
+ /**
484
+ * Optional callback to get a reCAPTCHA v3 token for bot protection.
485
+ * Called for every request when provided; server determines which methods require it.
486
+ * @example Browser: `() => grecaptcha.execute('site-key', { action: 'sign' })`
487
+ * @example Testing: `() => 'test-token'`
488
+ */
489
+ getRecaptchaToken?: () => Promise<string> | string;
384
490
  /** Optional HMAC secret for signature-based authentication */
385
491
  hmacSecret?: string;
386
492
  /** URL of the Kora RPC server */
@@ -389,15 +495,25 @@ export interface KoraClientOptions {
389
495
  /**
390
496
  * Plugin Types - Kit-typed responses for the Kora plugin
391
497
  */
392
- import type { Address, Base64EncodedWireTransaction, Blockhash, Instruction as KitInstruction, MicroLamports, Signature } from '@solana/kit';
498
+ import type { Address, Base64EncodedWireTransaction, Blockhash, Instruction as KitInstruction, Signature } from '@solana/kit';
499
+ import { KoraClient } from '../client.js';
393
500
  /** Configuration options for the Kora Kit plugin */
394
501
  export interface KoraPluginConfig {
395
502
  /** Optional API key for authentication */
396
503
  apiKey?: string;
397
504
  /** Kora RPC endpoint URL */
398
505
  endpoint: string;
506
+ /**
507
+ * Optional callback to get a reCAPTCHA v3 token for bot protection.
508
+ * Called for every request when provided; server determines which methods require it.
509
+ * @example Browser: `() => grecaptcha.execute('site-key', { action: 'sign' })`
510
+ * @example Testing: `() => 'test-token'`
511
+ */
512
+ getRecaptchaToken?: () => Promise<string> | string;
399
513
  /** Optional HMAC secret for signature-based authentication */
400
514
  hmacSecret?: string;
515
+ /** Existing Kora Client for reusing existing instance */
516
+ koraClient?: KoraClient;
401
517
  }
402
518
  /** Plugin response for getPayerSigner with Kit Address types */
403
519
  export interface KitPayerSignerResponse {
@@ -421,7 +537,7 @@ export interface KitEstimateFeeResponse {
421
537
  /** Transaction fee in lamports */
422
538
  fee_in_lamports: number;
423
539
  /** Transaction fee in the requested token */
424
- fee_in_token: number;
540
+ fee_in_token?: number;
425
541
  /** Public key of the payment destination */
426
542
  payment_address: Address;
427
543
  /** Public key of the signer used to estimate the fee */
@@ -443,19 +559,6 @@ export interface KitSignAndSendTransactionResponse {
443
559
  /** Public key of the signer used to send the transaction */
444
560
  signer_pubkey: Address;
445
561
  }
446
- /** Plugin response for transferTransaction with Kit types */
447
- export interface KitTransferTransactionResponse {
448
- /** Recent blockhash used in the transaction */
449
- blockhash: Blockhash;
450
- /** Parsed instructions from the transaction message */
451
- instructions: KitInstruction[];
452
- /** Base64-encoded message */
453
- message: string;
454
- /** Public key of the signer used to send the transaction */
455
- signer_pubkey: Address;
456
- /** Base64-encoded signed transaction */
457
- transaction: Base64EncodedWireTransaction;
458
- }
459
562
  /** Plugin response for getPaymentInstruction with Kit types */
460
563
  export interface KitPaymentInstructionResponse {
461
564
  /** Base64-encoded original transaction */
@@ -480,10 +583,37 @@ export interface KitConfigResponse {
480
583
  /** Validation rules and constraints */
481
584
  validation_config: KitValidationConfig;
482
585
  }
586
+ /** Plugin response for estimateBundleFee with Kit types */
587
+ export interface KitEstimateBundleFeeResponse {
588
+ /** Total bundle fee in lamports across all transactions */
589
+ fee_in_lamports: number;
590
+ /** Total bundle fee in the requested token */
591
+ fee_in_token?: number;
592
+ /** Public key of the payment destination */
593
+ payment_address: Address;
594
+ /** Public key of the signer used to estimate the fee */
595
+ signer_pubkey: Address;
596
+ }
597
+ /** Plugin response for signBundle with Kit types */
598
+ export interface KitSignBundleResponse {
599
+ /** Array of base64-encoded signed transactions */
600
+ signed_transactions: Base64EncodedWireTransaction[];
601
+ /** Public key of the signer used to sign the transactions */
602
+ signer_pubkey: Address;
603
+ }
604
+ /** Plugin response for signAndSendBundle with Kit types */
605
+ export interface KitSignAndSendBundleResponse {
606
+ /** UUID of the submitted Jito bundle */
607
+ bundle_uuid: string;
608
+ /** Array of base64-encoded signed transactions */
609
+ signed_transactions: Base64EncodedWireTransaction[];
610
+ /** Public key of the signer used to sign the transactions */
611
+ signer_pubkey: Address;
612
+ }
483
613
  /** Plugin validation config with Kit Address types */
484
614
  export interface KitValidationConfig {
485
- /** List of allowed Solana program IDs */
486
- allowed_programs: Address[];
615
+ /** List of allowed Solana program IDs, or "All" to allow any program. */
616
+ allowed_programs: 'All' | Address[];
487
617
  /** List of SPL tokens accepted for paid transactions */
488
618
  allowed_spl_paid_tokens: Address[];
489
619
  /** List of allowed token mint addresses for fee payment */
@@ -504,41 +634,31 @@ export interface KitValidationConfig {
504
634
  token2022: Token2022Config;
505
635
  }
506
636
  /**
507
- * Configuration for creating a Kora Kit client.
637
+ * Kit Client Types
638
+ */
639
+ /**
640
+ * Configuration for the {@link kora} bundle plugin.
508
641
  *
509
- * @example
510
- * ```ts
511
- * const client = await createKitKoraClient({
512
- * endpoint: 'https://kora.example.com',
513
- * rpcUrl: 'https://api.mainnet-beta.solana.com',
514
- * feeToken: address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
515
- * feePayerWallet: myWalletSigner, // TransactionSigner that authorizes SPL fee payment
516
- * });
517
- * ```
518
- */
519
- export interface KoraKitClientConfig {
520
- /** Optional API key for authentication */
642
+ * The user's signer is read from `client.identity` (set via `identity()` from
643
+ * `@solana/kit-plugin-signer`), so this config intentionally omits any signer field.
644
+ */
645
+ export interface KoraBundleConfig {
521
646
  readonly apiKey?: string;
522
- /** Optional compute unit limit (uses provisory/simulation if not set) */
523
647
  readonly computeUnitLimit?: number;
524
- /** Optional priority fee in micro-lamports */
525
648
  readonly computeUnitPrice?: MicroLamports;
526
- /** Kora RPC endpoint URL */
527
649
  readonly endpoint: string;
528
- /** Wallet signer paying SPL fees (must be a real signer so the payment transfer is authorized) */
529
- readonly feePayerWallet: TransactionSigner;
530
- /** SPL mint address for fee payment */
531
650
  readonly feeToken: Address;
532
- /** Optional HMAC secret for signature-based authentication */
651
+ readonly getRecaptchaToken?: () => Promise<string> | string;
533
652
  readonly hmacSecret?: string;
534
- /**
535
- * Solana RPC URL used for compute unit estimation and program plugin compatibility.
536
- * The client simulates transactions against this RPC node to determine optimal
537
- * compute unit limits (resulting in lower fees), and exposes it as `ClientWithRpc`
538
- * so Kit program plugins like `tokenProgram()` work out of the box.
539
- * This must be a direct Solana RPC URL (not the Kora endpoint).
540
- */
541
653
  readonly rpcUrl: string;
542
- /** Token program ID for fee payment (defaults to TOKEN_PROGRAM_ADDRESS; use TOKEN_2022_PROGRAM_ADDRESS for Token-2022) */
543
654
  readonly tokenProgramId?: Address;
655
+ readonly userId?: string;
656
+ }
657
+ /**
658
+ * Configuration for {@link createKitKoraClient}.
659
+ *
660
+ * @deprecated Use {@link KoraBundleConfig} with the {@link kora} plugin instead.
661
+ */
662
+ export interface KoraKitClientConfig extends KoraBundleConfig {
663
+ readonly feePayerWallet: TransactionSigner;
544
664
  }
@@ -5,34 +5,34 @@ export function runAuthenticationTests() {
5
5
  describe('Authentication', () => {
6
6
  it('should fail with incorrect API key', async () => {
7
7
  const client = new KoraClient({
8
- rpcUrl: koraRpcUrl,
9
8
  apiKey: 'WRONG-API-KEY',
9
+ rpcUrl: koraRpcUrl,
10
10
  });
11
11
  // Auth failure should result in an error (empty response body causes JSON parse error)
12
12
  await expect(client.getConfig()).rejects.toThrow();
13
13
  });
14
14
  it('should fail with incorrect HMAC secret', async () => {
15
15
  const client = new KoraClient({
16
- rpcUrl: koraRpcUrl,
17
16
  hmacSecret: 'WRONG-HMAC-SECRET',
17
+ rpcUrl: koraRpcUrl,
18
18
  });
19
19
  // Auth failure should result in an error
20
20
  await expect(client.getConfig()).rejects.toThrow();
21
21
  });
22
22
  it('should fail with both incorrect credentials', async () => {
23
23
  const client = new KoraClient({
24
- rpcUrl: koraRpcUrl,
25
24
  apiKey: 'WRONG-API-KEY',
26
25
  hmacSecret: 'WRONG-HMAC-SECRET',
26
+ rpcUrl: koraRpcUrl,
27
27
  });
28
28
  // Auth failure should result in an error
29
29
  await expect(client.getConfig()).rejects.toThrow();
30
30
  });
31
31
  it('should succeed with correct credentials', async () => {
32
32
  const client = new KoraClient({
33
- rpcUrl: koraRpcUrl,
34
33
  apiKey: 'test-api-key-123',
35
34
  hmacSecret: 'test-hmac-secret-456',
35
+ rpcUrl: koraRpcUrl,
36
36
  });
37
37
  const config = await client.getConfig();
38
38
  expect(config).toBeDefined();