@solana/kora 0.2.0-beta.4 → 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.
@@ -1,5 +1,5 @@
1
1
  import { createEmptyClient } from '@solana/kit';
2
- import { koraPlugin } from '../src/plugin.js';
2
+ import { koraPlugin } from '../src/kit/plugin.js';
3
3
  // Mock fetch globally
4
4
  const mockFetch = jest.fn();
5
5
  global.fetch = mockFetch;
@@ -12,8 +12,8 @@ describe('Kora Kit Plugin', () => {
12
12
  const mockSuccessfulResponse = (result) => {
13
13
  mockFetch.mockResolvedValueOnce({
14
14
  json: jest.fn().mockResolvedValueOnce({
15
- id: 1,
16
15
  jsonrpc: '2.0',
16
+ id: 1,
17
17
  result,
18
18
  }),
19
19
  });
@@ -22,9 +22,9 @@ describe('Kora Kit Plugin', () => {
22
22
  const mockErrorResponse = (error) => {
23
23
  mockFetch.mockResolvedValueOnce({
24
24
  json: jest.fn().mockResolvedValueOnce({
25
- error,
26
- id: 1,
27
25
  jsonrpc: '2.0',
26
+ id: 1,
27
+ error,
28
28
  }),
29
29
  });
30
30
  };
@@ -41,14 +41,11 @@ describe('Kora Kit Plugin', () => {
41
41
  expect(typeof enhanced.kora.getConfig).toBe('function');
42
42
  expect(typeof enhanced.kora.getPayerSigner).toBe('function');
43
43
  expect(typeof enhanced.kora.getBlockhash).toBe('function');
44
- expect(typeof enhanced.kora.getVersion).toBe('function');
45
44
  expect(typeof enhanced.kora.getSupportedTokens).toBe('function');
46
45
  expect(typeof enhanced.kora.estimateTransactionFee).toBe('function');
47
- expect(typeof enhanced.kora.estimateBundleFee).toBe('function');
48
46
  expect(typeof enhanced.kora.signTransaction).toBe('function');
49
47
  expect(typeof enhanced.kora.signAndSendTransaction).toBe('function');
50
- expect(typeof enhanced.kora.signBundle).toBe('function');
51
- expect(typeof enhanced.kora.signAndSendBundle).toBe('function');
48
+ expect(typeof enhanced.kora.transferTransaction).toBe('function');
52
49
  expect(typeof enhanced.kora.getPaymentInstruction).toBe('function');
53
50
  });
54
51
  it('should work with empty client object', () => {
@@ -58,8 +55,8 @@ describe('Kora Kit Plugin', () => {
58
55
  });
59
56
  it('should support authentication options', () => {
60
57
  const authConfig = {
61
- apiKey: 'test-api-key',
62
58
  endpoint: mockEndpoint,
59
+ apiKey: 'test-api-key',
63
60
  hmacSecret: 'test-hmac-secret',
64
61
  };
65
62
  const plugin = koraPlugin(authConfig);
@@ -77,67 +74,67 @@ describe('Kora Kit Plugin', () => {
77
74
  describe('getConfig', () => {
78
75
  it('should return Kit-typed Address arrays', async () => {
79
76
  const rawResponse = {
80
- enabled_methods: {
81
- estimate_transaction_fee: true,
82
- get_blockhash: true,
83
- get_config: true,
84
- get_supported_tokens: true,
85
- liveness: true,
86
- sign_and_send_transaction: true,
87
- sign_transaction: true,
88
- transfer_transaction: true,
89
- },
90
77
  fee_payers: ['DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7'],
91
78
  validation_config: {
79
+ max_allowed_lamports: 1000000,
80
+ max_signatures: 10,
81
+ price_source: 'Jupiter',
92
82
  allowed_programs: ['11111111111111111111111111111111'],
93
- allowed_spl_paid_tokens: ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'],
94
83
  allowed_tokens: ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'],
84
+ allowed_spl_paid_tokens: ['EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'],
95
85
  disallowed_accounts: [],
96
86
  fee_payer_policy: {
97
- spl_token: {
98
- allow_approve: true,
99
- allow_burn: true,
100
- allow_close_account: true,
101
- allow_freeze_account: true,
102
- allow_mint_to: true,
103
- allow_revoke: true,
104
- allow_set_authority: true,
105
- allow_thaw_account: true,
106
- allow_transfer: true,
107
- },
108
87
  system: {
109
- allow_allocate: true,
88
+ allow_transfer: true,
110
89
  allow_assign: true,
111
90
  allow_create_account: true,
112
- allow_transfer: true,
91
+ allow_allocate: true,
113
92
  nonce: {
93
+ allow_initialize: true,
114
94
  allow_advance: true,
115
95
  allow_authorize: true,
116
- allow_initialize: true,
117
96
  allow_withdraw: true,
118
97
  },
119
98
  },
120
- token_2022: {
121
- allow_approve: true,
99
+ spl_token: {
100
+ allow_transfer: true,
122
101
  allow_burn: true,
123
102
  allow_close_account: true,
124
- allow_freeze_account: true,
125
- allow_mint_to: true,
103
+ allow_approve: true,
126
104
  allow_revoke: true,
127
105
  allow_set_authority: true,
106
+ allow_mint_to: true,
107
+ allow_freeze_account: true,
128
108
  allow_thaw_account: true,
109
+ },
110
+ token_2022: {
129
111
  allow_transfer: true,
112
+ allow_burn: true,
113
+ allow_close_account: true,
114
+ allow_approve: true,
115
+ allow_revoke: true,
116
+ allow_set_authority: true,
117
+ allow_mint_to: true,
118
+ allow_freeze_account: true,
119
+ allow_thaw_account: true,
130
120
  },
131
121
  },
132
- max_allowed_lamports: 1000000,
133
- max_signatures: 10,
134
- price: { margin: 0.1, type: 'margin' },
135
- price_source: 'Jupiter',
122
+ price: { type: 'margin', margin: 0.1 },
136
123
  token2022: {
137
- blocked_account_extensions: [],
138
124
  blocked_mint_extensions: [],
125
+ blocked_account_extensions: [],
139
126
  },
140
127
  },
128
+ enabled_methods: {
129
+ liveness: true,
130
+ estimate_transaction_fee: true,
131
+ get_supported_tokens: true,
132
+ sign_transaction: true,
133
+ sign_and_send_transaction: true,
134
+ transfer_transaction: true,
135
+ get_blockhash: true,
136
+ get_config: true,
137
+ },
141
138
  };
142
139
  mockSuccessfulResponse(rawResponse);
143
140
  const result = await kora.getConfig();
@@ -153,8 +150,8 @@ describe('Kora Kit Plugin', () => {
153
150
  describe('getPayerSigner', () => {
154
151
  it('should return Kit-typed Address fields', async () => {
155
152
  const rawResponse = {
156
- payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
157
153
  signer_address: 'DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
154
+ payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
158
155
  };
159
156
  mockSuccessfulResponse(rawResponse);
160
157
  const result = await kora.getPayerSigner();
@@ -177,16 +174,6 @@ describe('Kora Kit Plugin', () => {
177
174
  expect(hash).toBe('4NxM2D4kQcipkzMWBWQME5YSVnj5kT8QKA7rvb3rKLvE');
178
175
  });
179
176
  });
180
- describe('getVersion', () => {
181
- it('should return version string', async () => {
182
- const rawResponse = {
183
- version: '2.0.0',
184
- };
185
- mockSuccessfulResponse(rawResponse);
186
- const result = await kora.getVersion();
187
- expect(result.version).toBe('2.0.0');
188
- });
189
- });
190
177
  describe('getSupportedTokens', () => {
191
178
  it('should return Kit-typed Address array', async () => {
192
179
  const rawResponse = {
@@ -210,13 +197,13 @@ describe('Kora Kit Plugin', () => {
210
197
  const rawResponse = {
211
198
  fee_in_lamports: 5000,
212
199
  fee_in_token: 50,
213
- payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
214
200
  signer_pubkey: 'DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
201
+ payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
215
202
  };
216
203
  mockSuccessfulResponse(rawResponse);
217
204
  const result = await kora.estimateTransactionFee({
218
- fee_token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
219
205
  transaction: 'base64EncodedTransaction',
206
+ fee_token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
220
207
  });
221
208
  // Type assertions
222
209
  const signerPubkey = result.signer_pubkey;
@@ -227,28 +214,6 @@ describe('Kora Kit Plugin', () => {
227
214
  expect(paymentAddr).toBe('PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7');
228
215
  });
229
216
  });
230
- describe('estimateBundleFee', () => {
231
- it('should return Kit-typed Address fields for bundle', async () => {
232
- const rawResponse = {
233
- fee_in_lamports: 15000,
234
- fee_in_token: 150,
235
- payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
236
- signer_pubkey: 'DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
237
- };
238
- mockSuccessfulResponse(rawResponse);
239
- const result = await kora.estimateBundleFee({
240
- fee_token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
241
- transactions: ['base64Tx1', 'base64Tx2', 'base64Tx3'],
242
- });
243
- // Type assertions
244
- const signerPubkey = result.signer_pubkey;
245
- const paymentAddr = result.payment_address;
246
- expect(result.fee_in_lamports).toBe(15000);
247
- expect(result.fee_in_token).toBe(150);
248
- expect(signerPubkey).toBe('DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7');
249
- expect(paymentAddr).toBe('PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7');
250
- });
251
- });
252
217
  describe('signTransaction', () => {
253
218
  it('should return Kit-typed response with Base64EncodedWireTransaction', async () => {
254
219
  const rawResponse = {
@@ -267,11 +232,9 @@ describe('Kora Kit Plugin', () => {
267
232
  });
268
233
  });
269
234
  describe('signAndSendTransaction', () => {
270
- it('should return Kit-typed response with Signature and Base64EncodedWireTransaction', async () => {
271
- // Use a valid base58 signature (88 characters, valid base58 alphabet)
272
- const mockSignature = '5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW';
235
+ it('should return Kit-typed response with Base64EncodedWireTransaction', async () => {
273
236
  const rawResponse = {
274
- signature: mockSignature,
237
+ signature: '5wBzExmp8yR5M6m4KjV8WT9T6B1NMQkaMbsFWqBoDPBMYWxDx6EuSGxNqKfXnBhDhAkEqMiGRjEwKnGhSN3pi3n',
275
238
  signed_transaction: 'base64SignedTransaction',
276
239
  signer_pubkey: 'DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
277
240
  };
@@ -280,52 +243,37 @@ describe('Kora Kit Plugin', () => {
280
243
  transaction: 'base64EncodedTransaction',
281
244
  });
282
245
  // Type assertions - verify Kit types
283
- const sig = result.signature;
284
246
  const signedTx = result.signed_transaction;
285
247
  const signerPubkey = result.signer_pubkey;
286
- expect(sig).toBe(mockSignature);
287
248
  expect(signedTx).toBe('base64SignedTransaction');
288
249
  expect(signerPubkey).toBe('DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7');
289
250
  });
290
251
  });
291
- describe('signBundle', () => {
292
- it('should return Kit-typed response with Base64EncodedWireTransaction array', async () => {
293
- const rawResponse = {
294
- signed_transactions: ['base64SignedTx1', 'base64SignedTx2'],
295
- signer_pubkey: 'DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
296
- };
297
- mockSuccessfulResponse(rawResponse);
298
- const result = await kora.signBundle({
299
- transactions: ['base64Tx1', 'base64Tx2'],
300
- });
301
- // Type assertions - verify Kit types
302
- const signedTxs = result.signed_transactions;
303
- const signerPubkey = result.signer_pubkey;
304
- expect(signedTxs).toHaveLength(2);
305
- expect(signedTxs[0]).toBe('base64SignedTx1');
306
- expect(signedTxs[1]).toBe('base64SignedTx2');
307
- expect(signerPubkey).toBe('DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7');
308
- });
309
- });
310
- describe('signAndSendBundle', () => {
311
- it('should return Kit-typed response with Base64EncodedWireTransaction array and bundle UUID', async () => {
252
+ describe('transferTransaction', () => {
253
+ it('should return Kit-typed response with Base64EncodedWireTransaction and Blockhash', async () => {
312
254
  const rawResponse = {
313
- bundle_uuid: 'jito-bundle-uuid-12345',
314
- signed_transactions: ['base64SignedTx1', 'base64SignedTx2'],
255
+ transaction: 'base64Transaction',
256
+ message: 'base64Message',
257
+ blockhash: '4NxM2D4kQcipkzMWBWQME5YSVnj5kT8QKA7rvb3rKLvE',
315
258
  signer_pubkey: 'DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
259
+ instructions: [],
316
260
  };
317
261
  mockSuccessfulResponse(rawResponse);
318
- const result = await kora.signAndSendBundle({
319
- transactions: ['base64Tx1', 'base64Tx2'],
262
+ const result = await kora.transferTransaction({
263
+ amount: 1000000,
264
+ token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
265
+ source: 'sourceWallet',
266
+ destination: 'destWallet',
320
267
  });
321
268
  // Type assertions - verify Kit types
322
- const signedTxs = result.signed_transactions;
269
+ const tx = result.transaction;
270
+ const hash = result.blockhash;
323
271
  const signerPubkey = result.signer_pubkey;
324
- expect(signedTxs).toHaveLength(2);
325
- expect(signedTxs[0]).toBe('base64SignedTx1');
326
- expect(signedTxs[1]).toBe('base64SignedTx2');
272
+ expect(tx).toBe('base64Transaction');
273
+ expect(result.message).toBe('base64Message');
274
+ expect(hash).toBe('4NxM2D4kQcipkzMWBWQME5YSVnj5kT8QKA7rvb3rKLvE');
327
275
  expect(signerPubkey).toBe('DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7');
328
- expect(result.bundle_uuid).toBe('jito-bundle-uuid-12345');
276
+ expect(result.instructions).toEqual([]);
329
277
  });
330
278
  });
331
279
  describe('getPaymentInstruction', () => {
@@ -333,16 +281,16 @@ describe('Kora Kit Plugin', () => {
333
281
  const mockFeeEstimate = {
334
282
  fee_in_lamports: 5000,
335
283
  fee_in_token: 50000,
336
- payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
337
284
  signer_pubkey: 'DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
285
+ payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
338
286
  };
339
287
  const testTx = 'Aoq7ymA5OGP+gmDXiY5m3cYXlY2Rz/a/gFjOgt9ZuoCS7UzuiGGaEnW2OOtvHvMQHkkD7Z4LRF5B63ftu+1oZwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgECB1urjQEjgFgzqYhJ8IXJeSg4cJP1j1g2CJstOQTDchOKUzqH3PxgGW3c4V3vZV05A5Y30/MggOBs0Kd00s1JEwg5TaEeaV4+KL2y7fXIAuf6cN0ZQitbhY+G9ExtBSChspOXPgNcy9pYpETe4bmB+fg4bfZx1tnicA/kIyyubczAmbcIKIuniNOOQYG2ggKCz8NjEsHVezrWMatndu1wk6J5miGP26J6Vwp31AljiAajAFuP0D9mWJwSeFuA7J5rPwbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpd/O36SW02zRtNtqk6GFeip2+yBQsVTeSbLL4rWJRkd4CBgQCBQQBCgxAQg8AAAAAAAYGBAIFAwEKDBAnAAAAAAAABg==';
340
288
  mockSuccessfulResponse(mockFeeEstimate);
341
289
  const result = await kora.getPaymentInstruction({
290
+ transaction: testTx,
342
291
  fee_token: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',
343
292
  source_wallet: '11111111111111111111111111111111',
344
293
  token_program_id: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
345
- transaction: testTx,
346
294
  });
347
295
  // Type assertions - verify Kit types
348
296
  const originalTx = result.original_transaction;
@@ -373,12 +321,12 @@ describe('Kora Kit Plugin', () => {
373
321
  await expect(kora.getConfig()).rejects.toThrow('Network error');
374
322
  });
375
323
  });
376
- describe('KoraApi Type Export', () => {
377
- it('should export KoraApi type correctly', () => {
378
- // This test verifies the KoraApi type is correctly exported
324
+ describe('KoraPlugin Type Export', () => {
325
+ it('should export KoraPlugin type correctly', () => {
326
+ // This test verifies the KoraPlugin type is correctly exported
379
327
  const plugin = koraPlugin(mockConfig);
380
328
  const client = plugin({});
381
- // Type check - assign to KoraApi type
329
+ // Type check - assign to KoraPlugin type
382
330
  const api = client.kora;
383
331
  expect(api).toBeDefined();
384
332
  });
@@ -394,20 +342,17 @@ describe('Kora Kit Plugin', () => {
394
342
  expect(typeof client.kora.getConfig).toBe('function');
395
343
  expect(typeof client.kora.getPayerSigner).toBe('function');
396
344
  expect(typeof client.kora.getBlockhash).toBe('function');
397
- expect(typeof client.kora.getVersion).toBe('function');
398
345
  expect(typeof client.kora.getSupportedTokens).toBe('function');
399
346
  expect(typeof client.kora.estimateTransactionFee).toBe('function');
400
- expect(typeof client.kora.estimateBundleFee).toBe('function');
401
347
  expect(typeof client.kora.signTransaction).toBe('function');
402
348
  expect(typeof client.kora.signAndSendTransaction).toBe('function');
403
- expect(typeof client.kora.signBundle).toBe('function');
404
- expect(typeof client.kora.signAndSendBundle).toBe('function');
349
+ expect(typeof client.kora.transferTransaction).toBe('function');
405
350
  expect(typeof client.kora.getPaymentInstruction).toBe('function');
406
351
  });
407
352
  it('should work with authentication config', () => {
408
353
  const authConfig = {
409
- apiKey: 'test-api-key',
410
354
  endpoint: mockEndpoint,
355
+ apiKey: 'test-api-key',
411
356
  hmacSecret: 'test-hmac-secret',
412
357
  };
413
358
  const client = createEmptyClient().use(koraPlugin(authConfig));
@@ -429,8 +374,8 @@ describe('Kora Kit Plugin', () => {
429
374
  });
430
375
  it('should call RPC methods correctly', async () => {
431
376
  const mockResponse = {
432
- payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
433
377
  signer_address: 'DemoKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
378
+ payment_address: 'PayKMZWkk483QoFPLRPQ2XVKB7bWnuXwSjvDE1JsWk7',
434
379
  };
435
380
  mockSuccessfulResponse(mockResponse);
436
381
  const client = createEmptyClient().use(koraPlugin(mockConfig));
@@ -1,26 +1,30 @@
1
- import { Address, Commitment, KeyPairSigner } from '@solana/kit';
1
+ import { Commitment, KeyPairSigner, Address } from '@solana/kit';
2
2
  import { KoraClient } from '../src/index.js';
3
3
  interface TestSuite {
4
- destinationAddress: Address<string>;
5
- koraAddress: Address<string>;
6
4
  koraClient: KoraClient;
7
5
  koraRpcUrl: string;
8
6
  testWallet: KeyPairSigner<string>;
9
7
  usdcMint: Address<string>;
10
- }
11
- export declare function loadEnvironmentVariables(): {
12
- commitment: Commitment;
13
8
  destinationAddress: Address<string>;
14
9
  koraAddress: Address<string>;
10
+ authConfig?: {
11
+ apiKey: string;
12
+ hmacSecret: string;
13
+ };
14
+ }
15
+ export declare function loadEnvironmentVariables(): {
15
16
  koraRpcUrl: string;
17
+ koraAddress: Address<string>;
16
18
  koraSignerType: string;
19
+ commitment: Commitment;
20
+ tokenDecimals: number;
21
+ tokenDropAmount: number;
17
22
  solDropAmount: bigint;
18
23
  solanaRpcUrl: string;
19
24
  solanaWsUrl: string;
20
- testUsdcMintSecret: string;
21
25
  testWalletSecret: string;
22
- tokenDecimals: number;
23
- tokenDropAmount: number;
26
+ testUsdcMintSecret: string;
27
+ destinationAddress: Address<string>;
24
28
  };
25
29
  declare function setupTestSuite(): Promise<TestSuite>;
26
30
  export default setupTestSuite;
@@ -1,28 +1,25 @@
1
- import { airdropFactory, appendTransactionMessageInstructions, assertIsAddress, assertIsSendableTransaction, assertIsTransactionWithBlockhashLifetime, createKeyPairSignerFromBytes, createSolanaRpc, createSolanaRpcSubscriptions, createTransactionMessage, getBase58Encoder, getSignatureFromTransaction, lamports, pipe, sendAndConfirmTransactionFactory, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, signTransactionMessageWithSigners, } from '@solana/kit';
2
- import { MAX_COMPUTE_UNIT_LIMIT, updateOrAppendSetComputeUnitLimitInstruction, updateOrAppendSetComputeUnitPriceInstruction, } from '@solana-program/compute-budget';
3
1
  import { getCreateAccountInstruction } from '@solana-program/system';
4
2
  import { findAssociatedTokenPda, getCreateAssociatedTokenIdempotentInstructionAsync, getInitializeMintInstruction, getMintSize, getMintToInstruction, TOKEN_PROGRAM_ADDRESS, } from '@solana-program/token';
3
+ import { airdropFactory, createSolanaRpc, createSolanaRpcSubscriptions, lamports, sendAndConfirmTransactionFactory, pipe, createTransactionMessage, setTransactionMessageLifetimeUsingBlockhash, setTransactionMessageFeePayerSigner, appendTransactionMessageInstructions, signTransactionMessageWithSigners, getSignatureFromTransaction, assertIsAddress, createKeyPairSignerFromBytes, getBase58Encoder, assertIsSendableTransaction, assertIsTransactionWithBlockhashLifetime, } from '@solana/kit';
4
+ import { updateOrAppendSetComputeUnitLimitInstruction, updateOrAppendSetComputeUnitPriceInstruction, MAX_COMPUTE_UNIT_LIMIT, } from '@solana-program/compute-budget';
5
5
  import { config } from 'dotenv';
6
6
  import path from 'path';
7
7
  import { KoraClient } from '../src/index.js';
8
8
  config({ path: path.resolve(process.cwd(), '.env') });
9
9
  const DEFAULTS = {
10
- COMMITMENT: 'processed',
11
10
  DECIMALS: 6,
12
- // Make sure this matches the USDC mint in kora.toml (9BgeTKqmFsPVnfYscfM6NvsgmZxei7XfdciShQ6D3bxJ)
13
- DESTINATION_ADDRESS: 'AVmDft8deQEo78bRKcGN5ZMf3hyjeLBK4Rd4xGB46yQM',
14
- // DO NOT USE THESE KEYPAIRS IN PRODUCTION, TESTING KEYPAIRS ONLY
15
- KORA_ADDRESS: '7AqpcUvgJ7Kh1VmJZ44rWp2XDow33vswo9VK9VqpPU2d',
11
+ TOKEN_DROP_AMOUNT: 100_000,
16
12
  KORA_RPC_URL: 'http://localhost:8080/',
17
- KORA_SIGNER_TYPE: 'memory',
18
- // Make sure this matches the kora-rpc signer address on launch (root .env)
19
- SENDER_SECRET: 'tzgfgSWTE3KUA6qfRoFYLaSfJm59uUeZRDy4ybMrLn1JV2drA1mftiaEcVFvq1Lok6h6EX2C4Y9kSKLvQWyMpS5',
20
13
  SOLANA_RPC_URL: 'http://127.0.0.1:8899',
21
14
  SOLANA_WS_URL: 'ws://127.0.0.1:8900',
15
+ COMMITMENT: 'processed',
22
16
  SOL_DROP_AMOUNT: 1_000_000_000,
23
- // HhA5j2rRiPbMrpF2ZD36r69FyZf3zWmEHRNSZbbNdVjf
24
- TEST_USDC_MINT_SECRET: '59kKmXphL5UJANqpFFjtH17emEq3oRNmYsx6a3P3vSGJRmhMgVdzH77bkNEi9bArRViT45e8L2TsuPxKNFoc3Qfg',
25
- TOKEN_DROP_AMOUNT: 100_000, // Default signer type
17
+ // DO NOT USE THESE KEYPAIRS IN PRODUCTION, TESTING KEYPAIRS ONLY
18
+ KORA_ADDRESS: '7AqpcUvgJ7Kh1VmJZ44rWp2XDow33vswo9VK9VqpPU2d', // Make sure this matches the kora-rpc signer address on launch (root .env)
19
+ SENDER_SECRET: 'tzgfgSWTE3KUA6qfRoFYLaSfJm59uUeZRDy4ybMrLn1JV2drA1mftiaEcVFvq1Lok6h6EX2C4Y9kSKLvQWyMpS5', // HhA5j2rRiPbMrpF2ZD36r69FyZf3zWmEHRNSZbbNdVjf
20
+ TEST_USDC_MINT_SECRET: '59kKmXphL5UJANqpFFjtH17emEq3oRNmYsx6a3P3vSGJRmhMgVdzH77bkNEi9bArRViT45e8L2TsuPxKNFoc3Qfg', // Make sure this matches the USDC mint in kora.toml (9BgeTKqmFsPVnfYscfM6NvsgmZxei7XfdciShQ6D3bxJ)
21
+ DESTINATION_ADDRESS: 'AVmDft8deQEo78bRKcGN5ZMf3hyjeLBK4Rd4xGB46yQM',
22
+ KORA_SIGNER_TYPE: 'memory', // Default signer type
26
23
  };
27
24
  const createKeyPairSignerFromB58Secret = async (b58Secret) => {
28
25
  const base58Encoder = getBase58Encoder();
@@ -66,18 +63,18 @@ export function loadEnvironmentVariables() {
66
63
  assertIsAddress(destinationAddress);
67
64
  assertIsAddress(koraAddress);
68
65
  return {
69
- commitment,
70
- destinationAddress,
71
- koraAddress,
72
66
  koraRpcUrl,
67
+ koraAddress,
73
68
  koraSignerType,
69
+ commitment,
70
+ tokenDecimals,
71
+ tokenDropAmount,
74
72
  solDropAmount,
75
73
  solanaRpcUrl,
76
74
  solanaWsUrl,
77
- testUsdcMintSecret,
78
75
  testWalletSecret,
79
- tokenDecimals,
80
- tokenDropAmount,
76
+ testUsdcMintSecret,
77
+ destinationAddress,
81
78
  };
82
79
  }
83
80
  async function createKeyPairSigners() {
@@ -85,9 +82,9 @@ async function createKeyPairSigners() {
85
82
  const testWallet = await createKeyPairSignerFromB58Secret(testWalletSecret);
86
83
  const usdcMint = await createKeyPairSignerFromB58Secret(testUsdcMintSecret);
87
84
  return {
88
- destinationAddress,
89
85
  testWallet,
90
86
  usdcMint,
87
+ destinationAddress,
91
88
  };
92
89
  }
93
90
  const createDefaultTransaction = async (client, feePayer, computeLimit = MAX_COMPUTE_UNIT_LIMIT, feeMicroLamports = 1n) => {
@@ -134,46 +131,46 @@ async function initializeToken({ client, mintAuthority, payer, owner, mint, drop
134
131
  const baseInstructions = [
135
132
  // Create the Mint Account
136
133
  getCreateAccountInstruction({
137
- lamports: mintRent,
138
- newAccount: mint,
139
134
  payer,
140
- programAddress: TOKEN_PROGRAM_ADDRESS,
135
+ newAccount: mint,
136
+ lamports: mintRent,
141
137
  space: mintSpace,
138
+ programAddress: TOKEN_PROGRAM_ADDRESS,
142
139
  }),
143
140
  // Initialize the Mint
144
141
  getInitializeMintInstruction({
145
- decimals,
146
142
  mint: mint.address,
143
+ decimals,
147
144
  mintAuthority: mintAuthority.address,
148
145
  }),
149
146
  // Create Associated Token Account
150
147
  await getCreateAssociatedTokenIdempotentInstructionAsync({
151
148
  mint: mint.address,
152
- owner: owner.address,
153
149
  payer,
150
+ owner: owner.address,
154
151
  }),
155
152
  // Mint To the Destination Associated Token Account
156
153
  getMintToInstruction({
157
- amount: BigInt(dropAmount * 10 ** decimals),
158
154
  mint: mint.address,
159
- mintAuthority,
160
155
  token: ata,
156
+ amount: BigInt(dropAmount * 10 ** decimals),
157
+ mintAuthority,
161
158
  }),
162
159
  ];
163
160
  // Generate Create ATA instructions for other token accounts we wish to add
164
161
  const otherAtaInstructions = otherAtaWallets
165
162
  ? await Promise.all(otherAtaWallets.map(async (wallet) => await getCreateAssociatedTokenIdempotentInstructionAsync({
166
163
  mint: mint.address,
167
- owner: wallet,
168
164
  payer,
165
+ owner: wallet,
169
166
  })))
170
167
  : [];
171
168
  const alreadyExists = await mintExists(client, mint.address);
172
- const instructions = alreadyExists ? [...otherAtaInstructions] : [...baseInstructions, ...otherAtaInstructions];
169
+ let instructions = alreadyExists ? [...otherAtaInstructions] : [...baseInstructions, ...otherAtaInstructions];
173
170
  await sendAndConfirmInstructions(client, payer, instructions, 'Initialize token and ATAs', 'finalized');
174
171
  }
175
172
  async function setupTestSuite() {
176
- const { koraAddress, koraRpcUrl, tokenDecimals, tokenDropAmount, solDropAmount, solanaRpcUrl, solanaWsUrl } = loadEnvironmentVariables();
173
+ const { koraAddress, koraRpcUrl, commitment, tokenDecimals, tokenDropAmount, solDropAmount, solanaRpcUrl, solanaWsUrl, } = await loadEnvironmentVariables();
177
174
  // Load auth config from environment if not provided
178
175
  const authConfig = process.env.ENABLE_AUTH === 'true'
179
176
  ? {
@@ -205,21 +202,22 @@ async function setupTestSuite() {
205
202
  // Initialize token and ATAs
206
203
  await initializeToken({
207
204
  client,
208
- decimals: tokenDecimals,
209
- dropAmount: tokenDropAmount,
210
- mint: usdcMint,
211
205
  mintAuthority,
212
- otherAtaWallets: [testWallet.address, koraAddress, destinationAddress],
213
- owner: testWallet,
214
206
  payer: mintAuthority,
207
+ owner: testWallet,
208
+ mint: usdcMint,
209
+ dropAmount: tokenDropAmount,
210
+ decimals: tokenDecimals,
211
+ otherAtaWallets: [testWallet.address, koraAddress, destinationAddress],
215
212
  });
216
213
  return {
217
- destinationAddress,
218
- koraAddress,
219
214
  koraClient: new KoraClient({ rpcUrl: koraRpcUrl, ...authConfig }),
220
215
  koraRpcUrl,
221
216
  testWallet,
222
217
  usdcMint: usdcMint.address,
218
+ destinationAddress,
219
+ koraAddress,
220
+ authConfig,
223
221
  };
224
222
  }
225
223
  const mintExists = async (client, mint) => {
@@ -227,7 +225,7 @@ const mintExists = async (client, mint) => {
227
225
  const mintAccount = await client.rpc.getAccountInfo(mint).send();
228
226
  return mintAccount.value !== null;
229
227
  }
230
- catch {
228
+ catch (error) {
231
229
  return false;
232
230
  }
233
231
  };