@solana/kora 0.2.0-beta.1 → 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 +22 -27
- package/dist/src/client.js +49 -56
- 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 +277 -135
- 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 -138
- 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
|
*
|
|
@@ -111,6 +111,25 @@ export declare class KoraClient {
|
|
|
111
111
|
* ```
|
|
112
112
|
*/
|
|
113
113
|
estimateTransactionFee(request: EstimateTransactionFeeRequest): Promise<EstimateTransactionFeeResponse>;
|
|
114
|
+
/**
|
|
115
|
+
* Estimates the bundle fee in both lamports and the specified token.
|
|
116
|
+
* @param request - Bundle fee estimation request parameters
|
|
117
|
+
* @param request.transactions - Array of base64-encoded transactions to estimate fees for
|
|
118
|
+
* @param request.fee_token - Mint address of the token to calculate fees in
|
|
119
|
+
* @returns Total fee amounts across all transactions in both lamports and the specified token
|
|
120
|
+
* @throws {Error} When the RPC call fails, the bundle is invalid, or the token is not supported
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* const fees = await client.estimateBundleFee({
|
|
125
|
+
* transactions: ['base64EncodedTransaction1', 'base64EncodedTransaction2'],
|
|
126
|
+
* fee_token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC
|
|
127
|
+
* });
|
|
128
|
+
* console.log('Total fee in lamports:', fees.fee_in_lamports);
|
|
129
|
+
* console.log('Total fee in USDC:', fees.fee_in_token);
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
estimateBundleFee(request: EstimateBundleFeeRequest): Promise<EstimateBundleFeeResponse>;
|
|
114
133
|
/**
|
|
115
134
|
* Signs a transaction with the Kora fee payer without broadcasting it.
|
|
116
135
|
* @param request - Sign request parameters
|
|
@@ -150,6 +169,7 @@ export declare class KoraClient {
|
|
|
150
169
|
* @param request.transactions - Array of base64-encoded transactions to sign
|
|
151
170
|
* @param request.signer_key - Optional signer address for the transactions
|
|
152
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)
|
|
153
173
|
* @returns Array of signed transactions and signer public key
|
|
154
174
|
* @throws {Error} When the RPC call fails or validation fails
|
|
155
175
|
*
|
|
@@ -169,6 +189,7 @@ export declare class KoraClient {
|
|
|
169
189
|
* @param request.transactions - Array of base64-encoded transactions to sign and send
|
|
170
190
|
* @param request.signer_key - Optional signer address for the transactions
|
|
171
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)
|
|
172
193
|
* @returns Array of signed transactions, signer public key, and Jito bundle UUID
|
|
173
194
|
* @throws {Error} When the RPC call fails, validation fails, or Jito submission fails
|
|
174
195
|
*
|
|
@@ -182,32 +203,6 @@ export declare class KoraClient {
|
|
|
182
203
|
* ```
|
|
183
204
|
*/
|
|
184
205
|
signAndSendBundle(request: SignAndSendBundleRequest): Promise<SignAndSendBundleResponse>;
|
|
185
|
-
/**
|
|
186
|
-
* Creates an unsigned transfer transaction.
|
|
187
|
-
*
|
|
188
|
-
* @deprecated Use `getPaymentInstruction` instead for fee payment flows.
|
|
189
|
-
*
|
|
190
|
-
* @param request - Transfer request parameters
|
|
191
|
-
* @param request.amount - Amount to transfer (in token's smallest unit)
|
|
192
|
-
* @param request.token - Mint address of the token to transfer
|
|
193
|
-
* @param request.source - Source wallet public key
|
|
194
|
-
* @param request.destination - Destination wallet public key
|
|
195
|
-
* @param request.signer_key - Optional signer key to select specific Kora signer
|
|
196
|
-
* @returns Unsigned transaction, message, blockhash, and signer info
|
|
197
|
-
* @throws {Error} When the RPC call fails or token is not supported
|
|
198
|
-
*
|
|
199
|
-
* @example
|
|
200
|
-
* ```typescript
|
|
201
|
-
* const transfer = await client.transferTransaction({
|
|
202
|
-
* amount: 1000000, // 1 USDC (6 decimals)
|
|
203
|
-
* token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
204
|
-
* source: 'sourceWalletPublicKey',
|
|
205
|
-
* destination: 'destinationWalletPublicKey',
|
|
206
|
-
* });
|
|
207
|
-
* console.log('Signer:', transfer.signer_pubkey);
|
|
208
|
-
* ```
|
|
209
|
-
*/
|
|
210
|
-
transferTransaction(request: TransferTransactionRequest): Promise<TransferTransactionResponse>;
|
|
211
206
|
/**
|
|
212
207
|
* Creates a payment instruction to append to a transaction for fee payment to the Kora paymaster.
|
|
213
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,28 @@ 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);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Estimates the bundle fee in both lamports and the specified token.
|
|
171
|
+
* @param request - Bundle fee estimation request parameters
|
|
172
|
+
* @param request.transactions - Array of base64-encoded transactions to estimate fees for
|
|
173
|
+
* @param request.fee_token - Mint address of the token to calculate fees in
|
|
174
|
+
* @returns Total fee amounts across all transactions in both lamports and the specified token
|
|
175
|
+
* @throws {Error} When the RPC call fails, the bundle is invalid, or the token is not supported
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const fees = await client.estimateBundleFee({
|
|
180
|
+
* transactions: ['base64EncodedTransaction1', 'base64EncodedTransaction2'],
|
|
181
|
+
* fee_token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC
|
|
182
|
+
* });
|
|
183
|
+
* console.log('Total fee in lamports:', fees.fee_in_lamports);
|
|
184
|
+
* console.log('Total fee in USDC:', fees.fee_in_token);
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
async estimateBundleFee(request) {
|
|
188
|
+
return await this.rpcRequest('estimateBundleFee', request);
|
|
169
189
|
}
|
|
170
190
|
/**
|
|
171
191
|
* Signs a transaction with the Kora fee payer without broadcasting it.
|
|
@@ -184,7 +204,7 @@ export class KoraClient {
|
|
|
184
204
|
* ```
|
|
185
205
|
*/
|
|
186
206
|
async signTransaction(request) {
|
|
187
|
-
return this.rpcRequest('signTransaction', request);
|
|
207
|
+
return await this.rpcRequest('signTransaction', request);
|
|
188
208
|
}
|
|
189
209
|
/**
|
|
190
210
|
* Signs a transaction and immediately broadcasts it to the Solana network.
|
|
@@ -202,7 +222,7 @@ export class KoraClient {
|
|
|
202
222
|
* ```
|
|
203
223
|
*/
|
|
204
224
|
async signAndSendTransaction(request) {
|
|
205
|
-
return this.rpcRequest('signAndSendTransaction', request);
|
|
225
|
+
return await this.rpcRequest('signAndSendTransaction', request);
|
|
206
226
|
}
|
|
207
227
|
/**
|
|
208
228
|
* Signs a bundle of transactions with the Kora fee payer without broadcasting.
|
|
@@ -210,6 +230,7 @@ export class KoraClient {
|
|
|
210
230
|
* @param request.transactions - Array of base64-encoded transactions to sign
|
|
211
231
|
* @param request.signer_key - Optional signer address for the transactions
|
|
212
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)
|
|
213
234
|
* @returns Array of signed transactions and signer public key
|
|
214
235
|
* @throws {Error} When the RPC call fails or validation fails
|
|
215
236
|
*
|
|
@@ -223,7 +244,7 @@ export class KoraClient {
|
|
|
223
244
|
* ```
|
|
224
245
|
*/
|
|
225
246
|
async signBundle(request) {
|
|
226
|
-
return this.rpcRequest('signBundle', request);
|
|
247
|
+
return await this.rpcRequest('signBundle', request);
|
|
227
248
|
}
|
|
228
249
|
/**
|
|
229
250
|
* Signs a bundle of transactions and sends them to Jito block engine.
|
|
@@ -231,6 +252,7 @@ export class KoraClient {
|
|
|
231
252
|
* @param request.transactions - Array of base64-encoded transactions to sign and send
|
|
232
253
|
* @param request.signer_key - Optional signer address for the transactions
|
|
233
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)
|
|
234
256
|
* @returns Array of signed transactions, signer public key, and Jito bundle UUID
|
|
235
257
|
* @throws {Error} When the RPC call fails, validation fails, or Jito submission fails
|
|
236
258
|
*
|
|
@@ -244,39 +266,7 @@ export class KoraClient {
|
|
|
244
266
|
* ```
|
|
245
267
|
*/
|
|
246
268
|
async signAndSendBundle(request) {
|
|
247
|
-
return this.rpcRequest('signAndSendBundle', request);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Creates an unsigned transfer transaction.
|
|
251
|
-
*
|
|
252
|
-
* @deprecated Use `getPaymentInstruction` instead for fee payment flows.
|
|
253
|
-
*
|
|
254
|
-
* @param request - Transfer request parameters
|
|
255
|
-
* @param request.amount - Amount to transfer (in token's smallest unit)
|
|
256
|
-
* @param request.token - Mint address of the token to transfer
|
|
257
|
-
* @param request.source - Source wallet public key
|
|
258
|
-
* @param request.destination - Destination wallet public key
|
|
259
|
-
* @param request.signer_key - Optional signer key to select specific Kora signer
|
|
260
|
-
* @returns Unsigned transaction, message, blockhash, and signer info
|
|
261
|
-
* @throws {Error} When the RPC call fails or token is not supported
|
|
262
|
-
*
|
|
263
|
-
* @example
|
|
264
|
-
* ```typescript
|
|
265
|
-
* const transfer = await client.transferTransaction({
|
|
266
|
-
* amount: 1000000, // 1 USDC (6 decimals)
|
|
267
|
-
* token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
268
|
-
* source: 'sourceWalletPublicKey',
|
|
269
|
-
* destination: 'destinationWalletPublicKey',
|
|
270
|
-
* });
|
|
271
|
-
* console.log('Signer:', transfer.signer_pubkey);
|
|
272
|
-
* ```
|
|
273
|
-
*/
|
|
274
|
-
async transferTransaction(request) {
|
|
275
|
-
const response = await this.rpcRequest('transferTransaction', request);
|
|
276
|
-
// Parse instructions from the message to enhance developer experience
|
|
277
|
-
// Always set instructions, even for empty messages (for consistency)
|
|
278
|
-
response.instructions = getInstructionsFromBase64Message(response.message || '');
|
|
279
|
-
return response;
|
|
269
|
+
return await this.rpcRequest('signAndSendBundle', request);
|
|
280
270
|
}
|
|
281
271
|
/**
|
|
282
272
|
* Creates a payment instruction to append to a transaction for fee payment to the Kora paymaster.
|
|
@@ -310,34 +300,37 @@ export class KoraClient {
|
|
|
310
300
|
assertIsAddress(fee_token);
|
|
311
301
|
assertIsAddress(token_program_id);
|
|
312
302
|
const { fee_in_token, payment_address, signer_pubkey } = await this.estimateTransactionFee({
|
|
313
|
-
transaction,
|
|
314
303
|
fee_token,
|
|
315
304
|
sig_verify,
|
|
316
305
|
signer_key,
|
|
306
|
+
transaction,
|
|
317
307
|
});
|
|
318
308
|
assertIsAddress(payment_address);
|
|
319
309
|
const [sourceTokenAccount] = await findAssociatedTokenPda({
|
|
310
|
+
mint: fee_token,
|
|
320
311
|
owner: source_wallet,
|
|
321
312
|
tokenProgram: token_program_id,
|
|
322
|
-
mint: fee_token,
|
|
323
313
|
});
|
|
324
314
|
const [destinationTokenAccount] = await findAssociatedTokenPda({
|
|
315
|
+
mint: fee_token,
|
|
325
316
|
owner: payment_address,
|
|
326
317
|
tokenProgram: token_program_id,
|
|
327
|
-
mint: fee_token,
|
|
328
318
|
});
|
|
319
|
+
if (fee_in_token === undefined) {
|
|
320
|
+
throw new Error('Fee token was specified but fee_in_token was not returned from server');
|
|
321
|
+
}
|
|
329
322
|
const paymentInstruction = getTransferInstruction({
|
|
330
|
-
source: sourceTokenAccount,
|
|
331
|
-
destination: destinationTokenAccount,
|
|
332
|
-
authority: createNoopSigner(source_wallet),
|
|
333
323
|
amount: fee_in_token,
|
|
324
|
+
authority: createNoopSigner(source_wallet),
|
|
325
|
+
destination: destinationTokenAccount,
|
|
326
|
+
source: sourceTokenAccount,
|
|
334
327
|
});
|
|
335
328
|
return {
|
|
336
329
|
original_transaction: transaction,
|
|
337
|
-
|
|
330
|
+
payment_address,
|
|
338
331
|
payment_amount: fee_in_token,
|
|
332
|
+
payment_instruction: paymentInstruction,
|
|
339
333
|
payment_token: fee_token,
|
|
340
|
-
payment_address,
|
|
341
334
|
signer_address: signer_pubkey,
|
|
342
335
|
};
|
|
343
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
|
+
}
|