-
Notifications
You must be signed in to change notification settings - Fork 245
Expand file tree
/
Copy pathindex.ts
More file actions
113 lines (103 loc) · 4.28 KB
/
index.ts
File metadata and controls
113 lines (103 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { address, createEmptyClient, createNoopSigner, createSolanaRpc } from '@solana/kit';
import {
planAndSendTransactions,
transactionPlanExecutor as transactionPlanExecutorPlugin,
transactionPlanner as transactionPlannerPlugin,
} from '@solana/kit-plugin-instruction-plan';
import { payer } from '@solana/kit-plugin-payer';
import { rpc } from '@solana/kit-plugin-rpc';
import {
estimateAndUpdateProvisoryComputeUnitLimitFactory,
estimateComputeUnitLimitFactory,
} from '@solana-program/compute-budget';
import { KoraClient } from '../client.js';
import { koraPlugin } from '../plugin.js';
import type { KoraKitClientConfig } from '../types/index.js';
import { createKoraTransactionPlanExecutor } from './executor.js';
import { buildPlaceholderPaymentInstruction, koraPaymentAddress } from './payment.js';
import { buildComputeBudgetInstructions, createKoraTransactionPlanner } from './planner.js';
/** The type returned by {@link createKitKoraClient}. */
export type KoraKitClient = Awaited<ReturnType<typeof createKitKoraClient>>;
/**
* Creates a Kora Kit client composed from Kit plugins.
*
* The returned client satisfies `ClientWithPayer`, `ClientWithTransactionPlanning`,
* and `ClientWithTransactionSending`, making it composable with Kit program plugins.
*
* @beta This API is experimental and may change in future releases.
*
* @example
* ```typescript
* import { createKitKoraClient } from '@solana/kora';
* import { address } from '@solana/kit';
*
* const client = await createKitKoraClient({
* endpoint: 'https://kora.example.com',
* rpcUrl: 'https://api.mainnet-beta.solana.com',
* feeToken: address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
* feePayerWallet: userSigner,
* });
*
* const result = await client.sendTransaction([myInstruction]);
* ```
*/
// TODO: Bundle support — the plan/execute pipeline currently handles single transactions only.
// For Jito bundles, users must manually encode transactions and call `client.kora.signAndSendBundle()`.
// A future `createKitKoraBundleClient` (or a bundle-aware executor plugin) could extend this to
// plan multiple transaction messages and submit them as a single bundle.
export async function createKitKoraClient(config: KoraKitClientConfig) {
const koraClient = new KoraClient({
apiKey: config.apiKey,
getRecaptchaToken: config.getRecaptchaToken,
hmacSecret: config.hmacSecret,
rpcUrl: config.endpoint,
});
const { signer_address, payment_address } = await koraClient.getPayerSigner();
const paymentAddr = payment_address ? address(payment_address) : undefined;
const payerSigner = createNoopSigner(address(signer_address));
const computeBudgetIxs = buildComputeBudgetInstructions(config);
const solanaRpc = createSolanaRpc(config.rpcUrl);
const hasCuEstimation = config.computeUnitLimit === undefined;
const resolveProvisoryComputeUnitLimit = hasCuEstimation
? estimateAndUpdateProvisoryComputeUnitLimitFactory(estimateComputeUnitLimitFactory({ rpc: solanaRpc }))
: undefined;
const payment = paymentAddr
? await buildPlaceholderPaymentInstruction(
config.feePayerWallet,
paymentAddr,
config.feeToken,
config.tokenProgramId,
)
: undefined;
const koraTransactionPlanner = createKoraTransactionPlanner(
payerSigner,
computeBudgetIxs,
payment?.instruction,
hasCuEstimation,
);
const koraTransactionPlanExecutor = createKoraTransactionPlanExecutor(
koraClient,
config,
payerSigner,
payment
? {
destinationTokenAccount: payment.destinationTokenAccount,
sourceTokenAccount: payment.sourceTokenAccount,
}
: undefined,
resolveProvisoryComputeUnitLimit,
);
return createEmptyClient()
.use(rpc(config.rpcUrl))
.use(
koraPlugin({
endpoint: config.endpoint,
koraClient,
}),
)
.use(payer(payerSigner))
.use(koraPaymentAddress(paymentAddr))
.use(transactionPlannerPlugin(koraTransactionPlanner))
.use(transactionPlanExecutorPlugin(koraTransactionPlanExecutor))
.use(planAndSendTransactions());
}