@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.
- package/dist/src/client.d.ts +7 -201
- package/dist/src/client.js +15 -218
- 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 -82
- package/dist/src/types/index.d.ts +89 -161
- 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 +163 -253
- package/package.json +31 -13
- package/dist/src/plugin.d.ts +0 -85
package/dist/test/plugin.test.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
88
|
+
allow_transfer: true,
|
|
110
89
|
allow_assign: true,
|
|
111
90
|
allow_create_account: true,
|
|
112
|
-
|
|
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
|
-
|
|
121
|
-
|
|
99
|
+
spl_token: {
|
|
100
|
+
allow_transfer: true,
|
|
122
101
|
allow_burn: true,
|
|
123
102
|
allow_close_account: true,
|
|
124
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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('
|
|
292
|
-
it('should return Kit-typed response with Base64EncodedWireTransaction
|
|
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
|
-
|
|
314
|
-
|
|
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.
|
|
319
|
-
|
|
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
|
|
269
|
+
const tx = result.transaction;
|
|
270
|
+
const hash = result.blockhash;
|
|
323
271
|
const signerPubkey = result.signer_pubkey;
|
|
324
|
-
expect(
|
|
325
|
-
expect(
|
|
326
|
-
expect(
|
|
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.
|
|
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('
|
|
377
|
-
it('should export
|
|
378
|
-
// This test verifies the
|
|
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
|
|
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.
|
|
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));
|
package/dist/test/setup.d.ts
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
23
|
-
|
|
26
|
+
testUsdcMintSecret: string;
|
|
27
|
+
destinationAddress: Address<string>;
|
|
24
28
|
};
|
|
25
29
|
declare function setupTestSuite(): Promise<TestSuite>;
|
|
26
30
|
export default setupTestSuite;
|
package/dist/test/setup.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
80
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
};
|