@bitflowlabs/core-sdk 2.5.1-beta.0 → 3.0.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 +39 -27
- package/dist/src/BitflowSDK.js +0 -1
- package/dist/src/BitflowSDK.js.map +1 -1
- package/dist/src/config.d.ts +5 -1
- package/dist/src/config.js +10 -20
- package/dist/src/config.js.map +1 -1
- package/dist/src/types.d.ts +4 -4
- package/dist/test/BitflowSDK.test.js +283 -102
- package/dist/test/BitflowSDK.test.js.map +1 -1
- package/dist/test/config.test.js +132 -77
- package/dist/test/config.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -39,7 +39,11 @@ const createMockRoute = (providerValue) => {
|
|
|
39
39
|
// the provider field is null, undefined, or a real address.
|
|
40
40
|
},
|
|
41
41
|
},
|
|
42
|
-
swapData: {
|
|
42
|
+
swapData: {
|
|
43
|
+
contract: 'SP...swap-contract',
|
|
44
|
+
function: 'swap',
|
|
45
|
+
parameters: {},
|
|
46
|
+
},
|
|
43
47
|
postConditions: {},
|
|
44
48
|
tokenXDecimals: 6,
|
|
45
49
|
tokenYDecimals: 6,
|
|
@@ -66,9 +70,14 @@ describe('BitflowSDK - Provider Logic in getQuoteForRoute', () => {
|
|
|
66
70
|
// This is the key change: we now simulate a contract function that expects a 'provider'.
|
|
67
71
|
mockedGetInterface.mockResolvedValue({
|
|
68
72
|
contractInterface: {},
|
|
69
|
-
functionArgs: [{ name: 'provider', type: '{optional: principal}' }]
|
|
73
|
+
functionArgs: [{ name: 'provider', type: '{optional: principal}' }],
|
|
74
|
+
});
|
|
75
|
+
mockedCallReadOnly.mockResolvedValue({
|
|
76
|
+
convertedResult: 100,
|
|
77
|
+
rawResult: 1000,
|
|
78
|
+
tokenXDecimals: 6,
|
|
79
|
+
tokenYDecimals: 6,
|
|
70
80
|
});
|
|
71
|
-
mockedCallReadOnly.mockResolvedValue({ convertedResult: 100, rawResult: 1000, tokenXDecimals: 6, tokenYDecimals: 6 });
|
|
72
81
|
// Set up the default provider address for the SDK instance
|
|
73
82
|
config_1.configs.BITFLOW_PROVIDER_ADDRESS = MOCK_PROVIDER_ADDRESS;
|
|
74
83
|
// Initialize the SDK for each test
|
|
@@ -77,7 +86,9 @@ describe('BitflowSDK - Provider Logic in getQuoteForRoute', () => {
|
|
|
77
86
|
it('Scenario 1: Should use default provider when the route provider is null', async () => {
|
|
78
87
|
// ARRANGE: Create a fake route where the provider is explicitly `null`
|
|
79
88
|
const mockRouteWithNullProvider = createMockRoute(null);
|
|
80
|
-
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
89
|
+
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
90
|
+
'token-y': [mockRouteWithNullProvider],
|
|
91
|
+
});
|
|
81
92
|
// ACT: Run the function we want to test
|
|
82
93
|
await sdk.getQuoteForRoute('token-x', 'token-y', 100);
|
|
83
94
|
// ASSERT: Check if our logic worked correctly
|
|
@@ -88,7 +99,9 @@ describe('BitflowSDK - Provider Logic in getQuoteForRoute', () => {
|
|
|
88
99
|
it('Scenario 2: Should use default provider when the route provider is missing (undefined)', async () => {
|
|
89
100
|
// ARRANGE: Create a fake route where the 'provider' key doesn't exist
|
|
90
101
|
const mockRouteWithUndefinedProvider = createMockRoute(undefined);
|
|
91
|
-
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
102
|
+
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
103
|
+
'token-y': [mockRouteWithUndefinedProvider],
|
|
104
|
+
});
|
|
92
105
|
// ACT
|
|
93
106
|
await sdk.getQuoteForRoute('token-x', 'token-y', 100);
|
|
94
107
|
// ASSERT
|
|
@@ -100,7 +113,9 @@ describe('BitflowSDK - Provider Logic in getQuoteForRoute', () => {
|
|
|
100
113
|
// ARRANGE: Create a fake route that already has a valid provider address
|
|
101
114
|
const routeSpecificProvider = 'SP3B15B6STM80A752A80W3P7J53KSAQ7J01PJ80B9';
|
|
102
115
|
const mockRouteWithSpecificProvider = createMockRoute(routeSpecificProvider);
|
|
103
|
-
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
116
|
+
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
117
|
+
'token-y': [mockRouteWithSpecificProvider],
|
|
118
|
+
});
|
|
104
119
|
// ACT
|
|
105
120
|
await sdk.getQuoteForRoute('token-x', 'token-y', 100);
|
|
106
121
|
// ASSERT
|
|
@@ -111,9 +126,14 @@ describe('BitflowSDK - Provider Logic in getQuoteForRoute', () => {
|
|
|
111
126
|
});
|
|
112
127
|
it('Scenario 4: Should NOT add a provider if the function does not expect one', async () => {
|
|
113
128
|
// ARRANGE: For this test only, override the mock to simulate a function WITHOUT a provider.
|
|
114
|
-
mockedGetInterface.mockResolvedValue({
|
|
129
|
+
mockedGetInterface.mockResolvedValue({
|
|
130
|
+
contractInterface: {},
|
|
131
|
+
functionArgs: [{ name: 'amount', type: 'uint' }],
|
|
132
|
+
});
|
|
115
133
|
const mockRouteWithoutProvider = createMockRoute(undefined); // Provider is missing
|
|
116
|
-
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
134
|
+
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
135
|
+
'token-y': [mockRouteWithoutProvider],
|
|
136
|
+
});
|
|
117
137
|
// ACT
|
|
118
138
|
await sdk.getQuoteForRoute('token-x', 'token-y', 100);
|
|
119
139
|
// ASSERT
|
|
@@ -132,7 +152,9 @@ describe('BitflowSDK - Token and Swap Retrieval Methods', () => {
|
|
|
132
152
|
{ tokenId: 'token-x', isKeeperToken: false },
|
|
133
153
|
{ tokenId: 'token-keeper', isKeeperToken: true },
|
|
134
154
|
]);
|
|
135
|
-
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
155
|
+
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
156
|
+
'token-keeper': ['swap1', 'swap2'],
|
|
157
|
+
});
|
|
136
158
|
sdk = new BitflowSDK_1.BitflowSDK();
|
|
137
159
|
});
|
|
138
160
|
it('should return all available tokens', async () => {
|
|
@@ -145,9 +167,7 @@ describe('BitflowSDK - Token and Swap Retrieval Methods', () => {
|
|
|
145
167
|
});
|
|
146
168
|
it('should return only keeper tokens', async () => {
|
|
147
169
|
const tokens = await sdk.getKeeperTokens();
|
|
148
|
-
expect(tokens).toEqual([
|
|
149
|
-
{ tokenId: 'token-keeper', isKeeperToken: true }
|
|
150
|
-
]);
|
|
170
|
+
expect(tokens).toEqual([{ tokenId: 'token-keeper', isKeeperToken: true }]);
|
|
151
171
|
});
|
|
152
172
|
it('should return possible swaps for a token', async () => {
|
|
153
173
|
const swaps = await sdk.getPossibleSwaps('token-keeper');
|
|
@@ -165,7 +185,10 @@ describe('BitflowSDK - Token Y and Route Methods', () => {
|
|
|
165
185
|
{ tokenId: 'token-x', isKeeperToken: false },
|
|
166
186
|
{ tokenId: 'token-y', isKeeperToken: true },
|
|
167
187
|
]);
|
|
168
|
-
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
188
|
+
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
189
|
+
'token-y': [{ foo: 'bar' }],
|
|
190
|
+
'token-z': [{ baz: 'qux' }],
|
|
191
|
+
});
|
|
169
192
|
sdk = new BitflowSDK_1.BitflowSDK();
|
|
170
193
|
// Pre-populate swapOptions for keeper methods
|
|
171
194
|
sdk.context.swapOptions = {
|
|
@@ -173,23 +196,34 @@ describe('BitflowSDK - Token Y and Route Methods', () => {
|
|
|
173
196
|
};
|
|
174
197
|
});
|
|
175
198
|
it('should return all possible token Y for a given token X', async () => {
|
|
176
|
-
sdk.context.swapOptions['token-x'] = {
|
|
199
|
+
sdk.context.swapOptions['token-x'] = {
|
|
200
|
+
'token-y': [],
|
|
201
|
+
'token-z': [],
|
|
202
|
+
};
|
|
177
203
|
const result = await sdk.getAllPossibleTokenY('token-x');
|
|
178
204
|
expect(result).toEqual(['token-y', 'token-z']);
|
|
179
205
|
});
|
|
180
206
|
it('should return all keeper possible token Y for a given token X', async () => {
|
|
181
207
|
// Simulate getKeeperPossibleSwaps returns a similar structure
|
|
182
|
-
sdk.getKeeperPossibleSwaps = jest
|
|
208
|
+
sdk.getKeeperPossibleSwaps = jest
|
|
209
|
+
.fn()
|
|
210
|
+
.mockResolvedValue({ 'token-y': [], 'token-z': [] });
|
|
183
211
|
const result = await sdk.getAllKeeperPossibleTokenY('token-x');
|
|
184
212
|
expect(result).toEqual(['token-y', 'token-z']);
|
|
185
213
|
});
|
|
186
214
|
it('should return all possible token Y routes for a given token X and Y', async () => {
|
|
187
|
-
sdk.context.swapOptions['token-x'] = {
|
|
215
|
+
sdk.context.swapOptions['token-x'] = {
|
|
216
|
+
'token-y': [{ foo: 'bar' }],
|
|
217
|
+
'token-z': [{ baz: 'qux' }],
|
|
218
|
+
};
|
|
188
219
|
const result = await sdk.getAllPossibleTokenYRoutes('token-x', 'token-y');
|
|
189
220
|
expect(result).toEqual([{ foo: 'bar' }]);
|
|
190
221
|
});
|
|
191
222
|
it('should return all keeper possible token Y routes for a given token X and Y', async () => {
|
|
192
|
-
sdk.getKeeperPossibleSwaps = jest.fn().mockResolvedValue({
|
|
223
|
+
sdk.getKeeperPossibleSwaps = jest.fn().mockResolvedValue({
|
|
224
|
+
'token-y': [{ foo: 'bar' }],
|
|
225
|
+
'token-z': [{ baz: 'qux' }],
|
|
226
|
+
});
|
|
193
227
|
const result = await sdk.getAllKeeperPossibleTokenYRoutes('token-x', 'token-y');
|
|
194
228
|
expect(result).toEqual([{ foo: 'bar' }]);
|
|
195
229
|
});
|
|
@@ -207,31 +241,64 @@ describe('BitflowSDK - Route Quote Methods', () => {
|
|
|
207
241
|
{ tokenId: 'token-x', isKeeperToken: false },
|
|
208
242
|
{ tokenId: 'token-y', isKeeperToken: true },
|
|
209
243
|
]);
|
|
210
|
-
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
244
|
+
mockedFetchPossibleSwaps.mockResolvedValue({
|
|
245
|
+
'token-y': [
|
|
246
|
+
{
|
|
211
247
|
quoteData: {
|
|
212
248
|
contract: 'SP...contract',
|
|
213
249
|
function: 'get-quote',
|
|
214
250
|
parameters: { amount: null },
|
|
215
251
|
},
|
|
216
|
-
swapData: {
|
|
252
|
+
swapData: {
|
|
253
|
+
contract: 'SP...swap-contract',
|
|
254
|
+
function: 'swap',
|
|
255
|
+
parameters: {},
|
|
256
|
+
},
|
|
217
257
|
dex_path: ['BITFLOW_STABLE_XY_2'],
|
|
218
258
|
tokenPath: ['token-x', 'token-y'],
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
});
|
|
262
|
+
mockedGetInterface.mockResolvedValue({
|
|
263
|
+
contractInterface: {},
|
|
264
|
+
functionArgs: [{ name: 'amount', type: 'uint' }],
|
|
265
|
+
});
|
|
266
|
+
mockedCallReadOnly.mockResolvedValue({
|
|
267
|
+
convertedResult: 100,
|
|
268
|
+
rawResult: 1000,
|
|
269
|
+
tokenXDecimals: 6,
|
|
270
|
+
tokenYDecimals: 6,
|
|
271
|
+
allRoutes: [],
|
|
272
|
+
bestRoute: null,
|
|
273
|
+
});
|
|
274
|
+
mockedCallReadOnlyNoScale.mockResolvedValue({
|
|
275
|
+
convertedResult: 100,
|
|
276
|
+
rawResult: 1000,
|
|
277
|
+
tokenXDecimals: 6,
|
|
278
|
+
tokenYDecimals: 6,
|
|
279
|
+
allRoutes: [],
|
|
280
|
+
bestRoute: null,
|
|
281
|
+
});
|
|
223
282
|
sdk = new BitflowSDK_1.BitflowSDK();
|
|
224
283
|
sdk.context.swapOptions = {
|
|
225
|
-
'token-x': {
|
|
284
|
+
'token-x': {
|
|
285
|
+
'token-y': [
|
|
286
|
+
{
|
|
226
287
|
quoteData: {
|
|
227
288
|
contract: 'SP...contract',
|
|
228
289
|
function: 'get-quote',
|
|
229
290
|
parameters: { amount: null },
|
|
230
291
|
},
|
|
231
|
-
swapData: {
|
|
292
|
+
swapData: {
|
|
293
|
+
contract: 'SP...swap-contract',
|
|
294
|
+
function: 'swap',
|
|
295
|
+
parameters: {},
|
|
296
|
+
},
|
|
232
297
|
dex_path: ['BITFLOW_STABLE_XY_2'],
|
|
233
298
|
tokenPath: ['token-x', 'token-y'],
|
|
234
|
-
}
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
},
|
|
235
302
|
};
|
|
236
303
|
});
|
|
237
304
|
it('should get a quote for a route', async () => {
|
|
@@ -318,8 +385,13 @@ describe('BitflowSDK - Execution and Keeper Methods', () => {
|
|
|
318
385
|
await expect(sdk.executeSwap(swapExecutionData, senderAddress)).rejects.toThrow('only available in browser environments');
|
|
319
386
|
});
|
|
320
387
|
it('should get or create keeper contract', async () => {
|
|
321
|
-
mockedGetOrCreateKeeperContractAPI.mockResolvedValue({
|
|
322
|
-
|
|
388
|
+
mockedGetOrCreateKeeperContractAPI.mockResolvedValue({
|
|
389
|
+
contract: 'keeper-contract',
|
|
390
|
+
});
|
|
391
|
+
const params = {
|
|
392
|
+
stacksAddress: 'SOMEADDR',
|
|
393
|
+
keeperType: types_1.KeeperType.SWAP_BTC_TO_STX,
|
|
394
|
+
};
|
|
323
395
|
const result = await sdk.getOrCreateKeeperContract(params);
|
|
324
396
|
expect(result).toEqual({ contract: 'keeper-contract' });
|
|
325
397
|
expect(mockedGetOrCreateKeeperContractAPI).toHaveBeenCalled();
|
|
@@ -332,14 +404,21 @@ describe('BitflowSDK - Execution and Keeper Methods', () => {
|
|
|
332
404
|
});
|
|
333
405
|
it('should get quote', async () => {
|
|
334
406
|
mockedGetQuoteAPI.mockResolvedValue({ quote: 'quote-data' });
|
|
335
|
-
const params = {
|
|
407
|
+
const params = {
|
|
408
|
+
stacksAddress: 'SOMEADDR',
|
|
409
|
+
actionAmount: '1',
|
|
410
|
+
keeperType: types_1.KeeperType.SWAP_BTC_TO_STX,
|
|
411
|
+
};
|
|
336
412
|
const result = await sdk.getQuote(params);
|
|
337
413
|
expect(result).toEqual({ quote: 'quote-data' });
|
|
338
414
|
expect(mockedGetQuoteAPI).toHaveBeenCalled();
|
|
339
415
|
});
|
|
340
416
|
it('should handle errors in getOrCreateKeeperContract', async () => {
|
|
341
417
|
mockedGetOrCreateKeeperContractAPI.mockRejectedValue(new Error('fail'));
|
|
342
|
-
const params = {
|
|
418
|
+
const params = {
|
|
419
|
+
stacksAddress: 'SOMEADDR',
|
|
420
|
+
keeperType: types_1.KeeperType.SWAP_BTC_TO_STX,
|
|
421
|
+
};
|
|
343
422
|
await expect(sdk.getOrCreateKeeperContract(params)).rejects.toThrow('fail');
|
|
344
423
|
});
|
|
345
424
|
it('should handle errors in getUser', async () => {
|
|
@@ -348,7 +427,11 @@ describe('BitflowSDK - Execution and Keeper Methods', () => {
|
|
|
348
427
|
});
|
|
349
428
|
it('should handle errors in getQuote', async () => {
|
|
350
429
|
mockedGetQuoteAPI.mockRejectedValue(new Error('fail'));
|
|
351
|
-
const params = {
|
|
430
|
+
const params = {
|
|
431
|
+
stacksAddress: 'SOMEADDR',
|
|
432
|
+
actionAmount: '1',
|
|
433
|
+
keeperType: types_1.KeeperType.SWAP_BTC_TO_STX,
|
|
434
|
+
};
|
|
352
435
|
await expect(sdk.getQuote(params)).rejects.toThrow('fail');
|
|
353
436
|
});
|
|
354
437
|
});
|
|
@@ -486,10 +569,12 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
486
569
|
mockedCallGetSwapParams.mockResolvedValue({
|
|
487
570
|
swapData: { data: 'swap-data' },
|
|
488
571
|
parameters: { params: 'params' },
|
|
489
|
-
postConditions: { conditions: 'conditions' }
|
|
572
|
+
postConditions: { conditions: 'conditions' },
|
|
490
573
|
});
|
|
491
574
|
// Mock the getKeeperQuoteForRouteWithoutScaling method
|
|
492
|
-
jest
|
|
575
|
+
jest
|
|
576
|
+
.spyOn(BitflowSDK_1.BitflowSDK.prototype, 'getKeeperQuoteForRouteWithoutScaling')
|
|
577
|
+
.mockResolvedValue({
|
|
493
578
|
bestRoute: {
|
|
494
579
|
route: {
|
|
495
580
|
dex_path: ['BITFLOW_XY_2_xyk'],
|
|
@@ -529,7 +614,8 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
529
614
|
tokenXDecimals: 6,
|
|
530
615
|
tokenYDecimals: 6,
|
|
531
616
|
},
|
|
532
|
-
allRoutes: [
|
|
617
|
+
allRoutes: [
|
|
618
|
+
{
|
|
533
619
|
route: {
|
|
534
620
|
dex_path: ['BITFLOW_XY_2_xyk'],
|
|
535
621
|
token_path: ['token-x', 'token-y'],
|
|
@@ -567,7 +653,8 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
567
653
|
tokenPath: ['token-x', 'token-y'],
|
|
568
654
|
tokenXDecimals: 6,
|
|
569
655
|
tokenYDecimals: 6,
|
|
570
|
-
}
|
|
656
|
+
},
|
|
657
|
+
],
|
|
571
658
|
inputData: {
|
|
572
659
|
tokenX: 'token-x',
|
|
573
660
|
tokenY: 'token-y',
|
|
@@ -581,13 +668,17 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
581
668
|
route: {
|
|
582
669
|
dex_path: ['BITFLOW_XY_2'],
|
|
583
670
|
postConditions: {},
|
|
584
|
-
quoteData: {
|
|
671
|
+
quoteData: {
|
|
672
|
+
contract: 'SP...contract',
|
|
673
|
+
function: 'get-quote',
|
|
674
|
+
parameters: { amount: null },
|
|
675
|
+
},
|
|
585
676
|
swapData: {
|
|
586
677
|
contract: 'SP...swap-contract',
|
|
587
678
|
function: 'swap',
|
|
588
679
|
parameters: {
|
|
589
|
-
'pool-trait': 'SP1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.xyk-pool-v-1-2'
|
|
590
|
-
}
|
|
680
|
+
'pool-trait': 'SP1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.xyk-pool-v-1-2',
|
|
681
|
+
},
|
|
591
682
|
},
|
|
592
683
|
token_path: ['token-x', 'token-y'],
|
|
593
684
|
tokenXDecimals: 6,
|
|
@@ -602,7 +693,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
602
693
|
expect(result).toEqual({
|
|
603
694
|
swapData: { data: 'swap-data' },
|
|
604
695
|
parameters: { params: 'params' },
|
|
605
|
-
postConditions: { conditions: 'conditions' }
|
|
696
|
+
postConditions: { conditions: 'conditions' },
|
|
606
697
|
});
|
|
607
698
|
expect(mockedCallGetSwapParams).toHaveBeenCalled();
|
|
608
699
|
});
|
|
@@ -611,13 +702,17 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
611
702
|
route: {
|
|
612
703
|
dex_path: ['BITFLOW_XY_2'],
|
|
613
704
|
postConditions: {},
|
|
614
|
-
quoteData: {
|
|
705
|
+
quoteData: {
|
|
706
|
+
contract: 'SP...contract',
|
|
707
|
+
function: 'get-quote',
|
|
708
|
+
parameters: { amount: null },
|
|
709
|
+
},
|
|
615
710
|
swapData: {
|
|
616
711
|
contract: 'SP...swap-contract',
|
|
617
712
|
function: 'swap',
|
|
618
713
|
parameters: {
|
|
619
|
-
'pool-trait': 'SP1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.xyk-pool-v-1-2'
|
|
620
|
-
}
|
|
714
|
+
'pool-trait': 'SP1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.xyk-pool-v-1-2',
|
|
715
|
+
},
|
|
621
716
|
},
|
|
622
717
|
token_path: ['token-x', 'token-y'],
|
|
623
718
|
tokenXDecimals: 6,
|
|
@@ -632,12 +727,12 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
632
727
|
expect(result).toEqual({
|
|
633
728
|
swapData: { data: 'swap-data' },
|
|
634
729
|
parameters: { params: 'params' },
|
|
635
|
-
postConditions: { conditions: 'conditions' }
|
|
730
|
+
postConditions: { conditions: 'conditions' },
|
|
636
731
|
});
|
|
637
732
|
expect(mockedCallGetSwapParams).toHaveBeenCalled();
|
|
638
733
|
});
|
|
639
734
|
it('should get keeper aggregator route data', async () => {
|
|
640
|
-
sdk[
|
|
735
|
+
sdk['context'].availableTokens = [
|
|
641
736
|
{
|
|
642
737
|
base: 'base-x',
|
|
643
738
|
type: 'type-x',
|
|
@@ -646,7 +741,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
646
741
|
status: 'active',
|
|
647
742
|
symbol: 'TKX',
|
|
648
743
|
tokenId: 'token-x',
|
|
649
|
-
|
|
744
|
+
'token-id': 'token-x',
|
|
650
745
|
tokenContract: 'contract-x',
|
|
651
746
|
tokenDecimals: 6,
|
|
652
747
|
tokenName: 'Token X',
|
|
@@ -655,11 +750,11 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
655
750
|
bridge: 'FALSE',
|
|
656
751
|
layerOneAsset: null,
|
|
657
752
|
priceData: {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
753
|
+
'1h_change': null,
|
|
754
|
+
'1yr_change': null,
|
|
755
|
+
'24h_change': null,
|
|
756
|
+
'30d_change': null,
|
|
757
|
+
'7d_change': null,
|
|
663
758
|
last_price: null,
|
|
664
759
|
last_updated: null,
|
|
665
760
|
},
|
|
@@ -672,7 +767,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
672
767
|
status: 'active',
|
|
673
768
|
symbol: 'TKY',
|
|
674
769
|
tokenId: 'token-y',
|
|
675
|
-
|
|
770
|
+
'token-id': 'token-y',
|
|
676
771
|
tokenContract: 'contract-y',
|
|
677
772
|
tokenDecimals: 8,
|
|
678
773
|
tokenName: 'Token Y',
|
|
@@ -681,11 +776,11 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
681
776
|
bridge: 'FALSE',
|
|
682
777
|
layerOneAsset: null,
|
|
683
778
|
priceData: {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
779
|
+
'1h_change': null,
|
|
780
|
+
'1yr_change': null,
|
|
781
|
+
'24h_change': null,
|
|
782
|
+
'30d_change': null,
|
|
783
|
+
'7d_change': null,
|
|
689
784
|
last_price: null,
|
|
690
785
|
last_updated: null,
|
|
691
786
|
},
|
|
@@ -696,7 +791,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
696
791
|
expect(result.actionTrait).toBeDefined();
|
|
697
792
|
});
|
|
698
793
|
it('should handle mixed XYK and stableswap route', async () => {
|
|
699
|
-
sdk[
|
|
794
|
+
sdk['context'].availableTokens = [
|
|
700
795
|
{
|
|
701
796
|
base: 'base-x',
|
|
702
797
|
type: 'type-x',
|
|
@@ -705,7 +800,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
705
800
|
status: 'active',
|
|
706
801
|
symbol: 'TKX',
|
|
707
802
|
tokenId: 'token-x',
|
|
708
|
-
|
|
803
|
+
'token-id': 'token-x',
|
|
709
804
|
tokenContract: 'contract-x',
|
|
710
805
|
tokenDecimals: 6,
|
|
711
806
|
tokenName: 'Token X',
|
|
@@ -714,11 +809,11 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
714
809
|
bridge: 'FALSE',
|
|
715
810
|
layerOneAsset: null,
|
|
716
811
|
priceData: {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
812
|
+
'1h_change': null,
|
|
813
|
+
'1yr_change': null,
|
|
814
|
+
'24h_change': null,
|
|
815
|
+
'30d_change': null,
|
|
816
|
+
'7d_change': null,
|
|
722
817
|
last_price: null,
|
|
723
818
|
last_updated: null,
|
|
724
819
|
},
|
|
@@ -731,7 +826,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
731
826
|
status: 'active',
|
|
732
827
|
symbol: 'TKY',
|
|
733
828
|
tokenId: 'token-y',
|
|
734
|
-
|
|
829
|
+
'token-id': 'token-y',
|
|
735
830
|
tokenContract: 'contract-y',
|
|
736
831
|
tokenDecimals: 8,
|
|
737
832
|
tokenName: 'Token Y',
|
|
@@ -740,18 +835,20 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
740
835
|
bridge: 'FALSE',
|
|
741
836
|
layerOneAsset: null,
|
|
742
837
|
priceData: {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
838
|
+
'1h_change': null,
|
|
839
|
+
'1yr_change': null,
|
|
840
|
+
'24h_change': null,
|
|
841
|
+
'30d_change': null,
|
|
842
|
+
'7d_change': null,
|
|
748
843
|
last_price: null,
|
|
749
844
|
last_updated: null,
|
|
750
845
|
},
|
|
751
846
|
},
|
|
752
847
|
];
|
|
753
848
|
// Override the mock for this specific test
|
|
754
|
-
jest
|
|
849
|
+
jest
|
|
850
|
+
.spyOn(BitflowSDK_1.BitflowSDK.prototype, 'getKeeperQuoteForRouteWithoutScaling')
|
|
851
|
+
.mockResolvedValue({
|
|
755
852
|
bestRoute: {
|
|
756
853
|
route: {
|
|
757
854
|
dex_path: ['BITFLOW_XY_2_xyk', 'BITFLOW_STABLE_XY_2_stable'],
|
|
@@ -793,7 +890,8 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
793
890
|
tokenXDecimals: 6,
|
|
794
891
|
tokenYDecimals: 6,
|
|
795
892
|
},
|
|
796
|
-
allRoutes: [
|
|
893
|
+
allRoutes: [
|
|
894
|
+
{
|
|
797
895
|
route: {
|
|
798
896
|
dex_path: ['BITFLOW_XY_2_xyk', 'BITFLOW_STABLE_XY_2_stable'],
|
|
799
897
|
token_path: ['token-x', 'token-y'],
|
|
@@ -833,7 +931,8 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
833
931
|
tokenPath: ['token-x', 'token-y'],
|
|
834
932
|
tokenXDecimals: 6,
|
|
835
933
|
tokenYDecimals: 6,
|
|
836
|
-
}
|
|
934
|
+
},
|
|
935
|
+
],
|
|
837
936
|
inputData: {
|
|
838
937
|
tokenX: 'token-x',
|
|
839
938
|
tokenY: 'token-y',
|
|
@@ -845,7 +944,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
845
944
|
expect(result.stableswapPoolList).toBeDefined();
|
|
846
945
|
});
|
|
847
946
|
it('should handle swaps-reversed parameter', async () => {
|
|
848
|
-
sdk[
|
|
947
|
+
sdk['context'].availableTokens = [
|
|
849
948
|
{
|
|
850
949
|
base: 'base-x',
|
|
851
950
|
type: 'type-x',
|
|
@@ -854,7 +953,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
854
953
|
status: 'active',
|
|
855
954
|
symbol: 'TKX',
|
|
856
955
|
tokenId: 'token-x',
|
|
857
|
-
|
|
956
|
+
'token-id': 'token-x',
|
|
858
957
|
tokenContract: 'contract-x',
|
|
859
958
|
tokenDecimals: 6,
|
|
860
959
|
tokenName: 'Token X',
|
|
@@ -863,11 +962,11 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
863
962
|
bridge: 'FALSE',
|
|
864
963
|
layerOneAsset: null,
|
|
865
964
|
priceData: {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
965
|
+
'1h_change': null,
|
|
966
|
+
'1yr_change': null,
|
|
967
|
+
'24h_change': null,
|
|
968
|
+
'30d_change': null,
|
|
969
|
+
'7d_change': null,
|
|
871
970
|
last_price: null,
|
|
872
971
|
last_updated: null,
|
|
873
972
|
},
|
|
@@ -880,7 +979,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
880
979
|
status: 'active',
|
|
881
980
|
symbol: 'TKY',
|
|
882
981
|
tokenId: 'token-y',
|
|
883
|
-
|
|
982
|
+
'token-id': 'token-y',
|
|
884
983
|
tokenContract: 'contract-y',
|
|
885
984
|
tokenDecimals: 8,
|
|
886
985
|
tokenName: 'Token Y',
|
|
@@ -889,18 +988,20 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
889
988
|
bridge: 'FALSE',
|
|
890
989
|
layerOneAsset: null,
|
|
891
990
|
priceData: {
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
991
|
+
'1h_change': null,
|
|
992
|
+
'1yr_change': null,
|
|
993
|
+
'24h_change': null,
|
|
994
|
+
'30d_change': null,
|
|
995
|
+
'7d_change': null,
|
|
897
996
|
last_price: null,
|
|
898
997
|
last_updated: null,
|
|
899
998
|
},
|
|
900
999
|
},
|
|
901
1000
|
];
|
|
902
1001
|
// Override the mock for this specific test
|
|
903
|
-
jest
|
|
1002
|
+
jest
|
|
1003
|
+
.spyOn(BitflowSDK_1.BitflowSDK.prototype, 'getKeeperQuoteForRouteWithoutScaling')
|
|
1004
|
+
.mockResolvedValue({
|
|
904
1005
|
bestRoute: {
|
|
905
1006
|
route: {
|
|
906
1007
|
dex_path: ['BITFLOW_XY_2_xyk'],
|
|
@@ -942,7 +1043,8 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
942
1043
|
tokenXDecimals: 6,
|
|
943
1044
|
tokenYDecimals: 6,
|
|
944
1045
|
},
|
|
945
|
-
allRoutes: [
|
|
1046
|
+
allRoutes: [
|
|
1047
|
+
{
|
|
946
1048
|
route: {
|
|
947
1049
|
dex_path: ['BITFLOW_XY_2_xyk'],
|
|
948
1050
|
token_path: ['token-x', 'token-y'],
|
|
@@ -982,7 +1084,8 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
982
1084
|
tokenPath: ['token-x', 'token-y'],
|
|
983
1085
|
tokenXDecimals: 6,
|
|
984
1086
|
tokenYDecimals: 6,
|
|
985
|
-
}
|
|
1087
|
+
},
|
|
1088
|
+
],
|
|
986
1089
|
inputData: {
|
|
987
1090
|
tokenX: 'token-x',
|
|
988
1091
|
tokenY: 'token-y',
|
|
@@ -996,7 +1099,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
996
1099
|
});
|
|
997
1100
|
it('should handle unsupported DEX path in mapDexPathToActionTrait', async () => {
|
|
998
1101
|
// Patch availableTokens so contract identifier lookup does not fail
|
|
999
|
-
sdk[
|
|
1102
|
+
sdk['context'].availableTokens = [
|
|
1000
1103
|
{
|
|
1001
1104
|
base: 'base-x',
|
|
1002
1105
|
type: 'type-x',
|
|
@@ -1005,7 +1108,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
1005
1108
|
status: 'active',
|
|
1006
1109
|
symbol: 'TKX',
|
|
1007
1110
|
tokenId: 'token-x',
|
|
1008
|
-
|
|
1111
|
+
'token-id': 'token-x',
|
|
1009
1112
|
tokenContract: 'contract-x',
|
|
1010
1113
|
tokenDecimals: 6,
|
|
1011
1114
|
tokenName: 'Token X',
|
|
@@ -1014,11 +1117,11 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
1014
1117
|
bridge: 'FALSE',
|
|
1015
1118
|
layerOneAsset: null,
|
|
1016
1119
|
priceData: {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1120
|
+
'1h_change': null,
|
|
1121
|
+
'1yr_change': null,
|
|
1122
|
+
'24h_change': null,
|
|
1123
|
+
'30d_change': null,
|
|
1124
|
+
'7d_change': null,
|
|
1022
1125
|
last_price: null,
|
|
1023
1126
|
last_updated: null,
|
|
1024
1127
|
},
|
|
@@ -1031,7 +1134,7 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
1031
1134
|
status: 'active',
|
|
1032
1135
|
symbol: 'TKY',
|
|
1033
1136
|
tokenId: 'token-y',
|
|
1034
|
-
|
|
1137
|
+
'token-id': 'token-y',
|
|
1035
1138
|
tokenContract: 'contract-y',
|
|
1036
1139
|
tokenDecimals: 8,
|
|
1037
1140
|
tokenName: 'Token Y',
|
|
@@ -1040,11 +1143,11 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
1040
1143
|
bridge: 'FALSE',
|
|
1041
1144
|
layerOneAsset: null,
|
|
1042
1145
|
priceData: {
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1146
|
+
'1h_change': null,
|
|
1147
|
+
'1yr_change': null,
|
|
1148
|
+
'24h_change': null,
|
|
1149
|
+
'30d_change': null,
|
|
1150
|
+
'7d_change': null,
|
|
1048
1151
|
last_price: null,
|
|
1049
1152
|
last_updated: null,
|
|
1050
1153
|
},
|
|
@@ -1136,8 +1239,86 @@ describe('BitflowSDK - Swap Parameter and Preparation Methods', () => {
|
|
|
1136
1239
|
});
|
|
1137
1240
|
it('should handle error in getKeeperAggregatorRouteData', async () => {
|
|
1138
1241
|
// Mock getKeeperQuoteForRouteWithoutScaling to throw an error
|
|
1139
|
-
jest
|
|
1242
|
+
jest
|
|
1243
|
+
.spyOn(sdk, 'getKeeperQuoteForRouteWithoutScaling')
|
|
1244
|
+
.mockRejectedValue(new Error('API Error'));
|
|
1140
1245
|
await expect(sdk.getKeeperAggregatorRouteData('token-x', 'token-y', 100)).rejects.toThrow('API Error');
|
|
1141
1246
|
});
|
|
1142
1247
|
});
|
|
1248
|
+
describe('BitflowSDK - Class Initialization', () => {
|
|
1249
|
+
const mockedFetchAllTokens = fetchDataHelper.fetchAllTokensFromAPI;
|
|
1250
|
+
beforeEach(() => {
|
|
1251
|
+
jest.clearAllMocks();
|
|
1252
|
+
mockedFetchAllTokens.mockResolvedValue([
|
|
1253
|
+
{ tokenId: 'token-x', isKeeperToken: false },
|
|
1254
|
+
{ tokenId: 'token-y', isKeeperToken: true },
|
|
1255
|
+
]);
|
|
1256
|
+
});
|
|
1257
|
+
it('can be instantiated with no arguments', () => {
|
|
1258
|
+
expect(() => new BitflowSDK_1.BitflowSDK()).not.toThrow();
|
|
1259
|
+
});
|
|
1260
|
+
it('can be instantiated with an empty config object', () => {
|
|
1261
|
+
expect(() => new BitflowSDK_1.BitflowSDK({})).not.toThrow();
|
|
1262
|
+
});
|
|
1263
|
+
it('initializes context with empty collections', () => {
|
|
1264
|
+
const sdk = new BitflowSDK_1.BitflowSDK();
|
|
1265
|
+
const ctx = sdk.context;
|
|
1266
|
+
expect(ctx.availableTokens).toEqual([]);
|
|
1267
|
+
expect(ctx.contractInterfaces).toEqual({});
|
|
1268
|
+
expect(ctx.functionArgs).toEqual({});
|
|
1269
|
+
expect(ctx.swapOptions).toEqual({});
|
|
1270
|
+
});
|
|
1271
|
+
it('initializes context with STACKS_MAINNET network', () => {
|
|
1272
|
+
const { STACKS_MAINNET } = require('@stacks/network');
|
|
1273
|
+
const sdk = new BitflowSDK_1.BitflowSDK();
|
|
1274
|
+
expect(sdk.context.network).toBe(STACKS_MAINNET);
|
|
1275
|
+
});
|
|
1276
|
+
it('calls fetchAllTokensFromAPI during initialization', async () => {
|
|
1277
|
+
const sdk = new BitflowSDK_1.BitflowSDK();
|
|
1278
|
+
await sdk.getAvailableTokens();
|
|
1279
|
+
expect(mockedFetchAllTokens).toHaveBeenCalled();
|
|
1280
|
+
});
|
|
1281
|
+
it('merges a single config override into the shared configs object', () => {
|
|
1282
|
+
const providerAddress = 'SP2J6S063B42M61D5T1G295SA4238A7147A4N17X';
|
|
1283
|
+
new BitflowSDK_1.BitflowSDK({ BITFLOW_PROVIDER_ADDRESS: providerAddress });
|
|
1284
|
+
expect(config_1.configs.BITFLOW_PROVIDER_ADDRESS).toBe(providerAddress);
|
|
1285
|
+
});
|
|
1286
|
+
it('merges multiple config overrides into the shared configs object', () => {
|
|
1287
|
+
const customHost = 'https://custom-api.example.com';
|
|
1288
|
+
const providerAddress = 'SP2J6S063B42M61D5T1G295SA4238A7147A4N17X';
|
|
1289
|
+
new BitflowSDK_1.BitflowSDK({
|
|
1290
|
+
BITFLOW_API_HOST: customHost,
|
|
1291
|
+
BITFLOW_PROVIDER_ADDRESS: providerAddress,
|
|
1292
|
+
});
|
|
1293
|
+
expect(config_1.configs.BITFLOW_API_HOST).toBe(customHost);
|
|
1294
|
+
expect(config_1.configs.BITFLOW_PROVIDER_ADDRESS).toBe(providerAddress);
|
|
1295
|
+
});
|
|
1296
|
+
it('does not apply config overrides when constructed with no arguments', () => {
|
|
1297
|
+
const originalHost = config_1.configs.BITFLOW_API_HOST;
|
|
1298
|
+
new BitflowSDK_1.BitflowSDK();
|
|
1299
|
+
expect(config_1.configs.BITFLOW_API_HOST).toBe(originalHost);
|
|
1300
|
+
});
|
|
1301
|
+
it('does not re-fetch tokens when availableTokens is already populated', async () => {
|
|
1302
|
+
const sdk = new BitflowSDK_1.BitflowSDK();
|
|
1303
|
+
// Manually populate tokens to simulate a completed async init
|
|
1304
|
+
sdk.context.availableTokens = [
|
|
1305
|
+
{ tokenId: 'cached', isKeeperToken: false },
|
|
1306
|
+
];
|
|
1307
|
+
jest.clearAllMocks();
|
|
1308
|
+
const tokens = await sdk.getAvailableTokens();
|
|
1309
|
+
expect(tokens).toEqual([{ tokenId: 'cached', isKeeperToken: false }]);
|
|
1310
|
+
expect(mockedFetchAllTokens).not.toHaveBeenCalled();
|
|
1311
|
+
});
|
|
1312
|
+
it('re-fetches tokens in getAvailableTokens when availableTokens is empty', async () => {
|
|
1313
|
+
mockedFetchAllTokens.mockResolvedValue([
|
|
1314
|
+
{ tokenId: 'fetched-late', isKeeperToken: false },
|
|
1315
|
+
]);
|
|
1316
|
+
const sdk = new BitflowSDK_1.BitflowSDK();
|
|
1317
|
+
// Force context back to empty to simulate the async init not yet resolved
|
|
1318
|
+
sdk.context.availableTokens = [];
|
|
1319
|
+
const tokens = await sdk.getAvailableTokens();
|
|
1320
|
+
expect(tokens).toEqual([{ tokenId: 'fetched-late', isKeeperToken: false }]);
|
|
1321
|
+
expect(mockedFetchAllTokens).toHaveBeenCalled();
|
|
1322
|
+
});
|
|
1323
|
+
});
|
|
1143
1324
|
//# sourceMappingURL=BitflowSDK.test.js.map
|