@bitflowlabs/core-sdk 2.0.2 → 2.1.3
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/BitflowSDK.d.ts +6 -4
- package/dist/src/BitflowSDK.js +439 -239
- package/dist/src/BitflowSDK.js.map +1 -1
- package/dist/src/helpers/callReadOnlyHelper.d.ts +7 -1
- package/dist/src/helpers/callReadOnlyHelper.js +201 -26
- package/dist/src/helpers/callReadOnlyHelper.js.map +1 -1
- package/dist/src/keeper/keeperAPI.js +3 -48
- package/dist/src/keeper/keeperAPI.js.map +1 -1
- package/dist/src/keeper/types.d.ts +27 -10
- package/dist/src/keeper/types.js.map +1 -1
- package/dist/src/test/testMethods.js +10 -0
- package/dist/src/test/testMethods.js.map +1 -1
- package/package.json +2 -1
- package/src/BitflowSDK.ts +532 -269
- package/src/helpers/callReadOnlyHelper.ts +258 -32
- package/src/keeper/keeperAPI.ts +5 -68
- package/src/keeper/types.ts +28 -11
- package/src/test/testMethods.ts +19 -0
- package/dist/src/test-get-user.d.ts +0 -1
- package/dist/src/test-get-user.js +0 -77
- package/dist/src/test-get-user.js.map +0 -1
- package/dist/src/test-keeper-routes.d.ts +0 -1
- package/dist/src/test-keeper-routes.js +0 -67
- package/dist/src/test-keeper-routes.js.map +0 -1
- package/dist/src/test-order.d.ts +0 -1
- package/dist/src/test-order.js +0 -71
- package/dist/src/test-order.js.map +0 -1
- package/dist/src/test-raw-token-response.d.ts +0 -1
- package/dist/src/test-raw-token-response.js +0 -79
- package/dist/src/test-raw-token-response.js.map +0 -1
- package/dist/src/test-sdk.d.ts +0 -1
- package/dist/src/test-sdk.js +0 -229
- package/dist/src/test-sdk.js.map +0 -1
- package/dist/src/test-token.fetch.d.ts +0 -1
- package/dist/src/test-token.fetch.js +0 -63
- package/dist/src/test-token.fetch.js.map +0 -1
- package/src/test-get-user.ts +0 -87
- package/src/test-keeper-routes.ts +0 -76
- package/src/test-order.ts +0 -81
- package/src/test-raw-token-response.ts +0 -124
- package/src/test-sdk.ts +0 -262
- package/src/test-token.fetch.ts +0 -72
package/src/BitflowSDK.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { STACKS_MAINNET } from
|
|
2
|
-
import type { StacksProvider } from
|
|
1
|
+
import { STACKS_MAINNET } from '@stacks/network';
|
|
2
|
+
import type { StacksProvider } from '@stacks/connect';
|
|
3
3
|
import {
|
|
4
4
|
SwapContext,
|
|
5
5
|
Token,
|
|
@@ -10,14 +10,17 @@ import {
|
|
|
10
10
|
RouteQuote,
|
|
11
11
|
SwapDataParamsAndPostConditions,
|
|
12
12
|
BitflowSDKConfig,
|
|
13
|
-
} from
|
|
14
|
-
import { fetchAllTokensFromAPI } from
|
|
15
|
-
import { executeSwapHelper } from
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import {
|
|
13
|
+
} from './types';
|
|
14
|
+
import { fetchAllTokensFromAPI } from './helpers/fetchDataHelper';
|
|
15
|
+
import { executeSwapHelper } from './helpers/callSwapHelper';
|
|
16
|
+
import {
|
|
17
|
+
callReadOnlyFunctionHelper,
|
|
18
|
+
callReadOnlyFunctionHelperWithoutScaling,
|
|
19
|
+
} from './helpers/callReadOnlyHelper';
|
|
20
|
+
import { fetchPossibleSwapsFromAPI } from './helpers/fetchPossibleSwap';
|
|
21
|
+
import { getContractInterfaceAndFunction } from './helpers/getContractInterfaceAndFunction';
|
|
22
|
+
import { configs, validateConfig } from './config';
|
|
23
|
+
import { executeGetParams } from './helpers/callGetSwapParams';
|
|
21
24
|
import {
|
|
22
25
|
ActionFunctionArgs,
|
|
23
26
|
AggregatorRouteData,
|
|
@@ -36,7 +39,7 @@ import {
|
|
|
36
39
|
GetQuoteResponse,
|
|
37
40
|
GetUserResponse,
|
|
38
41
|
KeeperOrderRouteData,
|
|
39
|
-
} from
|
|
42
|
+
} from './keeper/types';
|
|
40
43
|
import {
|
|
41
44
|
cancelGroupOrderAPI,
|
|
42
45
|
cancelOrderAPI,
|
|
@@ -47,7 +50,15 @@ import {
|
|
|
47
50
|
getOrderAPI,
|
|
48
51
|
getQuoteAPI,
|
|
49
52
|
getUserAPI,
|
|
50
|
-
} from
|
|
53
|
+
} from './keeper/keeperAPI';
|
|
54
|
+
|
|
55
|
+
export const safeStringify = (obj: any, indent = 2) => {
|
|
56
|
+
return JSON.stringify(
|
|
57
|
+
obj,
|
|
58
|
+
(_, value) => (typeof value === 'bigint' ? value.toString() + 'n' : value),
|
|
59
|
+
indent
|
|
60
|
+
);
|
|
61
|
+
};
|
|
51
62
|
|
|
52
63
|
export class BitflowSDK {
|
|
53
64
|
private context: SwapContext;
|
|
@@ -69,21 +80,21 @@ export class BitflowSDK {
|
|
|
69
80
|
this.initializeContext();
|
|
70
81
|
}
|
|
71
82
|
private async loadConnectDependencies() {
|
|
72
|
-
if (typeof window ===
|
|
83
|
+
if (typeof window === 'undefined') {
|
|
73
84
|
throw new Error(
|
|
74
|
-
|
|
85
|
+
'Connect features are only available in browser environments'
|
|
75
86
|
);
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
try {
|
|
79
|
-
const { getStacksProvider } = await import(
|
|
90
|
+
const { getStacksProvider } = await import('@stacks/connect');
|
|
80
91
|
if (!this.stacksProvider) {
|
|
81
92
|
this.stacksProvider = await getStacksProvider();
|
|
82
93
|
}
|
|
83
94
|
return this.stacksProvider;
|
|
84
95
|
} catch (error) {
|
|
85
|
-
console.error(
|
|
86
|
-
throw new Error(
|
|
96
|
+
console.error('Error loading Stacks Connect:', error);
|
|
97
|
+
throw new Error('Failed to load Stacks Connect dependencies');
|
|
87
98
|
}
|
|
88
99
|
}
|
|
89
100
|
private async initializeContext(): Promise<void> {
|
|
@@ -119,7 +130,7 @@ export class BitflowSDK {
|
|
|
119
130
|
if (!this.context.swapOptions[cacheKey]) {
|
|
120
131
|
this.context.swapOptions[cacheKey] = await fetchPossibleSwapsFromAPI(
|
|
121
132
|
tokenX,
|
|
122
|
-
|
|
133
|
+
'KEEPER'
|
|
123
134
|
);
|
|
124
135
|
}
|
|
125
136
|
return this.context.swapOptions[cacheKey];
|
|
@@ -186,7 +197,7 @@ export class BitflowSDK {
|
|
|
186
197
|
continue;
|
|
187
198
|
}
|
|
188
199
|
|
|
189
|
-
const [contractDeployer, contractName] = contract.split(
|
|
200
|
+
const [contractDeployer, contractName] = contract.split('.');
|
|
190
201
|
|
|
191
202
|
if (!this.context.contractInterfaces[contract]) {
|
|
192
203
|
this.context.contractInterfaces[contract] =
|
|
@@ -201,21 +212,21 @@ export class BitflowSDK {
|
|
|
201
212
|
|
|
202
213
|
const params = { ...parameters };
|
|
203
214
|
|
|
204
|
-
if (
|
|
215
|
+
if ('dx' in params && params.dx === null) {
|
|
205
216
|
params.dx = amountInput;
|
|
206
|
-
} else if (
|
|
217
|
+
} else if ('dy' in params && params.dy === null) {
|
|
207
218
|
params.dy = amountInput;
|
|
208
|
-
} else if (
|
|
219
|
+
} else if ('amount' in params && params.amount === null) {
|
|
209
220
|
params.amount = amountInput;
|
|
210
|
-
} else if (
|
|
211
|
-
params[
|
|
212
|
-
} else if (
|
|
213
|
-
params[
|
|
214
|
-
} else if (
|
|
215
|
-
params[
|
|
216
|
-
params[
|
|
217
|
-
} else if (
|
|
218
|
-
params[
|
|
221
|
+
} else if ('amt-in' in params && params['amt-in'] === null) {
|
|
222
|
+
params['amt-in'] = amountInput;
|
|
223
|
+
} else if ('amt-in-max' in params && params['amt-in-max'] === null) {
|
|
224
|
+
params['amt-in-max'] = amountInput;
|
|
225
|
+
} else if ('y-amount' in params && params['y-amount'] === null) {
|
|
226
|
+
params['y-amount'] = amountInput;
|
|
227
|
+
params['x-amount'] = amountInput;
|
|
228
|
+
} else if ('x-amount' in params && params['x-amount'] === null) {
|
|
229
|
+
params['x-amount'] = amountInput;
|
|
219
230
|
} else {
|
|
220
231
|
params.dx = amountInput;
|
|
221
232
|
}
|
|
@@ -233,7 +244,7 @@ export class BitflowSDK {
|
|
|
233
244
|
this.context
|
|
234
245
|
);
|
|
235
246
|
|
|
236
|
-
if (typeof convertedResult ===
|
|
247
|
+
if (typeof convertedResult === 'number' && convertedResult > 0) {
|
|
237
248
|
const updatedQuoteData = {
|
|
238
249
|
...route.quoteData,
|
|
239
250
|
parameters: { ...params },
|
|
@@ -246,70 +257,70 @@ export class BitflowSDK {
|
|
|
246
257
|
amount:
|
|
247
258
|
params.amount ||
|
|
248
259
|
params.dx ||
|
|
249
|
-
params[
|
|
250
|
-
params[
|
|
251
|
-
params[
|
|
252
|
-
params[
|
|
260
|
+
params['amt-in'] ||
|
|
261
|
+
params['amt-in-max'] ||
|
|
262
|
+
params['y-amount'] ||
|
|
263
|
+
params['x-amount'] ||
|
|
253
264
|
params.dy,
|
|
254
265
|
dx:
|
|
255
266
|
params.amount ||
|
|
256
267
|
params.dx ||
|
|
257
|
-
params[
|
|
258
|
-
params[
|
|
259
|
-
params[
|
|
260
|
-
params[
|
|
268
|
+
params['amt-in'] ||
|
|
269
|
+
params['amt-in-max'] ||
|
|
270
|
+
params['y-amount'] ||
|
|
271
|
+
params['x-amount'] ||
|
|
261
272
|
params.dy,
|
|
262
273
|
dy:
|
|
263
274
|
params.amount ||
|
|
264
275
|
params.dx ||
|
|
265
|
-
params[
|
|
266
|
-
params[
|
|
267
|
-
params[
|
|
268
|
-
params[
|
|
276
|
+
params['amt-in'] ||
|
|
277
|
+
params['amt-in-max'] ||
|
|
278
|
+
params['y-amount'] ||
|
|
279
|
+
params['x-amount'] ||
|
|
269
280
|
params.dy,
|
|
270
|
-
|
|
281
|
+
'amt-in':
|
|
271
282
|
params.amount ||
|
|
272
283
|
params.dx ||
|
|
273
|
-
params[
|
|
274
|
-
params[
|
|
275
|
-
params[
|
|
276
|
-
params[
|
|
284
|
+
params['amt-in'] ||
|
|
285
|
+
params['amt-in-max'] ||
|
|
286
|
+
params['y-amount'] ||
|
|
287
|
+
params['x-amount'] ||
|
|
277
288
|
params.dy,
|
|
278
|
-
|
|
289
|
+
'amt-in-max':
|
|
279
290
|
params.amount ||
|
|
280
291
|
params.dx ||
|
|
281
|
-
params[
|
|
282
|
-
params[
|
|
283
|
-
params[
|
|
284
|
-
params[
|
|
292
|
+
params['amt-in'] ||
|
|
293
|
+
params['amt-in-max'] ||
|
|
294
|
+
params['y-amount'] ||
|
|
295
|
+
params['x-amount'] ||
|
|
285
296
|
params.dy,
|
|
286
|
-
|
|
297
|
+
'y-amount':
|
|
287
298
|
params.amount ||
|
|
288
299
|
params.dx ||
|
|
289
|
-
params[
|
|
290
|
-
params[
|
|
291
|
-
params[
|
|
292
|
-
params[
|
|
300
|
+
params['amt-in'] ||
|
|
301
|
+
params['amt-in-max'] ||
|
|
302
|
+
params['y-amount'] ||
|
|
303
|
+
params['x-amount'] ||
|
|
293
304
|
params.dy,
|
|
294
|
-
|
|
305
|
+
'x-amount':
|
|
295
306
|
params.amount ||
|
|
296
307
|
params.dx ||
|
|
297
|
-
params[
|
|
298
|
-
params[
|
|
299
|
-
params[
|
|
300
|
-
params[
|
|
308
|
+
params['amt-in'] ||
|
|
309
|
+
params['amt-in-max'] ||
|
|
310
|
+
params['y-amount'] ||
|
|
311
|
+
params['x-amount'] ||
|
|
301
312
|
params.dy,
|
|
302
313
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
314
|
+
'min-received': rawResult,
|
|
315
|
+
'min-dy': rawResult,
|
|
316
|
+
'min-dz': rawResult,
|
|
317
|
+
'min-dw': rawResult,
|
|
318
|
+
'amt-out': rawResult,
|
|
319
|
+
'amt-out-min': rawResult,
|
|
320
|
+
'min-x-amount': rawResult,
|
|
321
|
+
'min-dv': rawResult,
|
|
322
|
+
'min-y-amount': rawResult,
|
|
323
|
+
'min-dx': rawResult,
|
|
313
324
|
},
|
|
314
325
|
};
|
|
315
326
|
|
|
@@ -331,7 +342,7 @@ export class BitflowSDK {
|
|
|
331
342
|
|
|
332
343
|
allRoutes.push(quoteResult);
|
|
333
344
|
} else {
|
|
334
|
-
throw new Error(
|
|
345
|
+
throw new Error('Invalid quote result');
|
|
335
346
|
}
|
|
336
347
|
} catch (error) {
|
|
337
348
|
console.warn(
|
|
@@ -373,8 +384,8 @@ export class BitflowSDK {
|
|
|
373
384
|
amountInput: number
|
|
374
385
|
): Promise<QuoteResult> {
|
|
375
386
|
const COMPATIBLE_DEX_PATHS = new Set([
|
|
376
|
-
|
|
377
|
-
|
|
387
|
+
'BITFLOW_STABLE_XY_2',
|
|
388
|
+
'BITFLOW_XYK_XY_2',
|
|
378
389
|
]);
|
|
379
390
|
|
|
380
391
|
const isCompatibleRoute = (dexPath: string[]): boolean => {
|
|
@@ -414,7 +425,7 @@ export class BitflowSDK {
|
|
|
414
425
|
continue;
|
|
415
426
|
}
|
|
416
427
|
|
|
417
|
-
const [contractDeployer, contractName] = contract.split(
|
|
428
|
+
const [contractDeployer, contractName] = contract.split('.');
|
|
418
429
|
|
|
419
430
|
if (!this.context.contractInterfaces[contract]) {
|
|
420
431
|
this.context.contractInterfaces[contract] =
|
|
@@ -429,21 +440,21 @@ export class BitflowSDK {
|
|
|
429
440
|
|
|
430
441
|
const params = { ...parameters };
|
|
431
442
|
|
|
432
|
-
if (
|
|
443
|
+
if ('dx' in params && params.dx === null) {
|
|
433
444
|
params.dx = amountInput;
|
|
434
|
-
} else if (
|
|
445
|
+
} else if ('dy' in params && params.dy === null) {
|
|
435
446
|
params.dy = amountInput;
|
|
436
|
-
} else if (
|
|
447
|
+
} else if ('amount' in params && params.amount === null) {
|
|
437
448
|
params.amount = amountInput;
|
|
438
|
-
} else if (
|
|
439
|
-
params[
|
|
440
|
-
} else if (
|
|
441
|
-
params[
|
|
442
|
-
} else if (
|
|
443
|
-
params[
|
|
444
|
-
params[
|
|
445
|
-
} else if (
|
|
446
|
-
params[
|
|
449
|
+
} else if ('amt-in' in params && params['amt-in'] === null) {
|
|
450
|
+
params['amt-in'] = amountInput;
|
|
451
|
+
} else if ('amt-in-max' in params && params['amt-in-max'] === null) {
|
|
452
|
+
params['amt-in-max'] = amountInput;
|
|
453
|
+
} else if ('y-amount' in params && params['y-amount'] === null) {
|
|
454
|
+
params['y-amount'] = amountInput;
|
|
455
|
+
params['x-amount'] = amountInput;
|
|
456
|
+
} else if ('x-amount' in params && params['x-amount'] === null) {
|
|
457
|
+
params['x-amount'] = amountInput;
|
|
447
458
|
} else {
|
|
448
459
|
params.dx = amountInput;
|
|
449
460
|
}
|
|
@@ -461,7 +472,7 @@ export class BitflowSDK {
|
|
|
461
472
|
this.context
|
|
462
473
|
);
|
|
463
474
|
|
|
464
|
-
if (typeof convertedResult ===
|
|
475
|
+
if (typeof convertedResult === 'number' && convertedResult > 0) {
|
|
465
476
|
const updatedQuoteData = {
|
|
466
477
|
...route.quoteData,
|
|
467
478
|
parameters: { ...params },
|
|
@@ -474,61 +485,61 @@ export class BitflowSDK {
|
|
|
474
485
|
amount:
|
|
475
486
|
params.amount ||
|
|
476
487
|
params.dx ||
|
|
477
|
-
params[
|
|
478
|
-
params[
|
|
479
|
-
params[
|
|
480
|
-
params[
|
|
488
|
+
params['amt-in'] ||
|
|
489
|
+
params['amt-in-max'] ||
|
|
490
|
+
params['y-amount'] ||
|
|
491
|
+
params['x-amount'] ||
|
|
481
492
|
params.dy,
|
|
482
493
|
dx:
|
|
483
494
|
params.amount ||
|
|
484
495
|
params.dx ||
|
|
485
|
-
params[
|
|
486
|
-
params[
|
|
487
|
-
params[
|
|
488
|
-
params[
|
|
496
|
+
params['amt-in'] ||
|
|
497
|
+
params['amt-in-max'] ||
|
|
498
|
+
params['y-amount'] ||
|
|
499
|
+
params['x-amount'] ||
|
|
489
500
|
params.dy,
|
|
490
|
-
|
|
501
|
+
'amt-in':
|
|
491
502
|
params.amount ||
|
|
492
503
|
params.dx ||
|
|
493
|
-
params[
|
|
494
|
-
params[
|
|
495
|
-
params[
|
|
496
|
-
params[
|
|
504
|
+
params['amt-in'] ||
|
|
505
|
+
params['amt-in-max'] ||
|
|
506
|
+
params['y-amount'] ||
|
|
507
|
+
params['x-amount'] ||
|
|
497
508
|
params.dy,
|
|
498
|
-
|
|
509
|
+
'amt-in-max':
|
|
499
510
|
params.amount ||
|
|
500
511
|
params.dx ||
|
|
501
|
-
params[
|
|
502
|
-
params[
|
|
503
|
-
params[
|
|
504
|
-
params[
|
|
512
|
+
params['amt-in'] ||
|
|
513
|
+
params['amt-in-max'] ||
|
|
514
|
+
params['y-amount'] ||
|
|
515
|
+
params['x-amount'] ||
|
|
505
516
|
params.dy,
|
|
506
|
-
|
|
517
|
+
'y-amount':
|
|
507
518
|
params.amount ||
|
|
508
519
|
params.dx ||
|
|
509
|
-
params[
|
|
510
|
-
params[
|
|
511
|
-
params[
|
|
512
|
-
params[
|
|
520
|
+
params['amt-in'] ||
|
|
521
|
+
params['amt-in-max'] ||
|
|
522
|
+
params['y-amount'] ||
|
|
523
|
+
params['x-amount'] ||
|
|
513
524
|
params.dy,
|
|
514
|
-
|
|
525
|
+
'x-amount':
|
|
515
526
|
params.amount ||
|
|
516
527
|
params.dx ||
|
|
517
|
-
params[
|
|
518
|
-
params[
|
|
519
|
-
params[
|
|
520
|
-
params[
|
|
528
|
+
params['amt-in'] ||
|
|
529
|
+
params['amt-in-max'] ||
|
|
530
|
+
params['y-amount'] ||
|
|
531
|
+
params['x-amount'] ||
|
|
521
532
|
params.dy,
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
533
|
+
'min-received': rawResult,
|
|
534
|
+
'min-dy': rawResult,
|
|
535
|
+
'min-dz': rawResult,
|
|
536
|
+
'min-dw': rawResult,
|
|
537
|
+
'amt-out': rawResult,
|
|
538
|
+
'amt-out-min': rawResult,
|
|
539
|
+
'min-x-amount': rawResult,
|
|
540
|
+
'min-dv': rawResult,
|
|
541
|
+
'min-y-amount': rawResult,
|
|
542
|
+
'min-dx': rawResult,
|
|
532
543
|
},
|
|
533
544
|
};
|
|
534
545
|
|
|
@@ -550,7 +561,7 @@ export class BitflowSDK {
|
|
|
550
561
|
|
|
551
562
|
allRoutes.push(quoteResult);
|
|
552
563
|
} else {
|
|
553
|
-
throw new Error(
|
|
564
|
+
throw new Error('Invalid quote result');
|
|
554
565
|
}
|
|
555
566
|
} catch (error) {
|
|
556
567
|
console.warn(
|
|
@@ -585,6 +596,223 @@ export class BitflowSDK {
|
|
|
585
596
|
return result;
|
|
586
597
|
}
|
|
587
598
|
|
|
599
|
+
public async getKeeperQuoteForRouteWithoutScaling(
|
|
600
|
+
tokenX: string,
|
|
601
|
+
tokenY: string,
|
|
602
|
+
amountInput: number
|
|
603
|
+
): Promise<QuoteResult> {
|
|
604
|
+
const COMPATIBLE_DEX_PATHS = new Set([
|
|
605
|
+
'BITFLOW_STABLE_XY_2',
|
|
606
|
+
'BITFLOW_XYK_XY_2',
|
|
607
|
+
]);
|
|
608
|
+
|
|
609
|
+
const isCompatibleRoute = (dexPath: string[]): boolean => {
|
|
610
|
+
return dexPath.every((path) => COMPATIBLE_DEX_PATHS.has(path));
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
let routes = await this.getAllPossibleTokenYRoutes(tokenX, tokenY);
|
|
614
|
+
routes = routes.filter((route) => isCompatibleRoute(route.dex_path));
|
|
615
|
+
|
|
616
|
+
const allRoutes: RouteQuote[] = [];
|
|
617
|
+
|
|
618
|
+
for (let routeIndex = 0; routeIndex < routes.length; routeIndex++) {
|
|
619
|
+
const route = routes[routeIndex];
|
|
620
|
+
|
|
621
|
+
try {
|
|
622
|
+
if (!route.quoteData) {
|
|
623
|
+
console.warn(
|
|
624
|
+
`Skipping route ${routeIndex + 1} due to null quoteData:`,
|
|
625
|
+
route
|
|
626
|
+
);
|
|
627
|
+
continue;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const {
|
|
631
|
+
contract,
|
|
632
|
+
function: functionName,
|
|
633
|
+
parameters,
|
|
634
|
+
} = route.quoteData;
|
|
635
|
+
|
|
636
|
+
if (!contract || !functionName || !parameters) {
|
|
637
|
+
console.warn(
|
|
638
|
+
`Skipping route ${
|
|
639
|
+
routeIndex + 1
|
|
640
|
+
} due to missing required properties:`,
|
|
641
|
+
route.quoteData
|
|
642
|
+
);
|
|
643
|
+
continue;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
const [contractDeployer, contractName] = contract.split('.');
|
|
647
|
+
|
|
648
|
+
if (!this.context.contractInterfaces[contract]) {
|
|
649
|
+
this.context.contractInterfaces[contract] =
|
|
650
|
+
await getContractInterfaceAndFunction(
|
|
651
|
+
contractDeployer,
|
|
652
|
+
contractName,
|
|
653
|
+
functionName
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
const { interface: contractInterface, functionArgs } =
|
|
657
|
+
this.context.contractInterfaces[contract];
|
|
658
|
+
|
|
659
|
+
const params = { ...parameters };
|
|
660
|
+
|
|
661
|
+
if ('dx' in params && params.dx === null) {
|
|
662
|
+
params.dx = amountInput;
|
|
663
|
+
} else if ('dy' in params && params.dy === null) {
|
|
664
|
+
params.dy = amountInput;
|
|
665
|
+
} else if ('amount' in params && params.amount === null) {
|
|
666
|
+
params.amount = amountInput;
|
|
667
|
+
} else if ('amt-in' in params && params['amt-in'] === null) {
|
|
668
|
+
params['amt-in'] = amountInput;
|
|
669
|
+
} else if ('amt-in-max' in params && params['amt-in-max'] === null) {
|
|
670
|
+
params['amt-in-max'] = amountInput;
|
|
671
|
+
} else if ('y-amount' in params && params['y-amount'] === null) {
|
|
672
|
+
params['y-amount'] = amountInput;
|
|
673
|
+
params['x-amount'] = amountInput;
|
|
674
|
+
} else if ('x-amount' in params && params['x-amount'] === null) {
|
|
675
|
+
params['x-amount'] = amountInput;
|
|
676
|
+
} else {
|
|
677
|
+
params.dx = amountInput;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
const { convertedResult, rawResult, tokenXDecimals, tokenYDecimals } =
|
|
681
|
+
await callReadOnlyFunctionHelperWithoutScaling(
|
|
682
|
+
contractDeployer,
|
|
683
|
+
contractName,
|
|
684
|
+
functionName,
|
|
685
|
+
params,
|
|
686
|
+
contractDeployer,
|
|
687
|
+
tokenX,
|
|
688
|
+
tokenY,
|
|
689
|
+
route.swapData,
|
|
690
|
+
this.context
|
|
691
|
+
);
|
|
692
|
+
|
|
693
|
+
if (typeof convertedResult === 'number' && convertedResult > 0) {
|
|
694
|
+
const updatedQuoteData = {
|
|
695
|
+
...route.quoteData,
|
|
696
|
+
parameters: { ...params },
|
|
697
|
+
};
|
|
698
|
+
|
|
699
|
+
const updatedSwapData = {
|
|
700
|
+
...route.swapData,
|
|
701
|
+
parameters: {
|
|
702
|
+
...route.swapData.parameters,
|
|
703
|
+
amount:
|
|
704
|
+
params.amount ||
|
|
705
|
+
params.dx ||
|
|
706
|
+
params['amt-in'] ||
|
|
707
|
+
params['amt-in-max'] ||
|
|
708
|
+
params['y-amount'] ||
|
|
709
|
+
params['x-amount'] ||
|
|
710
|
+
params.dy,
|
|
711
|
+
dx:
|
|
712
|
+
params.amount ||
|
|
713
|
+
params.dx ||
|
|
714
|
+
params['amt-in'] ||
|
|
715
|
+
params['amt-in-max'] ||
|
|
716
|
+
params['y-amount'] ||
|
|
717
|
+
params['x-amount'] ||
|
|
718
|
+
params.dy,
|
|
719
|
+
'amt-in':
|
|
720
|
+
params.amount ||
|
|
721
|
+
params.dx ||
|
|
722
|
+
params['amt-in'] ||
|
|
723
|
+
params['amt-in-max'] ||
|
|
724
|
+
params['y-amount'] ||
|
|
725
|
+
params['x-amount'] ||
|
|
726
|
+
params.dy,
|
|
727
|
+
'amt-in-max':
|
|
728
|
+
params.amount ||
|
|
729
|
+
params.dx ||
|
|
730
|
+
params['amt-in'] ||
|
|
731
|
+
params['amt-in-max'] ||
|
|
732
|
+
params['y-amount'] ||
|
|
733
|
+
params['x-amount'] ||
|
|
734
|
+
params.dy,
|
|
735
|
+
'y-amount':
|
|
736
|
+
params.amount ||
|
|
737
|
+
params.dx ||
|
|
738
|
+
params['amt-in'] ||
|
|
739
|
+
params['amt-in-max'] ||
|
|
740
|
+
params['y-amount'] ||
|
|
741
|
+
params['x-amount'] ||
|
|
742
|
+
params.dy,
|
|
743
|
+
'x-amount':
|
|
744
|
+
params.amount ||
|
|
745
|
+
params.dx ||
|
|
746
|
+
params['amt-in'] ||
|
|
747
|
+
params['amt-in-max'] ||
|
|
748
|
+
params['y-amount'] ||
|
|
749
|
+
params['x-amount'] ||
|
|
750
|
+
params.dy,
|
|
751
|
+
'min-received': rawResult,
|
|
752
|
+
'min-dy': rawResult,
|
|
753
|
+
'min-dz': rawResult,
|
|
754
|
+
'min-dw': rawResult,
|
|
755
|
+
'amt-out': rawResult,
|
|
756
|
+
'amt-out-min': rawResult,
|
|
757
|
+
'min-x-amount': rawResult,
|
|
758
|
+
'min-dv': rawResult,
|
|
759
|
+
'min-y-amount': rawResult,
|
|
760
|
+
'min-dx': rawResult,
|
|
761
|
+
},
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
const quoteResult: RouteQuote = {
|
|
765
|
+
route: {
|
|
766
|
+
...route,
|
|
767
|
+
quoteData: updatedQuoteData,
|
|
768
|
+
swapData: updatedSwapData,
|
|
769
|
+
},
|
|
770
|
+
quote: convertedResult,
|
|
771
|
+
params: params,
|
|
772
|
+
quoteData: updatedQuoteData,
|
|
773
|
+
swapData: updatedSwapData,
|
|
774
|
+
dexPath: route.dex_path,
|
|
775
|
+
tokenPath: route.token_path,
|
|
776
|
+
tokenXDecimals: tokenXDecimals,
|
|
777
|
+
tokenYDecimals: tokenYDecimals,
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
allRoutes.push(quoteResult);
|
|
781
|
+
} else {
|
|
782
|
+
throw new Error('Invalid quote result');
|
|
783
|
+
}
|
|
784
|
+
} catch (error) {
|
|
785
|
+
console.warn(
|
|
786
|
+
`Failed to get quote for route ${routeIndex + 1}:`,
|
|
787
|
+
route,
|
|
788
|
+
error
|
|
789
|
+
);
|
|
790
|
+
allRoutes.push({
|
|
791
|
+
route,
|
|
792
|
+
quote: null,
|
|
793
|
+
params: route.quoteData
|
|
794
|
+
? { ...route.quoteData.parameters, amountInput }
|
|
795
|
+
: { amountInput },
|
|
796
|
+
quoteData: route.quoteData,
|
|
797
|
+
swapData: route.swapData,
|
|
798
|
+
dexPath: route.dex_path,
|
|
799
|
+
tokenPath: route.token_path,
|
|
800
|
+
tokenXDecimals: route.tokenXDecimals,
|
|
801
|
+
tokenYDecimals: route.tokenYDecimals,
|
|
802
|
+
error: (error as Error).message,
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
allRoutes.sort((a, b) => (b.quote || 0) - (a.quote || 0));
|
|
808
|
+
const result = {
|
|
809
|
+
bestRoute: allRoutes[0]?.quote !== null ? allRoutes[0] : null,
|
|
810
|
+
allRoutes,
|
|
811
|
+
inputData: { tokenX, tokenY, amountInput },
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
return result;
|
|
815
|
+
}
|
|
588
816
|
public async getSwapParams(
|
|
589
817
|
swapExecutionData: SwapExecutionData,
|
|
590
818
|
senderAddress: string,
|
|
@@ -602,42 +830,42 @@ export class BitflowSDK {
|
|
|
602
830
|
amount:
|
|
603
831
|
route.swapData.parameters.amount ||
|
|
604
832
|
amount ||
|
|
605
|
-
route.swapData.parameters[
|
|
606
|
-
route.swapData.parameters[
|
|
607
|
-
route.swapData.parameters[
|
|
833
|
+
route.swapData.parameters['amt-in'] ||
|
|
834
|
+
route.swapData.parameters['amt-in-max'] ||
|
|
835
|
+
route.swapData.parameters['y-amount'],
|
|
608
836
|
dx:
|
|
609
837
|
route.swapData.parameters.dx ||
|
|
610
838
|
amount ||
|
|
611
|
-
route.swapData.parameters[
|
|
612
|
-
route.swapData.parameters[
|
|
613
|
-
route.swapData.parameters[
|
|
614
|
-
|
|
839
|
+
route.swapData.parameters['amt-in'] ||
|
|
840
|
+
route.swapData.parameters['amt-in-max'] ||
|
|
841
|
+
route.swapData.parameters['y-amount'],
|
|
842
|
+
'amt-in':
|
|
615
843
|
route.swapData.parameters.dx ||
|
|
616
844
|
amount ||
|
|
617
|
-
route.swapData.parameters[
|
|
618
|
-
route.swapData.parameters[
|
|
619
|
-
route.swapData.parameters[
|
|
845
|
+
route.swapData.parameters['amt-in'] ||
|
|
846
|
+
route.swapData.parameters['amt-in-max'] ||
|
|
847
|
+
route.swapData.parameters['y-amount'] ||
|
|
620
848
|
route.swapData.parameters.dy,
|
|
621
|
-
|
|
849
|
+
'amt-in-max':
|
|
622
850
|
route.swapData.parameters.dx ||
|
|
623
851
|
amount ||
|
|
624
|
-
route.swapData.parameters[
|
|
625
|
-
route.swapData.parameters[
|
|
626
|
-
route.swapData.parameters[
|
|
852
|
+
route.swapData.parameters['amt-in'] ||
|
|
853
|
+
route.swapData.parameters['amt-in-max'] ||
|
|
854
|
+
route.swapData.parameters['y-amount'] ||
|
|
627
855
|
route.swapData.parameters.dy,
|
|
628
|
-
|
|
856
|
+
'y-amount':
|
|
629
857
|
route.swapData.parameters.dx ||
|
|
630
858
|
amount ||
|
|
631
|
-
route.swapData.parameters[
|
|
632
|
-
route.swapData.parameters[
|
|
633
|
-
route.swapData.parameters[
|
|
859
|
+
route.swapData.parameters['amt-in'] ||
|
|
860
|
+
route.swapData.parameters['amt-in-max'] ||
|
|
861
|
+
route.swapData.parameters['y-amount'] ||
|
|
634
862
|
route.swapData.parameters.dy,
|
|
635
863
|
dy:
|
|
636
864
|
route.swapData.parameters.dy ||
|
|
637
865
|
amount ||
|
|
638
|
-
route.swapData.parameters[
|
|
639
|
-
route.swapData.parameters[
|
|
640
|
-
route.swapData.parameters[
|
|
866
|
+
route.swapData.parameters['amt-in'] ||
|
|
867
|
+
route.swapData.parameters['amt-in-max'] ||
|
|
868
|
+
route.swapData.parameters['y-amount'] ||
|
|
641
869
|
route.swapData.parameters.dy,
|
|
642
870
|
},
|
|
643
871
|
},
|
|
@@ -669,11 +897,11 @@ export class BitflowSDK {
|
|
|
669
897
|
slippageTolerance
|
|
670
898
|
);
|
|
671
899
|
|
|
672
|
-
if (typeof window ===
|
|
900
|
+
if (typeof window === 'undefined') {
|
|
673
901
|
throw new Error(
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
902
|
+
'executeSwap is only available in browser environments. ' +
|
|
903
|
+
'For Node.js environments, use getSwapParams to get the transaction parameters ' +
|
|
904
|
+
'and handle the transaction execution separately.'
|
|
677
905
|
);
|
|
678
906
|
}
|
|
679
907
|
|
|
@@ -684,7 +912,7 @@ export class BitflowSDK {
|
|
|
684
912
|
} else {
|
|
685
913
|
const loadedProvider = await this.loadConnectDependencies();
|
|
686
914
|
if (!loadedProvider) {
|
|
687
|
-
throw new Error(
|
|
915
|
+
throw new Error('Failed to initialize Stacks provider');
|
|
688
916
|
}
|
|
689
917
|
provider = loadedProvider;
|
|
690
918
|
}
|
|
@@ -700,14 +928,14 @@ export class BitflowSDK {
|
|
|
700
928
|
} catch (error) {
|
|
701
929
|
if (
|
|
702
930
|
error instanceof Error &&
|
|
703
|
-
error.message.includes(
|
|
931
|
+
error.message.includes('only available in browser environments')
|
|
704
932
|
) {
|
|
705
933
|
throw error;
|
|
706
934
|
}
|
|
707
|
-
console.error(
|
|
935
|
+
console.error('Error executing swap:', error);
|
|
708
936
|
throw new Error(
|
|
709
937
|
`Failed to execute swap: ${
|
|
710
|
-
error instanceof Error ? error.message :
|
|
938
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
711
939
|
}`
|
|
712
940
|
);
|
|
713
941
|
}
|
|
@@ -731,7 +959,7 @@ export class BitflowSDK {
|
|
|
731
959
|
try {
|
|
732
960
|
return await getOrCreateKeeperContractAPI(params);
|
|
733
961
|
} catch (error) {
|
|
734
|
-
console.error(
|
|
962
|
+
console.error('Error in BitflowSDK.getOrCreateKeeperContract:', error);
|
|
735
963
|
throw error;
|
|
736
964
|
}
|
|
737
965
|
}
|
|
@@ -740,7 +968,7 @@ export class BitflowSDK {
|
|
|
740
968
|
try {
|
|
741
969
|
return await getOrderAPI(orderId);
|
|
742
970
|
} catch (error) {
|
|
743
|
-
console.error(
|
|
971
|
+
console.error('Error in BitflowSDK.getOrder:', error);
|
|
744
972
|
throw error;
|
|
745
973
|
}
|
|
746
974
|
}
|
|
@@ -749,7 +977,7 @@ export class BitflowSDK {
|
|
|
749
977
|
try {
|
|
750
978
|
return await getUserAPI(stacksAddress);
|
|
751
979
|
} catch (error) {
|
|
752
|
-
console.error(
|
|
980
|
+
console.error('Error in BitflowSDK.getUser:', error);
|
|
753
981
|
throw error;
|
|
754
982
|
}
|
|
755
983
|
}
|
|
@@ -760,7 +988,7 @@ export class BitflowSDK {
|
|
|
760
988
|
try {
|
|
761
989
|
return await createOrderAPI(params);
|
|
762
990
|
} catch (error) {
|
|
763
|
-
console.error(
|
|
991
|
+
console.error('Error in BitflowSDK.createOrder:', error);
|
|
764
992
|
throw error;
|
|
765
993
|
}
|
|
766
994
|
}
|
|
@@ -769,28 +997,11 @@ export class BitflowSDK {
|
|
|
769
997
|
try {
|
|
770
998
|
return await getQuoteAPI(params);
|
|
771
999
|
} catch (error) {
|
|
772
|
-
console.error(
|
|
1000
|
+
console.error('Error in BitflowSDK.getQuote:', error);
|
|
773
1001
|
throw error;
|
|
774
1002
|
}
|
|
775
1003
|
}
|
|
776
1004
|
|
|
777
|
-
private mapDexPathToActionTrait(dexPath: string[]): string {
|
|
778
|
-
const isXYK = dexPath.some((d) => d.toLowerCase().includes("xyk"));
|
|
779
|
-
const isStable = dexPath.some((d) => d.toLowerCase().includes("stable"));
|
|
780
|
-
|
|
781
|
-
if (isXYK && !isStable) {
|
|
782
|
-
return "SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-1-v-1-1";
|
|
783
|
-
}
|
|
784
|
-
if (isXYK && isStable) {
|
|
785
|
-
return "SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-2-v-1-1";
|
|
786
|
-
}
|
|
787
|
-
if (!isXYK && isStable) {
|
|
788
|
-
return "SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-3-v-1-1";
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
throw new Error(`Unsupported DEX path: ${dexPath.join(", ")}`);
|
|
792
|
-
}
|
|
793
|
-
|
|
794
1005
|
private async transformRouteToActionArgs(
|
|
795
1006
|
route: RouteQuote
|
|
796
1007
|
): Promise<ActionFunctionArgs> {
|
|
@@ -804,89 +1015,136 @@ export class BitflowSDK {
|
|
|
804
1015
|
const swapData = route.swapData;
|
|
805
1016
|
if (!swapData || !swapData.parameters) {
|
|
806
1017
|
throw new Error(
|
|
807
|
-
|
|
1018
|
+
'Invalid route data - missing swapData or swapData.parameters'
|
|
808
1019
|
);
|
|
809
1020
|
}
|
|
810
1021
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
1022
|
+
try {
|
|
1023
|
+
const availableTokens = await this.getAvailableTokens();
|
|
1024
|
+
const tokenPath = route.tokenPath;
|
|
1025
|
+
const expandedTokenPath: string[] = [];
|
|
814
1026
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
if (i > 0 && i < tokenPath.length - 1) {
|
|
1027
|
+
// Expand token path
|
|
1028
|
+
for (let i = 0; i < tokenPath.length - 1; i++) {
|
|
818
1029
|
expandedTokenPath.push(tokenPath[i]);
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
expandedTokenPath.push(tokenPath[tokenPath.length - 1]);
|
|
822
|
-
|
|
823
|
-
const tokenList: Record<string, string> = {};
|
|
824
|
-
expandedTokenPath.forEach((tokenId, index) => {
|
|
825
|
-
let contractIdentifier: string;
|
|
826
|
-
if (tokenId === "token-stx") {
|
|
827
|
-
contractIdentifier =
|
|
828
|
-
"SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.token-stx-v-1-2";
|
|
829
|
-
} else {
|
|
830
|
-
const token = availableTokens.find((t) => t.tokenId === tokenId);
|
|
831
|
-
if (!token || !token.tokenContract) {
|
|
832
|
-
throw new Error(
|
|
833
|
-
`Could not find contract identifier for token ${tokenId}`
|
|
834
|
-
);
|
|
1030
|
+
if (i > 0 && i < tokenPath.length - 1) {
|
|
1031
|
+
expandedTokenPath.push(tokenPath[i]);
|
|
835
1032
|
}
|
|
836
|
-
contractIdentifier = token.tokenContract;
|
|
837
1033
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
1034
|
+
expandedTokenPath.push(tokenPath[tokenPath.length - 1]);
|
|
1035
|
+
|
|
1036
|
+
// Map tokens to contract identifiers
|
|
1037
|
+
const tokenList: Record<string, string> = {};
|
|
1038
|
+
for (let index = 0; index < expandedTokenPath.length; index++) {
|
|
1039
|
+
const tokenId = expandedTokenPath[index];
|
|
1040
|
+
let contractIdentifier: string;
|
|
841
1041
|
|
|
842
|
-
|
|
1042
|
+
if (tokenId === 'token-stx') {
|
|
1043
|
+
contractIdentifier =
|
|
1044
|
+
'SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.token-stx-v-1-2';
|
|
1045
|
+
} else {
|
|
1046
|
+
const token = availableTokens.find((t) => t.tokenId === tokenId);
|
|
1047
|
+
if (!token || !token.tokenContract) {
|
|
1048
|
+
throw new Error(
|
|
1049
|
+
`Could not find contract identifier for token ${tokenId}`
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
contractIdentifier = token.tokenContract;
|
|
1053
|
+
}
|
|
843
1054
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
return { a: pools };
|
|
1055
|
+
const key = String.fromCharCode(97 + index); // 97 = 'a'
|
|
1056
|
+
tokenList[key] = contractIdentifier;
|
|
847
1057
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
1058
|
+
|
|
1059
|
+
actionFunctionArgs.tokenList = tokenList;
|
|
1060
|
+
|
|
1061
|
+
// Determine if this is a stableswap or XYK route
|
|
1062
|
+
const dexPath = route.dexPath;
|
|
1063
|
+
const isStableswapRoute = dexPath.some((path) =>
|
|
1064
|
+
path.toLowerCase().includes('stable')
|
|
1065
|
+
);
|
|
1066
|
+
|
|
1067
|
+
// Transform pool lists
|
|
1068
|
+
const transformPoolList = (pools: any): Record<string, string> => {
|
|
1069
|
+
if (typeof pools === 'string') {
|
|
1070
|
+
return { a: pools };
|
|
1071
|
+
}
|
|
1072
|
+
if (Array.isArray(pools)) {
|
|
1073
|
+
const poolObject: Record<string, string> = {};
|
|
1074
|
+
const letters = 'abcdefghijklmnopqrstuvwxyz';
|
|
1075
|
+
pools.forEach((pool, index) => {
|
|
1076
|
+
poolObject[letters[index]] = pool;
|
|
1077
|
+
});
|
|
1078
|
+
return poolObject;
|
|
1079
|
+
}
|
|
1080
|
+
if (typeof pools === 'object' && pools !== null) {
|
|
1081
|
+
return pools;
|
|
1082
|
+
}
|
|
1083
|
+
return {};
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
// Handle pools based on whether they're stableswap or XYK
|
|
1087
|
+
if (swapData.parameters['pool-trait']) {
|
|
1088
|
+
const poolIdentifier = swapData.parameters['pool-trait'];
|
|
1089
|
+
const transformedPool = transformPoolList(poolIdentifier);
|
|
1090
|
+
|
|
1091
|
+
// Check if the pool name contains 'stableswap'
|
|
1092
|
+
if (
|
|
1093
|
+
isStableswapRoute ||
|
|
1094
|
+
(typeof poolIdentifier === 'string' &&
|
|
1095
|
+
poolIdentifier.toLowerCase().includes('stableswap'))
|
|
1096
|
+
) {
|
|
1097
|
+
actionFunctionArgs.stableswapPoolList = transformedPool;
|
|
1098
|
+
} else {
|
|
1099
|
+
actionFunctionArgs.xykPoolList = transformedPool;
|
|
1100
|
+
}
|
|
1101
|
+
} else {
|
|
1102
|
+
// Handle specific pool types
|
|
1103
|
+
if (swapData.parameters['xyk-pools']) {
|
|
1104
|
+
actionFunctionArgs.xykPoolList = transformPoolList(
|
|
1105
|
+
swapData.parameters['xyk-pools']
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
if (swapData.parameters['stableswap-pools']) {
|
|
1110
|
+
actionFunctionArgs.stableswapPoolList = transformPoolList(
|
|
1111
|
+
swapData.parameters['stableswap-pools']
|
|
1112
|
+
);
|
|
1113
|
+
}
|
|
855
1114
|
}
|
|
856
|
-
|
|
857
|
-
|
|
1115
|
+
|
|
1116
|
+
if ('swaps-reversed' in swapData.parameters) {
|
|
1117
|
+
actionFunctionArgs.boolList = {
|
|
1118
|
+
a: swapData.parameters['swaps-reversed'].toString(),
|
|
1119
|
+
};
|
|
1120
|
+
} else {
|
|
1121
|
+
delete actionFunctionArgs.boolList;
|
|
858
1122
|
}
|
|
859
|
-
return {};
|
|
860
|
-
};
|
|
861
1123
|
|
|
862
|
-
|
|
863
|
-
actionFunctionArgs.
|
|
864
|
-
swapData.parameters["xyk-pools"]
|
|
865
|
-
);
|
|
866
|
-
} else if (swapData.parameters["pool-trait"]) {
|
|
867
|
-
actionFunctionArgs.xykPoolList = transformPoolList(
|
|
868
|
-
swapData.parameters["pool-trait"]
|
|
869
|
-
);
|
|
870
|
-
}
|
|
1124
|
+
const trait = this.mapDexPathToActionTrait(dexPath);
|
|
1125
|
+
actionFunctionArgs.actionTrait = trait;
|
|
871
1126
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
1127
|
+
return actionFunctionArgs;
|
|
1128
|
+
} catch (error) {
|
|
1129
|
+
throw error;
|
|
875
1130
|
}
|
|
1131
|
+
}
|
|
876
1132
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
};
|
|
881
|
-
} else {
|
|
882
|
-
delete actionFunctionArgs.boolList;
|
|
883
|
-
}
|
|
1133
|
+
private mapDexPathToActionTrait(dexPath: string[]): string {
|
|
1134
|
+
const isXYK = dexPath.some((d) => d.toLowerCase().includes('xyk'));
|
|
1135
|
+
const isStable = dexPath.some((d) => d.toLowerCase().includes('stable'));
|
|
884
1136
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
1137
|
+
if (isXYK && !isStable) {
|
|
1138
|
+
return 'SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-1-v-1-1';
|
|
1139
|
+
}
|
|
1140
|
+
if (isXYK && isStable) {
|
|
1141
|
+
return 'SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-2-v-1-1';
|
|
1142
|
+
}
|
|
1143
|
+
if (!isXYK && isStable) {
|
|
1144
|
+
return 'SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-3-v-1-1';
|
|
1145
|
+
}
|
|
888
1146
|
|
|
889
|
-
|
|
1147
|
+
throw new Error(`Unsupported DEX path: ${dexPath.join(', ')}`);
|
|
890
1148
|
}
|
|
891
1149
|
|
|
892
1150
|
public async getKeeperAggregatorRouteData(
|
|
@@ -894,28 +1152,33 @@ export class BitflowSDK {
|
|
|
894
1152
|
tokenY: string,
|
|
895
1153
|
amountX: number
|
|
896
1154
|
): Promise<ActionFunctionArgs> {
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
if (
|
|
904
|
-
!quoteResult ||
|
|
905
|
-
!quoteResult.allRoutes ||
|
|
906
|
-
quoteResult.allRoutes.length === 0
|
|
907
|
-
) {
|
|
908
|
-
throw new Error("No routes found");
|
|
909
|
-
}
|
|
1155
|
+
try {
|
|
1156
|
+
const quoteResult = await this.getKeeperQuoteForRouteWithoutScaling(
|
|
1157
|
+
tokenX,
|
|
1158
|
+
tokenY,
|
|
1159
|
+
amountX
|
|
1160
|
+
);
|
|
910
1161
|
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
1162
|
+
if (
|
|
1163
|
+
!quoteResult ||
|
|
1164
|
+
!quoteResult.allRoutes ||
|
|
1165
|
+
quoteResult.allRoutes.length === 0
|
|
1166
|
+
) {
|
|
1167
|
+
throw new Error('No routes found');
|
|
1168
|
+
}
|
|
915
1169
|
|
|
916
|
-
|
|
1170
|
+
const { bestRoute } = quoteResult;
|
|
1171
|
+
if (!bestRoute) {
|
|
1172
|
+
throw new Error('No best route found for keeper-compatible DEX paths');
|
|
1173
|
+
}
|
|
917
1174
|
|
|
918
|
-
|
|
1175
|
+
const actionFunctionArgs = await this.transformRouteToActionArgs(
|
|
1176
|
+
bestRoute
|
|
1177
|
+
);
|
|
1178
|
+
return actionFunctionArgs;
|
|
1179
|
+
} catch (error) {
|
|
1180
|
+
throw error;
|
|
1181
|
+
}
|
|
919
1182
|
}
|
|
920
1183
|
|
|
921
1184
|
public async createGroupOrder(
|
|
@@ -924,7 +1187,7 @@ export class BitflowSDK {
|
|
|
924
1187
|
try {
|
|
925
1188
|
return await createGroupOrderAPI(params);
|
|
926
1189
|
} catch (error) {
|
|
927
|
-
console.error(
|
|
1190
|
+
console.error('Error in BitflowSDK.createGroupOrder:', error);
|
|
928
1191
|
throw error;
|
|
929
1192
|
}
|
|
930
1193
|
}
|
|
@@ -936,7 +1199,7 @@ export class BitflowSDK {
|
|
|
936
1199
|
try {
|
|
937
1200
|
return await getGroupOrderAPI(groupId, includeOrders);
|
|
938
1201
|
} catch (error) {
|
|
939
|
-
console.error(
|
|
1202
|
+
console.error('Error in BitflowSDK.getGroupOrder:', error);
|
|
940
1203
|
throw error;
|
|
941
1204
|
}
|
|
942
1205
|
}
|
|
@@ -945,7 +1208,7 @@ export class BitflowSDK {
|
|
|
945
1208
|
try {
|
|
946
1209
|
return await cancelOrderAPI(orderId);
|
|
947
1210
|
} catch (error) {
|
|
948
|
-
console.error(
|
|
1211
|
+
console.error('Error in BitflowSDK.cancelOrder:', error);
|
|
949
1212
|
throw error;
|
|
950
1213
|
}
|
|
951
1214
|
}
|
|
@@ -956,7 +1219,7 @@ export class BitflowSDK {
|
|
|
956
1219
|
try {
|
|
957
1220
|
return await cancelGroupOrderAPI(groupId);
|
|
958
1221
|
} catch (error) {
|
|
959
|
-
console.error(
|
|
1222
|
+
console.error('Error in BitflowSDK.cancelGroupOrder:', error);
|
|
960
1223
|
throw error;
|
|
961
1224
|
}
|
|
962
1225
|
}
|