@solana/kora 0.2.0-beta.3 → 0.2.0-beta.6
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 +3 -1
- package/dist/src/client.js +10 -3
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/kit/executor.d.ts +7 -0
- package/dist/src/kit/executor.js +68 -0
- package/dist/src/kit/index.d.ts +53 -0
- package/dist/src/kit/index.js +75 -0
- package/dist/src/kit/payment.d.ts +18 -0
- package/dist/src/kit/payment.js +70 -0
- package/dist/src/kit/planner.d.ts +4 -0
- package/dist/src/kit/planner.js +23 -0
- package/dist/src/plugin.js +7 -5
- package/dist/src/types/index.d.ts +37 -1
- package/dist/test/integration.test.js +43 -16
- package/dist/test/kit-client.test.d.ts +1 -0
- package/dist/test/kit-client.test.js +491 -0
- package/dist/test/setup.d.ts +1 -4
- package/dist/test/setup.js +34 -136
- package/dist/test/unit.test.js +106 -22
- package/package.json +26 -16
package/dist/test/setup.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { findAssociatedTokenPda, getCreateAssociatedTokenIdempotentInstructionAsync, getInitializeMintInstruction, getMintSize, getMintToInstruction, TOKEN_PROGRAM_ADDRESS, } from '@solana-program/token';
|
|
1
|
+
import { assertIsAddress, createKeyPairSignerFromBytes, getBase58Encoder, lamports, } from '@solana/kit';
|
|
2
|
+
import { createClient } from '@solana/kit-client-litesvm';
|
|
3
|
+
import { tokenProgram, associatedTokenProgram } from '@solana-program/token';
|
|
5
4
|
import { config } from 'dotenv';
|
|
6
5
|
import path from 'path';
|
|
7
6
|
import { KoraClient } from '../src/index.js';
|
|
8
7
|
config({ path: path.resolve(process.cwd(), '.env') });
|
|
9
8
|
const DEFAULTS = {
|
|
10
|
-
COMMITMENT: 'processed',
|
|
11
9
|
DECIMALS: 6,
|
|
12
10
|
// Make sure this matches the USDC mint in kora.toml (9BgeTKqmFsPVnfYscfM6NvsgmZxei7XfdciShQ6D3bxJ)
|
|
13
11
|
DESTINATION_ADDRESS: 'AVmDft8deQEo78bRKcGN5ZMf3hyjeLBK4Rd4xGB46yQM',
|
|
@@ -17,8 +15,6 @@ const DEFAULTS = {
|
|
|
17
15
|
KORA_SIGNER_TYPE: 'memory',
|
|
18
16
|
// Make sure this matches the kora-rpc signer address on launch (root .env)
|
|
19
17
|
SENDER_SECRET: 'tzgfgSWTE3KUA6qfRoFYLaSfJm59uUeZRDy4ybMrLn1JV2drA1mftiaEcVFvq1Lok6h6EX2C4Y9kSKLvQWyMpS5',
|
|
20
|
-
SOLANA_RPC_URL: 'http://127.0.0.1:8899',
|
|
21
|
-
SOLANA_WS_URL: 'ws://127.0.0.1:8900',
|
|
22
18
|
SOL_DROP_AMOUNT: 1_000_000_000,
|
|
23
19
|
// HhA5j2rRiPbMrpF2ZD36r69FyZf3zWmEHRNSZbbNdVjf
|
|
24
20
|
TEST_USDC_MINT_SECRET: '59kKmXphL5UJANqpFFjtH17emEq3oRNmYsx6a3P3vSGJRmhMgVdzH77bkNEi9bArRViT45e8L2TsuPxKNFoc3Qfg',
|
|
@@ -54,9 +50,6 @@ export function loadEnvironmentVariables() {
|
|
|
54
50
|
}
|
|
55
51
|
}
|
|
56
52
|
const koraRpcUrl = process.env.KORA_RPC_URL || DEFAULTS.KORA_RPC_URL;
|
|
57
|
-
const solanaRpcUrl = process.env.SOLANA_RPC_URL || DEFAULTS.SOLANA_RPC_URL;
|
|
58
|
-
const solanaWsUrl = process.env.SOLANA_WS_URL || DEFAULTS.SOLANA_WS_URL;
|
|
59
|
-
const commitment = (process.env.COMMITMENT || DEFAULTS.COMMITMENT);
|
|
60
53
|
const tokenDecimals = Number(process.env.TOKEN_DECIMALS || DEFAULTS.DECIMALS);
|
|
61
54
|
const tokenDropAmount = Number(process.env.TOKEN_DROP_AMOUNT || DEFAULTS.TOKEN_DROP_AMOUNT);
|
|
62
55
|
const solDropAmount = BigInt(process.env.SOL_DROP_AMOUNT || DEFAULTS.SOL_DROP_AMOUNT);
|
|
@@ -66,14 +59,11 @@ export function loadEnvironmentVariables() {
|
|
|
66
59
|
assertIsAddress(destinationAddress);
|
|
67
60
|
assertIsAddress(koraAddress);
|
|
68
61
|
return {
|
|
69
|
-
commitment,
|
|
70
62
|
destinationAddress,
|
|
71
63
|
koraAddress,
|
|
72
64
|
koraRpcUrl,
|
|
73
65
|
koraSignerType,
|
|
74
66
|
solDropAmount,
|
|
75
|
-
solanaRpcUrl,
|
|
76
|
-
solanaWsUrl,
|
|
77
67
|
testUsdcMintSecret,
|
|
78
68
|
testWalletSecret,
|
|
79
69
|
tokenDecimals,
|
|
@@ -90,129 +80,46 @@ async function createKeyPairSigners() {
|
|
|
90
80
|
usdcMint,
|
|
91
81
|
};
|
|
92
82
|
}
|
|
93
|
-
const createDefaultTransaction = async (client, feePayer, computeLimit = MAX_COMPUTE_UNIT_LIMIT, feeMicroLamports = 1n) => {
|
|
94
|
-
const { value: latestBlockhash } = await client.rpc.getLatestBlockhash().send();
|
|
95
|
-
return pipe(createTransactionMessage({ version: 0 }), tx => setTransactionMessageFeePayerSigner(feePayer, tx), tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), tx => updateOrAppendSetComputeUnitPriceInstruction(feeMicroLamports, tx), tx => updateOrAppendSetComputeUnitLimitInstruction(computeLimit, tx));
|
|
96
|
-
};
|
|
97
|
-
const signAndSendTransaction = async (client, transactionMessage, commitment) => {
|
|
98
|
-
const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
|
|
99
|
-
const signature = getSignatureFromTransaction(signedTransaction);
|
|
100
|
-
assertIsSendableTransaction(signedTransaction);
|
|
101
|
-
assertIsTransactionWithBlockhashLifetime(signedTransaction);
|
|
102
|
-
await sendAndConfirmTransactionFactory(client)(signedTransaction, { commitment, skipPreflight: true });
|
|
103
|
-
return signature;
|
|
104
|
-
};
|
|
105
|
-
function safeStringify(obj) {
|
|
106
|
-
return JSON.stringify(obj, (key, value) => {
|
|
107
|
-
if (typeof value === 'bigint') {
|
|
108
|
-
return value.toString();
|
|
109
|
-
}
|
|
110
|
-
return value;
|
|
111
|
-
}, 2);
|
|
112
|
-
}
|
|
113
|
-
async function sendAndConfirmInstructions(client, payer, instructions, description, commitment = loadEnvironmentVariables().commitment) {
|
|
114
|
-
try {
|
|
115
|
-
const signature = await pipe(await createDefaultTransaction(client, payer, 200_000), tx => appendTransactionMessageInstructions(instructions, tx), tx => signAndSendTransaction(client, tx, commitment));
|
|
116
|
-
return signature;
|
|
117
|
-
}
|
|
118
|
-
catch (error) {
|
|
119
|
-
console.error(safeStringify(error));
|
|
120
|
-
throw new Error(`Failed to ${description.toLowerCase()}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
async function initializeToken({ client, mintAuthority, payer, owner, mint, dropAmount, decimals, otherAtaWallets, }) {
|
|
124
|
-
// Get Owner ATA
|
|
125
|
-
const [ata] = await findAssociatedTokenPda({
|
|
126
|
-
mint: mint.address,
|
|
127
|
-
owner: owner.address,
|
|
128
|
-
tokenProgram: TOKEN_PROGRAM_ADDRESS,
|
|
129
|
-
});
|
|
130
|
-
// Get Mint size & rent
|
|
131
|
-
const mintSpace = BigInt(getMintSize());
|
|
132
|
-
const mintRent = await client.rpc.getMinimumBalanceForRentExemption(mintSpace).send();
|
|
133
|
-
// Create instructions for new token mint
|
|
134
|
-
const baseInstructions = [
|
|
135
|
-
// Create the Mint Account
|
|
136
|
-
getCreateAccountInstruction({
|
|
137
|
-
lamports: mintRent,
|
|
138
|
-
newAccount: mint,
|
|
139
|
-
payer,
|
|
140
|
-
programAddress: TOKEN_PROGRAM_ADDRESS,
|
|
141
|
-
space: mintSpace,
|
|
142
|
-
}),
|
|
143
|
-
// Initialize the Mint
|
|
144
|
-
getInitializeMintInstruction({
|
|
145
|
-
decimals,
|
|
146
|
-
mint: mint.address,
|
|
147
|
-
mintAuthority: mintAuthority.address,
|
|
148
|
-
}),
|
|
149
|
-
// Create Associated Token Account
|
|
150
|
-
await getCreateAssociatedTokenIdempotentInstructionAsync({
|
|
151
|
-
mint: mint.address,
|
|
152
|
-
owner: owner.address,
|
|
153
|
-
payer,
|
|
154
|
-
}),
|
|
155
|
-
// Mint To the Destination Associated Token Account
|
|
156
|
-
getMintToInstruction({
|
|
157
|
-
amount: BigInt(dropAmount * 10 ** decimals),
|
|
158
|
-
mint: mint.address,
|
|
159
|
-
mintAuthority,
|
|
160
|
-
token: ata,
|
|
161
|
-
}),
|
|
162
|
-
];
|
|
163
|
-
// Generate Create ATA instructions for other token accounts we wish to add
|
|
164
|
-
const otherAtaInstructions = otherAtaWallets
|
|
165
|
-
? await Promise.all(otherAtaWallets.map(async (wallet) => await getCreateAssociatedTokenIdempotentInstructionAsync({
|
|
166
|
-
mint: mint.address,
|
|
167
|
-
owner: wallet,
|
|
168
|
-
payer,
|
|
169
|
-
})))
|
|
170
|
-
: [];
|
|
171
|
-
const alreadyExists = await mintExists(client, mint.address);
|
|
172
|
-
const instructions = alreadyExists ? [...otherAtaInstructions] : [...baseInstructions, ...otherAtaInstructions];
|
|
173
|
-
await sendAndConfirmInstructions(client, payer, instructions, 'Initialize token and ATAs', 'finalized');
|
|
174
|
-
}
|
|
175
83
|
async function setupTestSuite() {
|
|
176
|
-
const { koraAddress, koraRpcUrl, tokenDecimals, tokenDropAmount, solDropAmount
|
|
177
|
-
// Load auth config from environment if not provided
|
|
84
|
+
const { koraAddress, koraRpcUrl, tokenDecimals, tokenDropAmount, solDropAmount } = loadEnvironmentVariables();
|
|
178
85
|
const authConfig = process.env.ENABLE_AUTH === 'true'
|
|
179
86
|
? {
|
|
180
87
|
apiKey: process.env.KORA_API_KEY || 'test-api-key-123',
|
|
181
88
|
hmacSecret: process.env.KORA_HMAC_SECRET || 'test-hmac-secret-456',
|
|
182
89
|
}
|
|
183
90
|
: undefined;
|
|
184
|
-
// Create Solana client
|
|
185
|
-
const rpc = createSolanaRpc(solanaRpcUrl);
|
|
186
|
-
const rpcSubscriptions = createSolanaRpcSubscriptions(solanaWsUrl);
|
|
187
|
-
const airdrop = airdropFactory({ rpc, rpcSubscriptions });
|
|
188
|
-
const client = { rpc, rpcSubscriptions };
|
|
189
|
-
// Get or create keypairs
|
|
190
91
|
const { testWallet, usdcMint, destinationAddress } = await createKeyPairSigners();
|
|
191
|
-
const
|
|
192
|
-
// Airdrop SOL
|
|
193
|
-
await
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
92
|
+
const client = await createClient({ payer: testWallet }).use(tokenProgram()).use(associatedTokenProgram());
|
|
93
|
+
// Airdrop SOL via LiteSVM
|
|
94
|
+
await client.airdrop(koraAddress, lamports(solDropAmount));
|
|
95
|
+
await client.airdrop(testWallet.address, lamports(solDropAmount));
|
|
96
|
+
// Create mint
|
|
97
|
+
await client.token.instructions
|
|
98
|
+
.createMint({
|
|
99
|
+
newMint: usdcMint,
|
|
100
|
+
decimals: tokenDecimals,
|
|
101
|
+
mintAuthority: testWallet.address,
|
|
102
|
+
})
|
|
103
|
+
.sendTransaction();
|
|
104
|
+
// Mint tokens to testWallet's ATA (auto-creates ATA)
|
|
105
|
+
await client.token.instructions
|
|
106
|
+
.mintToATA({
|
|
107
|
+
mint: usdcMint.address,
|
|
108
|
+
owner: testWallet.address,
|
|
109
|
+
mintAuthority: testWallet,
|
|
110
|
+
amount: BigInt(tokenDropAmount * 10 ** tokenDecimals),
|
|
208
111
|
decimals: tokenDecimals,
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
112
|
+
})
|
|
113
|
+
.sendTransaction();
|
|
114
|
+
// Create ATAs for kora and destination wallets
|
|
115
|
+
for (const owner of [koraAddress, destinationAddress]) {
|
|
116
|
+
await client.associatedToken.instructions
|
|
117
|
+
.createAssociatedTokenIdempotent({
|
|
118
|
+
owner,
|
|
119
|
+
mint: usdcMint.address,
|
|
120
|
+
})
|
|
121
|
+
.sendTransaction();
|
|
122
|
+
}
|
|
216
123
|
return {
|
|
217
124
|
destinationAddress,
|
|
218
125
|
koraAddress,
|
|
@@ -222,13 +129,4 @@ async function setupTestSuite() {
|
|
|
222
129
|
usdcMint: usdcMint.address,
|
|
223
130
|
};
|
|
224
131
|
}
|
|
225
|
-
const mintExists = async (client, mint) => {
|
|
226
|
-
try {
|
|
227
|
-
const mintAccount = await client.rpc.getAccountInfo(mint).send();
|
|
228
|
-
return mintAccount.value !== null;
|
|
229
|
-
}
|
|
230
|
-
catch {
|
|
231
|
-
return false;
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
132
|
export default setupTestSuite;
|
package/dist/test/unit.test.js
CHANGED
|
@@ -509,28 +509,112 @@ describe('KoraClient Unit Tests', () => {
|
|
|
509
509
|
await expect(client.getConfig()).rejects.toThrow('RPC Error undefined: undefined');
|
|
510
510
|
});
|
|
511
511
|
});
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
512
|
+
describe('reCAPTCHA Authentication', () => {
|
|
513
|
+
it('should include x-recaptcha-token header when getRecaptchaToken callback is provided (sync)', async () => {
|
|
514
|
+
const recaptchaClient = new KoraClient({
|
|
515
|
+
getRecaptchaToken: () => 'test-recaptcha-token',
|
|
516
|
+
rpcUrl: mockRpcUrl,
|
|
517
|
+
});
|
|
518
|
+
mockSuccessfulResponse({ version: '1.0.0' });
|
|
519
|
+
await recaptchaClient.getVersion();
|
|
520
|
+
expect(mockFetch).toHaveBeenCalledWith(mockRpcUrl, {
|
|
521
|
+
body: JSON.stringify({
|
|
522
|
+
id: 1,
|
|
523
|
+
jsonrpc: '2.0',
|
|
524
|
+
method: 'getVersion',
|
|
525
|
+
params: undefined,
|
|
526
|
+
}),
|
|
527
|
+
headers: {
|
|
528
|
+
'Content-Type': 'application/json',
|
|
529
|
+
'x-recaptcha-token': 'test-recaptcha-token',
|
|
530
|
+
},
|
|
531
|
+
method: 'POST',
|
|
532
|
+
});
|
|
533
|
+
});
|
|
534
|
+
it('should include x-recaptcha-token header when getRecaptchaToken callback returns Promise', async () => {
|
|
535
|
+
const recaptchaClient = new KoraClient({
|
|
536
|
+
getRecaptchaToken: () => Promise.resolve('async-recaptcha-token'),
|
|
537
|
+
rpcUrl: mockRpcUrl,
|
|
538
|
+
});
|
|
539
|
+
mockSuccessfulResponse({ version: '1.0.0' });
|
|
540
|
+
await recaptchaClient.getVersion();
|
|
541
|
+
expect(mockFetch).toHaveBeenCalledWith(mockRpcUrl, {
|
|
542
|
+
body: JSON.stringify({
|
|
543
|
+
id: 1,
|
|
544
|
+
jsonrpc: '2.0',
|
|
545
|
+
method: 'getVersion',
|
|
546
|
+
params: undefined,
|
|
547
|
+
}),
|
|
548
|
+
headers: {
|
|
549
|
+
'Content-Type': 'application/json',
|
|
550
|
+
'x-recaptcha-token': 'async-recaptcha-token',
|
|
551
|
+
},
|
|
552
|
+
method: 'POST',
|
|
553
|
+
});
|
|
554
|
+
});
|
|
555
|
+
it('should NOT include x-recaptcha-token header when getRecaptchaToken is not provided', async () => {
|
|
556
|
+
mockSuccessfulResponse({ version: '1.0.0' });
|
|
557
|
+
await client.getVersion();
|
|
558
|
+
expect(mockFetch).toHaveBeenCalledWith(mockRpcUrl, {
|
|
559
|
+
body: JSON.stringify({
|
|
560
|
+
id: 1,
|
|
561
|
+
jsonrpc: '2.0',
|
|
562
|
+
method: 'getVersion',
|
|
563
|
+
params: undefined,
|
|
564
|
+
}),
|
|
565
|
+
headers: {
|
|
566
|
+
'Content-Type': 'application/json',
|
|
567
|
+
},
|
|
568
|
+
method: 'POST',
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
it('should include x-recaptcha-token along with other auth headers', async () => {
|
|
572
|
+
const combinedAuthClient = new KoraClient({
|
|
573
|
+
apiKey: 'test-api-key',
|
|
574
|
+
getRecaptchaToken: () => 'test-recaptcha-token',
|
|
575
|
+
rpcUrl: mockRpcUrl,
|
|
576
|
+
});
|
|
577
|
+
mockSuccessfulResponse({ version: '1.0.0' });
|
|
578
|
+
await combinedAuthClient.getVersion();
|
|
579
|
+
const callArgs = mockFetch.mock.calls[0][1];
|
|
580
|
+
expect(callArgs.headers).toMatchObject({
|
|
581
|
+
'Content-Type': 'application/json',
|
|
582
|
+
'x-api-key': 'test-api-key',
|
|
583
|
+
'x-recaptcha-token': 'test-recaptcha-token',
|
|
584
|
+
});
|
|
585
|
+
});
|
|
586
|
+
it('should call getRecaptchaToken callback for each request', async () => {
|
|
587
|
+
let callCount = 0;
|
|
588
|
+
const recaptchaClient = new KoraClient({
|
|
589
|
+
getRecaptchaToken: () => `token-${++callCount}`,
|
|
590
|
+
rpcUrl: mockRpcUrl,
|
|
591
|
+
});
|
|
592
|
+
mockSuccessfulResponse({ version: '1.0.0' });
|
|
593
|
+
await recaptchaClient.getVersion();
|
|
594
|
+
mockSuccessfulResponse({ blockhash: 'test-blockhash' });
|
|
595
|
+
await recaptchaClient.getBlockhash();
|
|
596
|
+
expect(callCount).toBe(2);
|
|
597
|
+
const calls = mockFetch.mock.calls;
|
|
598
|
+
expect(calls[0][1].headers['x-recaptcha-token']).toBe('token-1');
|
|
599
|
+
expect(calls[1][1].headers['x-recaptcha-token']).toBe('token-2');
|
|
600
|
+
});
|
|
601
|
+
it('should propagate errors when getRecaptchaToken callback throws', async () => {
|
|
602
|
+
const recaptchaClient = new KoraClient({
|
|
603
|
+
getRecaptchaToken: () => {
|
|
604
|
+
throw new Error('reCAPTCHA failed to load');
|
|
605
|
+
},
|
|
606
|
+
rpcUrl: mockRpcUrl,
|
|
607
|
+
});
|
|
608
|
+
await expect(recaptchaClient.getVersion()).rejects.toThrow('reCAPTCHA failed to load');
|
|
609
|
+
});
|
|
610
|
+
it('should propagate errors when getRecaptchaToken returns rejected Promise', async () => {
|
|
611
|
+
const recaptchaClient = new KoraClient({
|
|
612
|
+
getRecaptchaToken: () => Promise.reject(new Error('Token generation failed')),
|
|
613
|
+
rpcUrl: mockRpcUrl,
|
|
614
|
+
});
|
|
615
|
+
await expect(recaptchaClient.getVersion()).rejects.toThrow('Token generation failed');
|
|
616
|
+
});
|
|
617
|
+
});
|
|
534
618
|
});
|
|
535
619
|
describe('Transaction Utils', () => {
|
|
536
620
|
describe('getInstructionsFromBase64Message', () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/kora",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.6",
|
|
4
4
|
"description": "TypeScript SDK for Kora RPC",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -16,31 +16,42 @@
|
|
|
16
16
|
],
|
|
17
17
|
"author": "",
|
|
18
18
|
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/solana-foundation/kora",
|
|
22
|
+
"directory": "sdks/ts"
|
|
23
|
+
},
|
|
19
24
|
"peerDependencies": {
|
|
20
|
-
"@solana-program/
|
|
21
|
-
"@solana/
|
|
25
|
+
"@solana-program/compute-budget": "^0.15.0",
|
|
26
|
+
"@solana-program/token": "^0.12.0",
|
|
27
|
+
"@solana/kit": "^6.3.0",
|
|
28
|
+
"@solana/kit-plugin-instruction-plan": "^0.7.0",
|
|
29
|
+
"@solana/kit-plugin-payer": "^0.6.0",
|
|
30
|
+
"@solana/kit-plugin-rpc": "^0.7.0"
|
|
22
31
|
},
|
|
23
32
|
"devDependencies": {
|
|
24
|
-
"@
|
|
25
|
-
"@solana-program/system": "^0.
|
|
26
|
-
"@solana-
|
|
27
|
-
"@solana/
|
|
28
|
-
"@solana/kit": "^5.4.0",
|
|
33
|
+
"@eslint/js": "^9.39.3",
|
|
34
|
+
"@solana-program/system": "^0.12.0",
|
|
35
|
+
"@solana/eslint-config-solana": "6.0.0",
|
|
36
|
+
"@solana/kit-client-litesvm": "^0.7.0",
|
|
29
37
|
"@solana/prettier-config-solana": "^0.0.6",
|
|
30
38
|
"@types/jest": "^29.5.12",
|
|
31
39
|
"@types/node": "^20.17.27",
|
|
32
|
-
"@typescript-eslint/eslint-plugin": "^8.38.0",
|
|
33
|
-
"@typescript-eslint/parser": "^8.38.0",
|
|
34
40
|
"dotenv": "^16.4.5",
|
|
35
|
-
"eslint": "^9.
|
|
41
|
+
"eslint": "^9.39.3",
|
|
42
|
+
"eslint-plugin-jest": "^29.15.0",
|
|
43
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
44
|
+
"eslint-plugin-sort-keys-fix": "^1.1.2",
|
|
45
|
+
"eslint-plugin-typescript-sort-keys": "^3.3.0",
|
|
46
|
+
"globals": "^16.5.0",
|
|
36
47
|
"jest": "^29.7.0",
|
|
37
48
|
"prettier": "^3.2.5",
|
|
38
49
|
"ts-jest": "^29.1.2",
|
|
39
50
|
"ts-node": "^10.9.2",
|
|
40
51
|
"typedoc": "^0.28.9",
|
|
41
52
|
"typedoc-plugin-markdown": "^4.8.0",
|
|
42
|
-
"typescript": "^5.
|
|
43
|
-
"
|
|
53
|
+
"typescript": "^5.9.3",
|
|
54
|
+
"typescript-eslint": "^8.56.1"
|
|
44
55
|
},
|
|
45
56
|
"scripts": {
|
|
46
57
|
"build": "tsc",
|
|
@@ -50,13 +61,12 @@
|
|
|
50
61
|
"test:coverage": "jest --coverage",
|
|
51
62
|
"test:integration": "pnpm test integration.test.ts",
|
|
52
63
|
"test:integration:auth": "ENABLE_AUTH=true pnpm test integration.test.ts",
|
|
64
|
+
"test:integration:free": "FREE_PRICING=true pnpm test integration.test.ts",
|
|
53
65
|
"test:integration:privy": "KORA_SIGNER_TYPE=privy pnpm test integration.test.ts",
|
|
54
66
|
"test:integration:turnkey": "KORA_SIGNER_TYPE=turnkey pnpm test integration.test.ts",
|
|
55
67
|
"test:unit": "pnpm test unit.test.ts",
|
|
56
|
-
"test:ci:integration": "node scripts/test-with-validator.js",
|
|
57
|
-
"test:ci:integration:auth": "ENABLE_AUTH=true node scripts/test-with-validator.js",
|
|
58
68
|
"test:ci:unit": "jest test/unit.test.ts",
|
|
59
|
-
"lint": "eslint src
|
|
69
|
+
"lint": "eslint src/",
|
|
60
70
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
61
71
|
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
62
72
|
"type-check": "tsc --noEmit",
|