@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.
- package/dist/src/client.d.ts +212 -7
- package/dist/src/client.js +234 -17
- package/dist/src/error.d.ts +41 -0
- package/dist/src/error.js +54 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +2 -2
- package/dist/src/kit/executor.d.ts +2 -2
- package/dist/src/kit/executor.js +20 -7
- package/dist/src/kit/index.d.ts +85 -25
- package/dist/src/kit/index.js +79 -49
- package/dist/src/kit/payment.js +3 -2
- package/dist/src/kit/planner.d.ts +2 -2
- package/dist/src/plugin.d.ts +85 -0
- package/dist/src/plugin.js +179 -0
- package/dist/src/types/index.d.ts +200 -80
- package/dist/test/auth-setup.js +4 -4
- package/dist/test/integration.test.js +223 -298
- package/dist/test/kit-client.test.js +66 -3
- package/dist/test/plugin.test.js +169 -79
- package/dist/test/setup.d.ts +8 -15
- package/dist/test/setup.js +76 -153
- package/dist/test/unit.test.js +365 -161
- package/package.json +37 -34
- package/dist/src/kit/plugin.d.ts +0 -31
- package/dist/src/kit/plugin.js +0 -107
|
@@ -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
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
*
|
|
637
|
+
* Kit Client Types
|
|
638
|
+
*/
|
|
639
|
+
/**
|
|
640
|
+
* Configuration for the {@link kora} bundle plugin.
|
|
508
641
|
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
|
|
512
|
-
|
|
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
|
-
|
|
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
|
}
|
package/dist/test/auth-setup.js
CHANGED
|
@@ -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();
|