@solana/kora 0.2.0-beta.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -27
- package/dist/src/client.d.ts +6 -198
- package/dist/src/client.js +12 -208
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +2 -1
- package/dist/src/kit/executor.d.ts +7 -0
- package/dist/src/kit/executor.js +55 -0
- package/dist/src/kit/index.d.ts +50 -0
- package/dist/src/kit/index.js +67 -0
- package/dist/src/kit/payment.d.ts +18 -0
- package/dist/src/kit/payment.js +69 -0
- package/dist/src/kit/planner.d.ts +4 -0
- package/dist/src/kit/planner.js +23 -0
- package/dist/src/kit/plugin.d.ts +31 -0
- package/dist/src/{plugin.js → kit/plugin.js} +13 -81
- package/dist/src/types/index.d.ts +89 -145
- package/dist/test/auth-setup.js +4 -4
- package/dist/test/integration.test.js +322 -172
- package/dist/test/kit-client.test.d.ts +1 -0
- package/dist/test/kit-client.test.js +473 -0
- package/dist/test/plugin.test.js +71 -126
- package/dist/test/setup.d.ts +13 -9
- package/dist/test/setup.js +36 -38
- package/dist/test/unit.test.js +141 -147
- package/package.json +31 -13
- package/dist/src/plugin.d.ts +0 -85
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { KoraKitClientConfig } from '../types/index.js';
|
|
2
|
+
/** The type returned by {@link createKitKoraClient}. */
|
|
3
|
+
export type KoraKitClient = Awaited<ReturnType<typeof createKitKoraClient>>;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a Kora Kit client composed from Kit plugins.
|
|
6
|
+
*
|
|
7
|
+
* The returned client satisfies `ClientWithPayer`, `ClientWithTransactionPlanning`,
|
|
8
|
+
* and `ClientWithTransactionSending`, making it composable with Kit program plugins.
|
|
9
|
+
*
|
|
10
|
+
* @beta This API is experimental and may change in future releases.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { createKitKoraClient } from '@solana/kora';
|
|
15
|
+
* import { address } from '@solana/kit';
|
|
16
|
+
*
|
|
17
|
+
* const client = await createKitKoraClient({
|
|
18
|
+
* endpoint: 'https://kora.example.com',
|
|
19
|
+
* rpcUrl: 'https://api.mainnet-beta.solana.com',
|
|
20
|
+
* feeToken: address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
|
|
21
|
+
* feePayerWallet: userSigner,
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* const result = await client.sendTransaction([myInstruction]);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function createKitKoraClient(config: KoraKitClientConfig): Promise<import("@solana/kit").Client<import("@solana/kit").ClientWithTransactionPlanning & import("@solana/kit").ClientWithTransactionSending & object & {
|
|
28
|
+
rpc: import("@solana/kit").Rpc<import("@solana/kit").RequestAirdropApi & import("@solana/kit").GetAccountInfoApi & import("@solana/kit").GetBalanceApi & import("@solana/kit").GetBlockApi & import("@solana/kit").GetBlockCommitmentApi & import("@solana/kit").GetBlockHeightApi & import("@solana/kit").GetBlockProductionApi & import("@solana/kit").GetBlocksApi & import("@solana/kit").GetBlocksWithLimitApi & import("@solana/kit").GetBlockTimeApi & import("@solana/kit").GetClusterNodesApi & import("@solana/kit").GetEpochInfoApi & import("@solana/kit").GetEpochScheduleApi & import("@solana/kit").GetFeeForMessageApi & import("@solana/kit").GetFirstAvailableBlockApi & import("@solana/kit").GetGenesisHashApi & import("@solana/kit").GetHealthApi & import("@solana/kit").GetHighestSnapshotSlotApi & import("@solana/kit").GetIdentityApi & import("@solana/kit").GetInflationGovernorApi & import("@solana/kit").GetInflationRateApi & import("@solana/kit").GetInflationRewardApi & import("@solana/kit").GetLargestAccountsApi & import("@solana/kit").GetLatestBlockhashApi & import("@solana/kit").GetLeaderScheduleApi & import("@solana/kit").GetMaxRetransmitSlotApi & import("@solana/kit").GetMaxShredInsertSlotApi & import("@solana/kit").GetMinimumBalanceForRentExemptionApi & import("@solana/kit").GetMultipleAccountsApi & import("@solana/kit").GetProgramAccountsApi & import("@solana/kit").GetRecentPerformanceSamplesApi & import("@solana/kit").GetRecentPrioritizationFeesApi & import("@solana/kit").GetSignaturesForAddressApi & import("@solana/kit").GetSignatureStatusesApi & import("@solana/kit").GetSlotApi & import("@solana/kit").GetSlotLeaderApi & import("@solana/kit").GetSlotLeadersApi & import("@solana/kit").GetStakeMinimumDelegationApi & import("@solana/kit").GetSupplyApi & import("@solana/kit").GetTokenAccountBalanceApi & import("@solana/kit").GetTokenAccountsByDelegateApi & import("@solana/kit").GetTokenAccountsByOwnerApi & import("@solana/kit").GetTokenLargestAccountsApi & import("@solana/kit").GetTokenSupplyApi & import("@solana/kit").GetTransactionApi & import("@solana/kit").GetTransactionCountApi & import("@solana/kit").GetVersionApi & import("@solana/kit").GetVoteAccountsApi & import("@solana/kit").IsBlockhashValidApi & import("@solana/kit").MinimumLedgerSlotApi & import("@solana/kit").SendTransactionApi & import("@solana/kit").SimulateTransactionApi>;
|
|
29
|
+
rpcSubscriptions: import("@solana/kit").RpcSubscriptions<import("@solana/kit").SolanaRpcSubscriptionsApi>;
|
|
30
|
+
} & {
|
|
31
|
+
kora: {
|
|
32
|
+
estimateTransactionFee(request: import("../types/index.js").EstimateTransactionFeeRequest): Promise<import("../types/index.js").KitEstimateFeeResponse>;
|
|
33
|
+
getBlockhash(): Promise<import("../types/index.js").KitBlockhashResponse>;
|
|
34
|
+
getConfig(): Promise<import("../types/index.js").KitConfigResponse>;
|
|
35
|
+
getPayerSigner(): Promise<import("../types/index.js").KitPayerSignerResponse>;
|
|
36
|
+
getPaymentInstruction(request: import("../types/index.js").GetPaymentInstructionRequest): Promise<import("../types/index.js").KitPaymentInstructionResponse>;
|
|
37
|
+
getSupportedTokens(): Promise<import("../types/index.js").KitSupportedTokensResponse>;
|
|
38
|
+
signAndSendTransaction(request: import("../types/index.js").SignAndSendTransactionRequest): Promise<import("../types/index.js").KitSignAndSendTransactionResponse>;
|
|
39
|
+
signTransaction(request: import("../types/index.js").SignTransactionRequest): Promise<import("../types/index.js").KitSignTransactionResponse>;
|
|
40
|
+
transferTransaction(request: import("../types/index.js").TransferTransactionRequest): Promise<import("../types/index.js").KitTransferTransactionResponse>;
|
|
41
|
+
};
|
|
42
|
+
} & {
|
|
43
|
+
payer: import("@solana/kit").TransactionSigner;
|
|
44
|
+
} & {
|
|
45
|
+
paymentAddress: import("@solana/kit").Address | undefined;
|
|
46
|
+
} & {
|
|
47
|
+
transactionPlanner: import("@solana/kit").TransactionPlanner;
|
|
48
|
+
} & {
|
|
49
|
+
transactionPlanExecutor: import("@solana/kit").TransactionPlanExecutor;
|
|
50
|
+
}>>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { address, createEmptyClient, createNoopSigner, createSolanaRpc } from '@solana/kit';
|
|
2
|
+
import { planAndSendTransactions, transactionPlanExecutor as transactionPlanExecutorPlugin, transactionPlanner as transactionPlannerPlugin, } from '@solana/kit-plugin-instruction-plan';
|
|
3
|
+
import { payer } from '@solana/kit-plugin-payer';
|
|
4
|
+
import { rpc } from '@solana/kit-plugin-rpc';
|
|
5
|
+
import { estimateAndUpdateProvisoryComputeUnitLimitFactory, estimateComputeUnitLimitFactory, } from '@solana-program/compute-budget';
|
|
6
|
+
import { KoraClient } from '../client.js';
|
|
7
|
+
import { createKoraTransactionPlanExecutor } from './executor.js';
|
|
8
|
+
import { buildPlaceholderPaymentInstruction, koraPaymentAddress } from './payment.js';
|
|
9
|
+
import { buildComputeBudgetInstructions, createKoraTransactionPlanner } from './planner.js';
|
|
10
|
+
import { koraPlugin } from './plugin.js';
|
|
11
|
+
/**
|
|
12
|
+
* Creates a Kora Kit client composed from Kit plugins.
|
|
13
|
+
*
|
|
14
|
+
* The returned client satisfies `ClientWithPayer`, `ClientWithTransactionPlanning`,
|
|
15
|
+
* and `ClientWithTransactionSending`, making it composable with Kit program plugins.
|
|
16
|
+
*
|
|
17
|
+
* @beta This API is experimental and may change in future releases.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { createKitKoraClient } from '@solana/kora';
|
|
22
|
+
* import { address } from '@solana/kit';
|
|
23
|
+
*
|
|
24
|
+
* const client = await createKitKoraClient({
|
|
25
|
+
* endpoint: 'https://kora.example.com',
|
|
26
|
+
* rpcUrl: 'https://api.mainnet-beta.solana.com',
|
|
27
|
+
* feeToken: address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
|
|
28
|
+
* feePayerWallet: userSigner,
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* const result = await client.sendTransaction([myInstruction]);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export async function createKitKoraClient(config) {
|
|
35
|
+
const koraClient = new KoraClient({
|
|
36
|
+
apiKey: config.apiKey,
|
|
37
|
+
hmacSecret: config.hmacSecret,
|
|
38
|
+
rpcUrl: config.endpoint,
|
|
39
|
+
});
|
|
40
|
+
const { signer_address, payment_address } = await koraClient.getPayerSigner();
|
|
41
|
+
const paymentAddr = payment_address ? address(payment_address) : undefined;
|
|
42
|
+
const payerSigner = createNoopSigner(address(signer_address));
|
|
43
|
+
const computeBudgetIxs = buildComputeBudgetInstructions(config);
|
|
44
|
+
const solanaRpc = createSolanaRpc(config.rpcUrl);
|
|
45
|
+
const hasCuEstimation = config.computeUnitLimit === undefined;
|
|
46
|
+
const resolveProvisoryComputeUnitLimit = hasCuEstimation
|
|
47
|
+
? estimateAndUpdateProvisoryComputeUnitLimitFactory(estimateComputeUnitLimitFactory({ rpc: solanaRpc }))
|
|
48
|
+
: undefined;
|
|
49
|
+
const payment = paymentAddr
|
|
50
|
+
? await buildPlaceholderPaymentInstruction(config.feePayerWallet, paymentAddr, config.feeToken, config.tokenProgramId)
|
|
51
|
+
: undefined;
|
|
52
|
+
const koraTransactionPlanner = createKoraTransactionPlanner(payerSigner, computeBudgetIxs, payment?.instruction, hasCuEstimation);
|
|
53
|
+
const koraTransactionPlanExecutor = createKoraTransactionPlanExecutor(koraClient, config, payerSigner, payment
|
|
54
|
+
? {
|
|
55
|
+
destinationTokenAccount: payment.destinationTokenAccount,
|
|
56
|
+
sourceTokenAccount: payment.sourceTokenAccount,
|
|
57
|
+
}
|
|
58
|
+
: undefined, resolveProvisoryComputeUnitLimit);
|
|
59
|
+
return createEmptyClient()
|
|
60
|
+
.use(rpc(config.rpcUrl))
|
|
61
|
+
.use(koraPlugin({ apiKey: config.apiKey, endpoint: config.endpoint, hmacSecret: config.hmacSecret }))
|
|
62
|
+
.use(payer(payerSigner))
|
|
63
|
+
.use(koraPaymentAddress(paymentAddr))
|
|
64
|
+
.use(transactionPlannerPlugin(koraTransactionPlanner))
|
|
65
|
+
.use(transactionPlanExecutorPlugin(koraTransactionPlanExecutor))
|
|
66
|
+
.use(planAndSendTransactions());
|
|
67
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Address, type Instruction, type TransactionSigner } from '@solana/kit';
|
|
2
|
+
/** Plugin that adds a `paymentAddress` to the client. */
|
|
3
|
+
export declare function koraPaymentAddress(paymentAddress?: Address): <T extends object>(client: T) => T & {
|
|
4
|
+
paymentAddress: Address | undefined;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Builds a placeholder payment instruction (amount=0) to reserve transaction space
|
|
8
|
+
* during planning. The executor later replaces it with the real fee amount.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildPlaceholderPaymentInstruction(feePayerWallet: TransactionSigner, paymentAddress: Address, feeToken: Address, tokenProgramId?: Address): Promise<{
|
|
11
|
+
destinationTokenAccount: Address;
|
|
12
|
+
instruction: Instruction;
|
|
13
|
+
sourceTokenAccount: Address;
|
|
14
|
+
}>;
|
|
15
|
+
/** Replaces the placeholder (amount=0) with the estimated fee amount. */
|
|
16
|
+
export declare function updatePaymentInstructionAmount(instructions: readonly Instruction[], feePayerWallet: TransactionSigner, sourceTokenAccount: Address, destinationTokenAccount: Address, amount: bigint | number, tokenProgramId?: Address): Instruction[];
|
|
17
|
+
/** Removes the placeholder payment instruction (used when fee is 0). */
|
|
18
|
+
export declare function removePaymentInstruction(instructions: readonly Instruction[], sourceTokenAccount: Address, destinationTokenAccount: Address, feePayerWallet: TransactionSigner, tokenProgramId?: Address): Instruction[];
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { findAssociatedTokenPda, getTransferInstruction, parseTransferInstruction, TOKEN_PROGRAM_ADDRESS, TRANSFER_DISCRIMINATOR, } from '@solana-program/token';
|
|
2
|
+
/** Plugin that adds a `paymentAddress` to the client. */
|
|
3
|
+
export function koraPaymentAddress(paymentAddress) {
|
|
4
|
+
return (client) => ({
|
|
5
|
+
...client,
|
|
6
|
+
paymentAddress,
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Builds a placeholder payment instruction (amount=0) to reserve transaction space
|
|
11
|
+
* during planning. The executor later replaces it with the real fee amount.
|
|
12
|
+
*/
|
|
13
|
+
export async function buildPlaceholderPaymentInstruction(feePayerWallet, paymentAddress, feeToken, tokenProgramId) {
|
|
14
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ADDRESS;
|
|
15
|
+
const [sourceTokenAccount] = await findAssociatedTokenPda({
|
|
16
|
+
mint: feeToken,
|
|
17
|
+
owner: feePayerWallet.address,
|
|
18
|
+
tokenProgram,
|
|
19
|
+
});
|
|
20
|
+
const [destinationTokenAccount] = await findAssociatedTokenPda({
|
|
21
|
+
mint: feeToken,
|
|
22
|
+
owner: paymentAddress,
|
|
23
|
+
tokenProgram,
|
|
24
|
+
});
|
|
25
|
+
const instruction = getTransferInstruction({
|
|
26
|
+
amount: 0,
|
|
27
|
+
authority: feePayerWallet,
|
|
28
|
+
destination: destinationTokenAccount,
|
|
29
|
+
source: sourceTokenAccount,
|
|
30
|
+
});
|
|
31
|
+
return { destinationTokenAccount, instruction, sourceTokenAccount };
|
|
32
|
+
}
|
|
33
|
+
function isPlaceholderPaymentInstruction(ix, sourceTokenAccount, destinationTokenAccount, feePayerWallet, tokenProgramId) {
|
|
34
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ADDRESS;
|
|
35
|
+
if (ix.programAddress !== tokenProgram)
|
|
36
|
+
return false;
|
|
37
|
+
if (ix.data?.[0] !== TRANSFER_DISCRIMINATOR)
|
|
38
|
+
return false;
|
|
39
|
+
const parsed = parseTransferInstruction(ix);
|
|
40
|
+
return (parsed.accounts.source.address === sourceTokenAccount &&
|
|
41
|
+
parsed.accounts.destination.address === destinationTokenAccount &&
|
|
42
|
+
parsed.accounts.authority.address === feePayerWallet.address &&
|
|
43
|
+
parsed.data.amount === 0n);
|
|
44
|
+
}
|
|
45
|
+
/** Replaces the placeholder (amount=0) with the estimated fee amount. */
|
|
46
|
+
export function updatePaymentInstructionAmount(instructions, feePayerWallet, sourceTokenAccount, destinationTokenAccount, amount, tokenProgramId) {
|
|
47
|
+
let replaced = false;
|
|
48
|
+
const result = instructions.map(ix => {
|
|
49
|
+
if (!isPlaceholderPaymentInstruction(ix, sourceTokenAccount, destinationTokenAccount, feePayerWallet, tokenProgramId)) {
|
|
50
|
+
return ix;
|
|
51
|
+
}
|
|
52
|
+
replaced = true;
|
|
53
|
+
return getTransferInstruction({
|
|
54
|
+
amount,
|
|
55
|
+
authority: feePayerWallet,
|
|
56
|
+
destination: destinationTokenAccount,
|
|
57
|
+
source: sourceTokenAccount,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
if (!replaced) {
|
|
61
|
+
throw new Error('Failed to update payment instruction: no matching placeholder transfer instruction found. ' +
|
|
62
|
+
'This is a Kora SDK internal error — the transaction message may have been modified between planning and execution.');
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
/** Removes the placeholder payment instruction (used when fee is 0). */
|
|
67
|
+
export function removePaymentInstruction(instructions, sourceTokenAccount, destinationTokenAccount, feePayerWallet, tokenProgramId) {
|
|
68
|
+
return instructions.filter(ix => !isPlaceholderPaymentInstruction(ix, sourceTokenAccount, destinationTokenAccount, feePayerWallet, tokenProgramId));
|
|
69
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Instruction, type TransactionSigner } from '@solana/kit';
|
|
2
|
+
import type { KoraKitClientConfig } from '../types/index.js';
|
|
3
|
+
export declare function buildComputeBudgetInstructions(config: KoraKitClientConfig): Instruction[];
|
|
4
|
+
export declare function createKoraTransactionPlanner(payerSigner: TransactionSigner, computeBudgetIxs: Instruction[], paymentInstruction: Instruction | undefined, hasCuEstimation: boolean): import("@solana/kit").TransactionPlanner;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { appendTransactionMessageInstructions, createTransactionMessage, createTransactionPlanner, pipe, setTransactionMessageFeePayerSigner, } from '@solana/kit';
|
|
2
|
+
import { fillProvisorySetComputeUnitLimitInstruction, getSetComputeUnitLimitInstruction, getSetComputeUnitPriceInstruction, } from '@solana-program/compute-budget';
|
|
3
|
+
export function buildComputeBudgetInstructions(config) {
|
|
4
|
+
const instructions = [];
|
|
5
|
+
if (config.computeUnitLimit !== undefined) {
|
|
6
|
+
instructions.push(getSetComputeUnitLimitInstruction({ units: config.computeUnitLimit }));
|
|
7
|
+
}
|
|
8
|
+
if (config.computeUnitPrice !== undefined) {
|
|
9
|
+
instructions.push(getSetComputeUnitPriceInstruction({ microLamports: config.computeUnitPrice }));
|
|
10
|
+
}
|
|
11
|
+
return instructions;
|
|
12
|
+
}
|
|
13
|
+
export function createKoraTransactionPlanner(payerSigner, computeBudgetIxs, paymentInstruction, hasCuEstimation) {
|
|
14
|
+
return createTransactionPlanner({
|
|
15
|
+
createTransactionMessage: () => {
|
|
16
|
+
const allIxs = [...computeBudgetIxs];
|
|
17
|
+
if (paymentInstruction) {
|
|
18
|
+
allIxs.push(paymentInstruction);
|
|
19
|
+
}
|
|
20
|
+
return pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayerSigner(payerSigner, m), m => appendTransactionMessageInstructions(allIxs, m), m => (hasCuEstimation ? fillProvisorySetComputeUnitLimitInstruction(m) : m));
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { EstimateTransactionFeeRequest, GetPaymentInstructionRequest, KitBlockhashResponse, KitConfigResponse, KitEstimateFeeResponse, KitPayerSignerResponse, KitPaymentInstructionResponse, KitSignAndSendTransactionResponse, KitSignTransactionResponse, KitSupportedTokensResponse, KitTransferTransactionResponse, KoraPluginConfig, SignAndSendTransactionRequest, SignTransactionRequest, TransferTransactionRequest } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Kit plugin that adds `.kora` namespace with all Kora RPC methods.
|
|
4
|
+
* Responses are cast to Kit types (Address, Blockhash, Signature).
|
|
5
|
+
*
|
|
6
|
+
* Requires `@solana/kit` v5.4.0+ for the `createEmptyClient().use()` pattern.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const client = createEmptyClient()
|
|
11
|
+
* .use(koraPlugin({ endpoint: 'https://kora.example.com' }));
|
|
12
|
+
*
|
|
13
|
+
* const config = await client.kora.getConfig();
|
|
14
|
+
* const { signer_pubkey } = await client.kora.signTransaction({ transaction: tx });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function koraPlugin(config: KoraPluginConfig): <T extends object>(c: T) => T & {
|
|
18
|
+
kora: {
|
|
19
|
+
estimateTransactionFee(request: EstimateTransactionFeeRequest): Promise<KitEstimateFeeResponse>;
|
|
20
|
+
getBlockhash(): Promise<KitBlockhashResponse>;
|
|
21
|
+
getConfig(): Promise<KitConfigResponse>;
|
|
22
|
+
getPayerSigner(): Promise<KitPayerSignerResponse>;
|
|
23
|
+
getPaymentInstruction(request: GetPaymentInstructionRequest): Promise<KitPaymentInstructionResponse>;
|
|
24
|
+
getSupportedTokens(): Promise<KitSupportedTokensResponse>;
|
|
25
|
+
signAndSendTransaction(request: SignAndSendTransactionRequest): Promise<KitSignAndSendTransactionResponse>;
|
|
26
|
+
signTransaction(request: SignTransactionRequest): Promise<KitSignTransactionResponse>;
|
|
27
|
+
transferTransaction(request: TransferTransactionRequest): Promise<KitTransferTransactionResponse>;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
/** Type representing the Kora plugin namespace on the client. */
|
|
31
|
+
export type KoraPlugin = ReturnType<ReturnType<typeof koraPlugin>>['kora'];
|
|
@@ -1,33 +1,18 @@
|
|
|
1
1
|
import { address, blockhash, signature } from '@solana/kit';
|
|
2
|
-
import { KoraClient } from '
|
|
2
|
+
import { KoraClient } from '../client.js';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Kit plugin that adds `.kora` namespace with all Kora RPC methods.
|
|
5
|
+
* Responses are cast to Kit types (Address, Blockhash, Signature).
|
|
5
6
|
*
|
|
6
|
-
*
|
|
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
|
|
7
|
+
* Requires `@solana/kit` v5.4.0+ for the `createEmptyClient().use()` pattern.
|
|
16
8
|
*
|
|
17
9
|
* @example
|
|
18
10
|
* ```typescript
|
|
19
|
-
* import { createEmptyClient } from '@solana/kit';
|
|
20
|
-
* import { koraPlugin } from '@solana/kora';
|
|
21
|
-
*
|
|
22
11
|
* const client = createEmptyClient()
|
|
23
12
|
* .use(koraPlugin({ endpoint: 'https://kora.example.com' }));
|
|
24
13
|
*
|
|
25
|
-
* // All responses have Kit-typed fields
|
|
26
14
|
* const config = await client.kora.getConfig();
|
|
27
|
-
* // config.fee_payers is Address[] not string[]
|
|
28
|
-
*
|
|
29
15
|
* const { signer_pubkey } = await client.kora.signTransaction({ transaction: tx });
|
|
30
|
-
* // signer_pubkey is Address not string
|
|
31
16
|
* ```
|
|
32
17
|
*/
|
|
33
18
|
export function koraPlugin(config) {
|
|
@@ -39,21 +24,6 @@ export function koraPlugin(config) {
|
|
|
39
24
|
return (c) => ({
|
|
40
25
|
...c,
|
|
41
26
|
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
27
|
async estimateTransactionFee(request) {
|
|
58
28
|
const result = await client.estimateTransactionFee(request);
|
|
59
29
|
return {
|
|
@@ -63,18 +33,12 @@ export function koraPlugin(config) {
|
|
|
63
33
|
signer_pubkey: address(result.signer_pubkey),
|
|
64
34
|
};
|
|
65
35
|
},
|
|
66
|
-
/**
|
|
67
|
-
* Gets the latest blockhash with Kit Blockhash type.
|
|
68
|
-
*/
|
|
69
36
|
async getBlockhash() {
|
|
70
37
|
const result = await client.getBlockhash();
|
|
71
38
|
return {
|
|
72
39
|
blockhash: blockhash(result.blockhash),
|
|
73
40
|
};
|
|
74
41
|
},
|
|
75
|
-
/**
|
|
76
|
-
* Retrieves the current Kora server configuration with Kit-typed addresses.
|
|
77
|
-
*/
|
|
78
42
|
async getConfig() {
|
|
79
43
|
const result = await client.getConfig();
|
|
80
44
|
return {
|
|
@@ -89,9 +53,6 @@ export function koraPlugin(config) {
|
|
|
89
53
|
},
|
|
90
54
|
};
|
|
91
55
|
},
|
|
92
|
-
/**
|
|
93
|
-
* Retrieves the payer signer and payment destination with Kit-typed addresses.
|
|
94
|
-
*/
|
|
95
56
|
async getPayerSigner() {
|
|
96
57
|
const result = await client.getPayerSigner();
|
|
97
58
|
return {
|
|
@@ -99,9 +60,6 @@ export function koraPlugin(config) {
|
|
|
99
60
|
signer_address: address(result.signer_address),
|
|
100
61
|
};
|
|
101
62
|
},
|
|
102
|
-
/**
|
|
103
|
-
* Creates a payment instruction with Kit-typed response.
|
|
104
|
-
*/
|
|
105
63
|
async getPaymentInstruction(request) {
|
|
106
64
|
const result = await client.getPaymentInstruction(request);
|
|
107
65
|
return {
|
|
@@ -113,35 +71,12 @@ export function koraPlugin(config) {
|
|
|
113
71
|
signer_address: address(result.signer_address),
|
|
114
72
|
};
|
|
115
73
|
},
|
|
116
|
-
/**
|
|
117
|
-
* Retrieves the list of tokens supported for fee payment with Kit-typed addresses.
|
|
118
|
-
*/
|
|
119
74
|
async getSupportedTokens() {
|
|
120
75
|
const result = await client.getSupportedTokens();
|
|
121
76
|
return {
|
|
122
77
|
tokens: result.tokens.map(addr => address(addr)),
|
|
123
78
|
};
|
|
124
79
|
},
|
|
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
80
|
async signAndSendTransaction(request) {
|
|
146
81
|
const result = await client.signAndSendTransaction(request);
|
|
147
82
|
return {
|
|
@@ -150,24 +85,21 @@ export function koraPlugin(config) {
|
|
|
150
85
|
signer_pubkey: address(result.signer_pubkey),
|
|
151
86
|
};
|
|
152
87
|
},
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
*/
|
|
156
|
-
async signBundle(request) {
|
|
157
|
-
const result = await client.signBundle(request);
|
|
88
|
+
async signTransaction(request) {
|
|
89
|
+
const result = await client.signTransaction(request);
|
|
158
90
|
return {
|
|
159
|
-
|
|
91
|
+
signed_transaction: result.signed_transaction,
|
|
160
92
|
signer_pubkey: address(result.signer_pubkey),
|
|
161
93
|
};
|
|
162
94
|
},
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
*/
|
|
166
|
-
async signTransaction(request) {
|
|
167
|
-
const result = await client.signTransaction(request);
|
|
95
|
+
async transferTransaction(request) {
|
|
96
|
+
const result = await client.transferTransaction(request);
|
|
168
97
|
return {
|
|
169
|
-
|
|
98
|
+
blockhash: blockhash(result.blockhash),
|
|
99
|
+
instructions: result.instructions,
|
|
100
|
+
message: result.message,
|
|
170
101
|
signer_pubkey: address(result.signer_pubkey),
|
|
102
|
+
transaction: result.transaction,
|
|
171
103
|
};
|
|
172
104
|
},
|
|
173
105
|
},
|