@bitflowlabs/core-sdk 1.0.1 → 2.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/dist/src/BitflowSDK.d.ts +23 -2
- package/dist/src/BitflowSDK.js +536 -82
- package/dist/src/BitflowSDK.js.map +1 -1
- package/dist/src/config.d.ts +1 -1
- package/dist/src/config.js +6 -4
- package/dist/src/config.js.map +1 -1
- package/dist/src/helpers/callReadOnlyHelper.js +10 -4
- package/dist/src/helpers/callReadOnlyHelper.js.map +1 -1
- package/dist/src/helpers/callSwapHelper.d.ts +2 -2
- package/dist/src/helpers/callSwapHelper.js +48 -7
- package/dist/src/helpers/callSwapHelper.js.map +1 -1
- package/dist/src/helpers/fetchDataHelper.d.ts +1 -1
- package/dist/src/helpers/fetchDataHelper.js +50 -17
- package/dist/src/helpers/fetchDataHelper.js.map +1 -1
- package/dist/src/helpers/fetchPossibleSwap.d.ts +2 -2
- package/dist/src/helpers/fetchPossibleSwap.js +10 -2
- package/dist/src/helpers/fetchPossibleSwap.js.map +1 -1
- package/dist/src/helpers/handleResultHelper.js +15 -15
- package/dist/src/helpers/handleResultHelper.js.map +1 -1
- package/dist/src/helpers/newPostConditionsHelper.d.ts +2 -0
- package/dist/src/helpers/newPostConditionsHelper.js +145 -0
- package/dist/src/helpers/newPostConditionsHelper.js.map +1 -0
- package/dist/src/helpers/postConditionsHelper.js +38 -13
- package/dist/src/helpers/postConditionsHelper.js.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/keeper/keeperAPI.d.ts +10 -0
- package/dist/src/keeper/keeperAPI.js +332 -0
- package/dist/src/keeper/keeperAPI.js.map +1 -0
- package/dist/src/keeper/types.d.ts +253 -0
- package/dist/src/keeper/types.js +65 -0
- package/dist/src/keeper/types.js.map +1 -0
- package/dist/src/test-keeper-routes.d.ts +1 -0
- package/dist/src/test-keeper-routes.js +67 -0
- package/dist/src/test-keeper-routes.js.map +1 -0
- package/dist/src/test-raw-token-response.d.ts +1 -0
- package/dist/src/test-raw-token-response.js +79 -0
- package/dist/src/test-raw-token-response.js.map +1 -0
- package/dist/src/test-sdk.d.ts +1 -0
- package/dist/src/test-sdk.js +229 -0
- package/dist/src/test-sdk.js.map +1 -0
- package/dist/src/test-token.fetch.d.ts +1 -0
- package/dist/src/test-token.fetch.js +63 -0
- package/dist/src/test-token.fetch.js.map +1 -0
- package/dist/src/types.d.ts +27 -2
- package/package.json +6 -5
- package/src/BitflowSDK.ts +675 -97
- package/src/config.ts +9 -6
- package/src/helpers/callReadOnlyHelper.ts +12 -7
- package/src/helpers/callSwapHelper.ts +21 -7
- package/src/helpers/fetchDataHelper.ts +58 -19
- package/src/helpers/fetchPossibleSwap.ts +18 -4
- package/src/helpers/handleResultHelper.ts +17 -16
- package/src/helpers/newPostConditionsHelper.ts +172 -0
- package/src/helpers/postConditionsHelper.ts +71 -19
- package/src/index.ts +3 -2
- package/src/keeper/keeperAPI.ts +435 -0
- package/src/keeper/types.ts +293 -0
- package/src/test-keeper-routes.ts +76 -0
- package/src/test-raw-token-response.ts +124 -0
- package/src/test-sdk.ts +262 -0
- package/src/test-token.fetch.ts +72 -0
- package/src/types.ts +29 -2
package/dist/src/BitflowSDK.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.BitflowSDK = void 0;
|
|
4
37
|
const network_1 = require("@stacks/network");
|
|
@@ -9,6 +42,7 @@ const fetchPossibleSwap_1 = require("./helpers/fetchPossibleSwap");
|
|
|
9
42
|
const getContractInterfaceAndFunction_1 = require("./helpers/getContractInterfaceAndFunction");
|
|
10
43
|
const config_1 = require("./config");
|
|
11
44
|
const callGetSwapParams_1 = require("./helpers/callGetSwapParams");
|
|
45
|
+
const keeperAPI_1 = require("./keeper/keeperAPI");
|
|
12
46
|
class BitflowSDK {
|
|
13
47
|
constructor(config) {
|
|
14
48
|
if (config)
|
|
@@ -18,11 +52,27 @@ class BitflowSDK {
|
|
|
18
52
|
availableTokens: [],
|
|
19
53
|
contractInterfaces: {},
|
|
20
54
|
functionArgs: {},
|
|
21
|
-
network:
|
|
55
|
+
network: network_1.STACKS_MAINNET,
|
|
22
56
|
swapOptions: {},
|
|
23
57
|
};
|
|
24
58
|
this.initializeContext();
|
|
25
59
|
}
|
|
60
|
+
async loadConnectDependencies() {
|
|
61
|
+
if (typeof window === "undefined") {
|
|
62
|
+
throw new Error("Connect features are only available in browser environments");
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const { getStacksProvider } = await Promise.resolve().then(() => __importStar(require("@stacks/connect")));
|
|
66
|
+
if (!this.stacksProvider) {
|
|
67
|
+
this.stacksProvider = await getStacksProvider();
|
|
68
|
+
}
|
|
69
|
+
return this.stacksProvider;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.error("Error loading Stacks Connect:", error);
|
|
73
|
+
throw new Error("Failed to load Stacks Connect dependencies");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
26
76
|
async initializeContext() {
|
|
27
77
|
this.context.availableTokens = await (0, fetchDataHelper_1.fetchAllTokensFromAPI)();
|
|
28
78
|
}
|
|
@@ -32,20 +82,42 @@ class BitflowSDK {
|
|
|
32
82
|
}
|
|
33
83
|
return this.context.availableTokens;
|
|
34
84
|
}
|
|
85
|
+
async getKeeperTokens() {
|
|
86
|
+
if (this.context.availableTokens.length === 0) {
|
|
87
|
+
await this.initializeContext();
|
|
88
|
+
}
|
|
89
|
+
return this.context.availableTokens.filter((token) => token.isKeeperToken);
|
|
90
|
+
}
|
|
35
91
|
async getPossibleSwaps(tokenX) {
|
|
36
92
|
if (!this.context.swapOptions[tokenX]) {
|
|
37
93
|
this.context.swapOptions[tokenX] = await (0, fetchPossibleSwap_1.fetchPossibleSwapsFromAPI)(tokenX);
|
|
38
94
|
}
|
|
39
95
|
return this.context.swapOptions[tokenX];
|
|
40
96
|
}
|
|
97
|
+
async getKeeperPossibleSwaps(tokenX) {
|
|
98
|
+
// Use a separate cache key for keeper routes
|
|
99
|
+
const cacheKey = `keeper_${tokenX}`;
|
|
100
|
+
if (!this.context.swapOptions[cacheKey]) {
|
|
101
|
+
this.context.swapOptions[cacheKey] = await (0, fetchPossibleSwap_1.fetchPossibleSwapsFromAPI)(tokenX, "KEEPER");
|
|
102
|
+
}
|
|
103
|
+
return this.context.swapOptions[cacheKey];
|
|
104
|
+
}
|
|
41
105
|
async getAllPossibleTokenY(tokenX) {
|
|
42
106
|
const swapOptions = await this.getPossibleSwaps(tokenX);
|
|
43
107
|
return Object.keys(swapOptions);
|
|
44
108
|
}
|
|
109
|
+
async getAllKeeperPossibleTokenY(tokenX) {
|
|
110
|
+
const swapOptions = await this.getKeeperPossibleSwaps(tokenX);
|
|
111
|
+
return Object.keys(swapOptions);
|
|
112
|
+
}
|
|
45
113
|
async getAllPossibleTokenYRoutes(tokenX, tokenY) {
|
|
46
114
|
const swapOptions = await this.getPossibleSwaps(tokenX);
|
|
47
115
|
return swapOptions[tokenY] || [];
|
|
48
116
|
}
|
|
117
|
+
async getAllKeeperPossibleTokenYRoutes(tokenX, tokenY) {
|
|
118
|
+
const swapOptions = await this.getKeeperPossibleSwaps(tokenX);
|
|
119
|
+
return swapOptions[tokenY] || [];
|
|
120
|
+
}
|
|
49
121
|
async getQuoteForRoute(tokenX, tokenY, amountInput) {
|
|
50
122
|
var _a;
|
|
51
123
|
const routes = await this.getAllPossibleTokenYRoutes(tokenX, tokenY);
|
|
@@ -53,51 +125,49 @@ class BitflowSDK {
|
|
|
53
125
|
for (let routeIndex = 0; routeIndex < routes.length; routeIndex++) {
|
|
54
126
|
const route = routes[routeIndex];
|
|
55
127
|
try {
|
|
56
|
-
// Check if quoteData is null or undefined
|
|
57
128
|
if (!route.quoteData) {
|
|
58
129
|
console.warn(`Skipping route ${routeIndex + 1} due to null quoteData:`, route);
|
|
59
130
|
continue;
|
|
60
131
|
}
|
|
61
132
|
const { contract, function: functionName, parameters, } = route.quoteData;
|
|
62
|
-
// Check if any required property is missing
|
|
63
133
|
if (!contract || !functionName || !parameters) {
|
|
64
134
|
console.warn(`Skipping route ${routeIndex + 1} due to missing required properties:`, route.quoteData);
|
|
65
135
|
continue;
|
|
66
136
|
}
|
|
67
|
-
const [contractDeployer, contractName] = contract.split(
|
|
137
|
+
const [contractDeployer, contractName] = contract.split(".");
|
|
68
138
|
if (!this.context.contractInterfaces[contract]) {
|
|
69
139
|
this.context.contractInterfaces[contract] =
|
|
70
140
|
await (0, getContractInterfaceAndFunction_1.getContractInterfaceAndFunction)(contractDeployer, contractName, functionName);
|
|
71
141
|
}
|
|
72
142
|
const { interface: contractInterface, functionArgs } = this.context.contractInterfaces[contract];
|
|
73
143
|
const params = { ...parameters };
|
|
74
|
-
if (
|
|
144
|
+
if ("dx" in params && params.dx === null) {
|
|
75
145
|
params.dx = amountInput;
|
|
76
146
|
}
|
|
77
|
-
else if (
|
|
147
|
+
else if ("dy" in params && params.dy === null) {
|
|
78
148
|
params.dy = amountInput;
|
|
79
149
|
}
|
|
80
|
-
else if (
|
|
150
|
+
else if ("amount" in params && params.amount === null) {
|
|
81
151
|
params.amount = amountInput;
|
|
82
152
|
}
|
|
83
|
-
else if (
|
|
84
|
-
params[
|
|
153
|
+
else if ("amt-in" in params && params["amt-in"] === null) {
|
|
154
|
+
params["amt-in"] = amountInput;
|
|
85
155
|
}
|
|
86
|
-
else if (
|
|
87
|
-
params[
|
|
156
|
+
else if ("amt-in-max" in params && params["amt-in-max"] === null) {
|
|
157
|
+
params["amt-in-max"] = amountInput;
|
|
88
158
|
}
|
|
89
|
-
else if (
|
|
90
|
-
params[
|
|
91
|
-
params[
|
|
159
|
+
else if ("y-amount" in params && params["y-amount"] === null) {
|
|
160
|
+
params["y-amount"] = amountInput;
|
|
161
|
+
params["x-amount"] = amountInput;
|
|
92
162
|
}
|
|
93
|
-
else if (
|
|
94
|
-
params[
|
|
163
|
+
else if ("x-amount" in params && params["x-amount"] === null) {
|
|
164
|
+
params["x-amount"] = amountInput;
|
|
95
165
|
}
|
|
96
166
|
else {
|
|
97
167
|
params.dx = amountInput;
|
|
98
168
|
}
|
|
99
169
|
const { convertedResult, rawResult, tokenXDecimals, tokenYDecimals } = await (0, callReadOnlyHelper_1.callReadOnlyFunctionHelper)(contractDeployer, contractName, functionName, params, contractDeployer, tokenX, tokenY, route.swapData, this.context);
|
|
100
|
-
if (typeof convertedResult ===
|
|
170
|
+
if (typeof convertedResult === "number" && convertedResult > 0) {
|
|
101
171
|
const updatedQuoteData = {
|
|
102
172
|
...route.quoteData,
|
|
103
173
|
parameters: { ...params },
|
|
@@ -108,63 +178,63 @@ class BitflowSDK {
|
|
|
108
178
|
...route.swapData.parameters,
|
|
109
179
|
amount: params.amount ||
|
|
110
180
|
params.dx ||
|
|
111
|
-
params[
|
|
112
|
-
params[
|
|
113
|
-
params[
|
|
114
|
-
params[
|
|
181
|
+
params["amt-in"] ||
|
|
182
|
+
params["amt-in-max"] ||
|
|
183
|
+
params["y-amount"] ||
|
|
184
|
+
params["x-amount"] ||
|
|
115
185
|
params.dy,
|
|
116
186
|
dx: params.amount ||
|
|
117
187
|
params.dx ||
|
|
118
|
-
params[
|
|
119
|
-
params[
|
|
120
|
-
params[
|
|
121
|
-
params[
|
|
188
|
+
params["amt-in"] ||
|
|
189
|
+
params["amt-in-max"] ||
|
|
190
|
+
params["y-amount"] ||
|
|
191
|
+
params["x-amount"] ||
|
|
122
192
|
params.dy,
|
|
123
193
|
dy: params.amount ||
|
|
124
194
|
params.dx ||
|
|
125
|
-
params[
|
|
126
|
-
params[
|
|
127
|
-
params[
|
|
128
|
-
params[
|
|
195
|
+
params["amt-in"] ||
|
|
196
|
+
params["amt-in-max"] ||
|
|
197
|
+
params["y-amount"] ||
|
|
198
|
+
params["x-amount"] ||
|
|
129
199
|
params.dy,
|
|
130
|
-
|
|
200
|
+
"amt-in": params.amount ||
|
|
131
201
|
params.dx ||
|
|
132
|
-
params[
|
|
133
|
-
params[
|
|
134
|
-
params[
|
|
135
|
-
params[
|
|
202
|
+
params["amt-in"] ||
|
|
203
|
+
params["amt-in-max"] ||
|
|
204
|
+
params["y-amount"] ||
|
|
205
|
+
params["x-amount"] ||
|
|
136
206
|
params.dy,
|
|
137
|
-
|
|
207
|
+
"amt-in-max": params.amount ||
|
|
138
208
|
params.dx ||
|
|
139
|
-
params[
|
|
140
|
-
params[
|
|
141
|
-
params[
|
|
142
|
-
params[
|
|
209
|
+
params["amt-in"] ||
|
|
210
|
+
params["amt-in-max"] ||
|
|
211
|
+
params["y-amount"] ||
|
|
212
|
+
params["x-amount"] ||
|
|
143
213
|
params.dy,
|
|
144
|
-
|
|
214
|
+
"y-amount": params.amount ||
|
|
145
215
|
params.dx ||
|
|
146
|
-
params[
|
|
147
|
-
params[
|
|
148
|
-
params[
|
|
149
|
-
params[
|
|
216
|
+
params["amt-in"] ||
|
|
217
|
+
params["amt-in-max"] ||
|
|
218
|
+
params["y-amount"] ||
|
|
219
|
+
params["x-amount"] ||
|
|
150
220
|
params.dy,
|
|
151
|
-
|
|
221
|
+
"x-amount": params.amount ||
|
|
152
222
|
params.dx ||
|
|
153
|
-
params[
|
|
154
|
-
params[
|
|
155
|
-
params[
|
|
156
|
-
params[
|
|
223
|
+
params["amt-in"] ||
|
|
224
|
+
params["amt-in-max"] ||
|
|
225
|
+
params["y-amount"] ||
|
|
226
|
+
params["x-amount"] ||
|
|
157
227
|
params.dy,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
228
|
+
"min-received": rawResult,
|
|
229
|
+
"min-dy": rawResult,
|
|
230
|
+
"min-dz": rawResult,
|
|
231
|
+
"min-dw": rawResult,
|
|
232
|
+
"amt-out": rawResult,
|
|
233
|
+
"amt-out-min": rawResult,
|
|
234
|
+
"min-x-amount": rawResult,
|
|
235
|
+
"min-dv": rawResult,
|
|
236
|
+
"min-y-amount": rawResult,
|
|
237
|
+
"min-dx": rawResult,
|
|
168
238
|
},
|
|
169
239
|
};
|
|
170
240
|
const quoteResult = {
|
|
@@ -185,7 +255,174 @@ class BitflowSDK {
|
|
|
185
255
|
allRoutes.push(quoteResult);
|
|
186
256
|
}
|
|
187
257
|
else {
|
|
188
|
-
throw new Error(
|
|
258
|
+
throw new Error("Invalid quote result");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
console.warn(`Failed to get quote for route ${routeIndex + 1}:`, route, error);
|
|
263
|
+
allRoutes.push({
|
|
264
|
+
route,
|
|
265
|
+
quote: null,
|
|
266
|
+
params: route.quoteData
|
|
267
|
+
? { ...route.quoteData.parameters, amountInput }
|
|
268
|
+
: { amountInput },
|
|
269
|
+
quoteData: route.quoteData,
|
|
270
|
+
swapData: route.swapData,
|
|
271
|
+
dexPath: route.dex_path,
|
|
272
|
+
tokenPath: route.token_path,
|
|
273
|
+
tokenXDecimals: route.tokenXDecimals,
|
|
274
|
+
tokenYDecimals: route.tokenYDecimals,
|
|
275
|
+
error: error.message,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
allRoutes.sort((a, b) => (b.quote || 0) - (a.quote || 0));
|
|
280
|
+
const result = {
|
|
281
|
+
bestRoute: ((_a = allRoutes[0]) === null || _a === void 0 ? void 0 : _a.quote) !== null ? allRoutes[0] : null,
|
|
282
|
+
allRoutes,
|
|
283
|
+
inputData: { tokenX, tokenY, amountInput },
|
|
284
|
+
};
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
async getKeeperQuoteForRoute(tokenX, tokenY, amountInput) {
|
|
288
|
+
var _a;
|
|
289
|
+
const COMPATIBLE_DEX_PATHS = new Set([
|
|
290
|
+
"BITFLOW_STABLE_XY_2",
|
|
291
|
+
"BITFLOW_XYK_XY_2",
|
|
292
|
+
]);
|
|
293
|
+
const isCompatibleRoute = (dexPath) => {
|
|
294
|
+
return dexPath.every((path) => COMPATIBLE_DEX_PATHS.has(path));
|
|
295
|
+
};
|
|
296
|
+
let routes = await this.getAllPossibleTokenYRoutes(tokenX, tokenY);
|
|
297
|
+
routes = routes.filter((route) => isCompatibleRoute(route.dex_path));
|
|
298
|
+
const allRoutes = [];
|
|
299
|
+
for (let routeIndex = 0; routeIndex < routes.length; routeIndex++) {
|
|
300
|
+
const route = routes[routeIndex];
|
|
301
|
+
try {
|
|
302
|
+
if (!route.quoteData) {
|
|
303
|
+
console.warn(`Skipping route ${routeIndex + 1} due to null quoteData:`, route);
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
const { contract, function: functionName, parameters, } = route.quoteData;
|
|
307
|
+
if (!contract || !functionName || !parameters) {
|
|
308
|
+
console.warn(`Skipping route ${routeIndex + 1} due to missing required properties:`, route.quoteData);
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const [contractDeployer, contractName] = contract.split(".");
|
|
312
|
+
if (!this.context.contractInterfaces[contract]) {
|
|
313
|
+
this.context.contractInterfaces[contract] =
|
|
314
|
+
await (0, getContractInterfaceAndFunction_1.getContractInterfaceAndFunction)(contractDeployer, contractName, functionName);
|
|
315
|
+
}
|
|
316
|
+
const { interface: contractInterface, functionArgs } = this.context.contractInterfaces[contract];
|
|
317
|
+
const params = { ...parameters };
|
|
318
|
+
if ("dx" in params && params.dx === null) {
|
|
319
|
+
params.dx = amountInput;
|
|
320
|
+
}
|
|
321
|
+
else if ("dy" in params && params.dy === null) {
|
|
322
|
+
params.dy = amountInput;
|
|
323
|
+
}
|
|
324
|
+
else if ("amount" in params && params.amount === null) {
|
|
325
|
+
params.amount = amountInput;
|
|
326
|
+
}
|
|
327
|
+
else if ("amt-in" in params && params["amt-in"] === null) {
|
|
328
|
+
params["amt-in"] = amountInput;
|
|
329
|
+
}
|
|
330
|
+
else if ("amt-in-max" in params && params["amt-in-max"] === null) {
|
|
331
|
+
params["amt-in-max"] = amountInput;
|
|
332
|
+
}
|
|
333
|
+
else if ("y-amount" in params && params["y-amount"] === null) {
|
|
334
|
+
params["y-amount"] = amountInput;
|
|
335
|
+
params["x-amount"] = amountInput;
|
|
336
|
+
}
|
|
337
|
+
else if ("x-amount" in params && params["x-amount"] === null) {
|
|
338
|
+
params["x-amount"] = amountInput;
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
params.dx = amountInput;
|
|
342
|
+
}
|
|
343
|
+
const { convertedResult, rawResult, tokenXDecimals, tokenYDecimals } = await (0, callReadOnlyHelper_1.callReadOnlyFunctionHelper)(contractDeployer, contractName, functionName, params, contractDeployer, tokenX, tokenY, route.swapData, this.context);
|
|
344
|
+
if (typeof convertedResult === "number" && convertedResult > 0) {
|
|
345
|
+
const updatedQuoteData = {
|
|
346
|
+
...route.quoteData,
|
|
347
|
+
parameters: { ...params },
|
|
348
|
+
};
|
|
349
|
+
const updatedSwapData = {
|
|
350
|
+
...route.swapData,
|
|
351
|
+
parameters: {
|
|
352
|
+
...route.swapData.parameters,
|
|
353
|
+
amount: params.amount ||
|
|
354
|
+
params.dx ||
|
|
355
|
+
params["amt-in"] ||
|
|
356
|
+
params["amt-in-max"] ||
|
|
357
|
+
params["y-amount"] ||
|
|
358
|
+
params["x-amount"] ||
|
|
359
|
+
params.dy,
|
|
360
|
+
dx: params.amount ||
|
|
361
|
+
params.dx ||
|
|
362
|
+
params["amt-in"] ||
|
|
363
|
+
params["amt-in-max"] ||
|
|
364
|
+
params["y-amount"] ||
|
|
365
|
+
params["x-amount"] ||
|
|
366
|
+
params.dy,
|
|
367
|
+
"amt-in": params.amount ||
|
|
368
|
+
params.dx ||
|
|
369
|
+
params["amt-in"] ||
|
|
370
|
+
params["amt-in-max"] ||
|
|
371
|
+
params["y-amount"] ||
|
|
372
|
+
params["x-amount"] ||
|
|
373
|
+
params.dy,
|
|
374
|
+
"amt-in-max": params.amount ||
|
|
375
|
+
params.dx ||
|
|
376
|
+
params["amt-in"] ||
|
|
377
|
+
params["amt-in-max"] ||
|
|
378
|
+
params["y-amount"] ||
|
|
379
|
+
params["x-amount"] ||
|
|
380
|
+
params.dy,
|
|
381
|
+
"y-amount": params.amount ||
|
|
382
|
+
params.dx ||
|
|
383
|
+
params["amt-in"] ||
|
|
384
|
+
params["amt-in-max"] ||
|
|
385
|
+
params["y-amount"] ||
|
|
386
|
+
params["x-amount"] ||
|
|
387
|
+
params.dy,
|
|
388
|
+
"x-amount": params.amount ||
|
|
389
|
+
params.dx ||
|
|
390
|
+
params["amt-in"] ||
|
|
391
|
+
params["amt-in-max"] ||
|
|
392
|
+
params["y-amount"] ||
|
|
393
|
+
params["x-amount"] ||
|
|
394
|
+
params.dy,
|
|
395
|
+
"min-received": rawResult,
|
|
396
|
+
"min-dy": rawResult,
|
|
397
|
+
"min-dz": rawResult,
|
|
398
|
+
"min-dw": rawResult,
|
|
399
|
+
"amt-out": rawResult,
|
|
400
|
+
"amt-out-min": rawResult,
|
|
401
|
+
"min-x-amount": rawResult,
|
|
402
|
+
"min-dv": rawResult,
|
|
403
|
+
"min-y-amount": rawResult,
|
|
404
|
+
"min-dx": rawResult,
|
|
405
|
+
},
|
|
406
|
+
};
|
|
407
|
+
const quoteResult = {
|
|
408
|
+
route: {
|
|
409
|
+
...route,
|
|
410
|
+
quoteData: updatedQuoteData,
|
|
411
|
+
swapData: updatedSwapData,
|
|
412
|
+
},
|
|
413
|
+
quote: convertedResult,
|
|
414
|
+
params: params,
|
|
415
|
+
quoteData: updatedQuoteData,
|
|
416
|
+
swapData: updatedSwapData,
|
|
417
|
+
dexPath: route.dex_path,
|
|
418
|
+
tokenPath: route.token_path,
|
|
419
|
+
tokenXDecimals: tokenXDecimals,
|
|
420
|
+
tokenYDecimals: tokenYDecimals,
|
|
421
|
+
};
|
|
422
|
+
allRoutes.push(quoteResult);
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
throw new Error("Invalid quote result");
|
|
189
426
|
}
|
|
190
427
|
}
|
|
191
428
|
catch (error) {
|
|
@@ -225,37 +462,37 @@ class BitflowSDK {
|
|
|
225
462
|
...route.swapData.parameters,
|
|
226
463
|
amount: route.swapData.parameters.amount ||
|
|
227
464
|
amount ||
|
|
228
|
-
route.swapData.parameters[
|
|
229
|
-
route.swapData.parameters[
|
|
230
|
-
route.swapData.parameters[
|
|
465
|
+
route.swapData.parameters["amt-in"] ||
|
|
466
|
+
route.swapData.parameters["amt-in-max"] ||
|
|
467
|
+
route.swapData.parameters["y-amount"],
|
|
231
468
|
dx: route.swapData.parameters.dx ||
|
|
232
469
|
amount ||
|
|
233
|
-
route.swapData.parameters[
|
|
234
|
-
route.swapData.parameters[
|
|
235
|
-
route.swapData.parameters[
|
|
236
|
-
|
|
470
|
+
route.swapData.parameters["amt-in"] ||
|
|
471
|
+
route.swapData.parameters["amt-in-max"] ||
|
|
472
|
+
route.swapData.parameters["y-amount"],
|
|
473
|
+
"amt-in": route.swapData.parameters.dx ||
|
|
237
474
|
amount ||
|
|
238
|
-
route.swapData.parameters[
|
|
239
|
-
route.swapData.parameters[
|
|
240
|
-
route.swapData.parameters[
|
|
475
|
+
route.swapData.parameters["amt-in"] ||
|
|
476
|
+
route.swapData.parameters["amt-in-max"] ||
|
|
477
|
+
route.swapData.parameters["y-amount"] ||
|
|
241
478
|
route.swapData.parameters.dy,
|
|
242
|
-
|
|
479
|
+
"amt-in-max": route.swapData.parameters.dx ||
|
|
243
480
|
amount ||
|
|
244
|
-
route.swapData.parameters[
|
|
245
|
-
route.swapData.parameters[
|
|
246
|
-
route.swapData.parameters[
|
|
481
|
+
route.swapData.parameters["amt-in"] ||
|
|
482
|
+
route.swapData.parameters["amt-in-max"] ||
|
|
483
|
+
route.swapData.parameters["y-amount"] ||
|
|
247
484
|
route.swapData.parameters.dy,
|
|
248
|
-
|
|
485
|
+
"y-amount": route.swapData.parameters.dx ||
|
|
249
486
|
amount ||
|
|
250
|
-
route.swapData.parameters[
|
|
251
|
-
route.swapData.parameters[
|
|
252
|
-
route.swapData.parameters[
|
|
487
|
+
route.swapData.parameters["amt-in"] ||
|
|
488
|
+
route.swapData.parameters["amt-in-max"] ||
|
|
489
|
+
route.swapData.parameters["y-amount"] ||
|
|
253
490
|
route.swapData.parameters.dy,
|
|
254
491
|
dy: route.swapData.parameters.dy ||
|
|
255
492
|
amount ||
|
|
256
|
-
route.swapData.parameters[
|
|
257
|
-
route.swapData.parameters[
|
|
258
|
-
route.swapData.parameters[
|
|
493
|
+
route.swapData.parameters["amt-in"] ||
|
|
494
|
+
route.swapData.parameters["amt-in-max"] ||
|
|
495
|
+
route.swapData.parameters["y-amount"] ||
|
|
259
496
|
route.swapData.parameters.dy,
|
|
260
497
|
},
|
|
261
498
|
},
|
|
@@ -268,7 +505,224 @@ class BitflowSDK {
|
|
|
268
505
|
}
|
|
269
506
|
async executeSwap(swapExecutionData, senderAddress, slippageTolerance = 0.015, stacksProvider, onFinish, onCancel) {
|
|
270
507
|
const swapParams = await this.getSwapParams(swapExecutionData, senderAddress, slippageTolerance);
|
|
271
|
-
|
|
508
|
+
if (typeof window === "undefined") {
|
|
509
|
+
throw new Error("executeSwap is only available in browser environments. " +
|
|
510
|
+
"For Node.js environments, use getSwapParams to get the transaction parameters " +
|
|
511
|
+
"and handle the transaction execution separately.");
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
let provider;
|
|
515
|
+
if (stacksProvider) {
|
|
516
|
+
provider = stacksProvider;
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
const loadedProvider = await this.loadConnectDependencies();
|
|
520
|
+
if (!loadedProvider) {
|
|
521
|
+
throw new Error("Failed to initialize Stacks provider");
|
|
522
|
+
}
|
|
523
|
+
provider = loadedProvider;
|
|
524
|
+
}
|
|
525
|
+
await (0, callSwapHelper_1.executeSwapHelper)(swapParams, senderAddress, this.context, provider, onFinish, onCancel);
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
if (error instanceof Error &&
|
|
529
|
+
error.message.includes("only available in browser environments")) {
|
|
530
|
+
throw error;
|
|
531
|
+
}
|
|
532
|
+
console.error("Error executing swap:", error);
|
|
533
|
+
throw new Error(`Failed to execute swap: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
async prepareSwap(swapExecutionData, senderAddress, slippageTolerance = 0.015) {
|
|
537
|
+
return await this.getSwapParams(swapExecutionData, senderAddress, slippageTolerance);
|
|
538
|
+
}
|
|
539
|
+
async getOrCreateKeeperContract(params) {
|
|
540
|
+
try {
|
|
541
|
+
return await (0, keeperAPI_1.getOrCreateKeeperContractAPI)(params);
|
|
542
|
+
}
|
|
543
|
+
catch (error) {
|
|
544
|
+
console.error("Error in BitflowSDK.getOrCreateKeeperContract:", error);
|
|
545
|
+
throw error;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
async getOrder(orderId) {
|
|
549
|
+
try {
|
|
550
|
+
return await (0, keeperAPI_1.getOrderAPI)(orderId);
|
|
551
|
+
}
|
|
552
|
+
catch (error) {
|
|
553
|
+
console.error("Error in BitflowSDK.getOrder:", error);
|
|
554
|
+
throw error;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
async getUser(stacksAddress) {
|
|
558
|
+
try {
|
|
559
|
+
return await (0, keeperAPI_1.getUserAPI)(stacksAddress);
|
|
560
|
+
}
|
|
561
|
+
catch (error) {
|
|
562
|
+
console.error("Error in BitflowSDK.getUser:", error);
|
|
563
|
+
throw error;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
async createOrder(params) {
|
|
567
|
+
try {
|
|
568
|
+
return await (0, keeperAPI_1.createOrderAPI)(params);
|
|
569
|
+
}
|
|
570
|
+
catch (error) {
|
|
571
|
+
console.error("Error in BitflowSDK.createOrder:", error);
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
async getQuote(params) {
|
|
576
|
+
try {
|
|
577
|
+
return await (0, keeperAPI_1.getQuoteAPI)(params);
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
console.error("Error in BitflowSDK.getQuote:", error);
|
|
581
|
+
throw error;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
mapDexPathToActionTrait(dexPath) {
|
|
585
|
+
const isXYK = dexPath.some((d) => d.toLowerCase().includes("xyk"));
|
|
586
|
+
const isStable = dexPath.some((d) => d.toLowerCase().includes("stable"));
|
|
587
|
+
if (isXYK && !isStable) {
|
|
588
|
+
return "SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-1-v-1-1";
|
|
589
|
+
}
|
|
590
|
+
if (isXYK && isStable) {
|
|
591
|
+
return "SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-2-v-1-1";
|
|
592
|
+
}
|
|
593
|
+
if (!isXYK && isStable) {
|
|
594
|
+
return "SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.keeper-action-3-v-1-1";
|
|
595
|
+
}
|
|
596
|
+
throw new Error(`Unsupported DEX path: ${dexPath.join(", ")}`);
|
|
597
|
+
}
|
|
598
|
+
async transformRouteToActionArgs(route) {
|
|
599
|
+
const actionFunctionArgs = {
|
|
600
|
+
tokenList: {},
|
|
601
|
+
xykPoolList: {},
|
|
602
|
+
stableswapPoolList: {},
|
|
603
|
+
boolList: {},
|
|
604
|
+
};
|
|
605
|
+
const swapData = route.swapData;
|
|
606
|
+
if (!swapData || !swapData.parameters) {
|
|
607
|
+
throw new Error("Invalid route data - missing swapData or swapData.parameters");
|
|
608
|
+
}
|
|
609
|
+
const availableTokens = await this.getAvailableTokens();
|
|
610
|
+
const tokenPath = route.tokenPath;
|
|
611
|
+
const expandedTokenPath = [];
|
|
612
|
+
for (let i = 0; i < tokenPath.length - 1; i++) {
|
|
613
|
+
expandedTokenPath.push(tokenPath[i]);
|
|
614
|
+
if (i > 0 && i < tokenPath.length - 1) {
|
|
615
|
+
expandedTokenPath.push(tokenPath[i]);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
expandedTokenPath.push(tokenPath[tokenPath.length - 1]);
|
|
619
|
+
const tokenList = {};
|
|
620
|
+
expandedTokenPath.forEach((tokenId, index) => {
|
|
621
|
+
let contractIdentifier;
|
|
622
|
+
if (tokenId === "token-stx") {
|
|
623
|
+
contractIdentifier =
|
|
624
|
+
"SM1793C4R5PZ4NS4VQ4WMP7SKKYVH8JZEWSZ9HCCR.token-stx-v-1-2";
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
const token = availableTokens.find((t) => t.tokenId === tokenId);
|
|
628
|
+
if (!token || !token.tokenContract) {
|
|
629
|
+
throw new Error(`Could not find contract identifier for token ${tokenId}`);
|
|
630
|
+
}
|
|
631
|
+
contractIdentifier = token.tokenContract;
|
|
632
|
+
}
|
|
633
|
+
const key = String.fromCharCode(97 + index); // 97 = 'a'
|
|
634
|
+
tokenList[key] = contractIdentifier;
|
|
635
|
+
});
|
|
636
|
+
actionFunctionArgs.tokenList = tokenList;
|
|
637
|
+
const transformPoolList = (pools) => {
|
|
638
|
+
if (typeof pools === "string") {
|
|
639
|
+
return { a: pools };
|
|
640
|
+
}
|
|
641
|
+
if (Array.isArray(pools)) {
|
|
642
|
+
const poolObject = {};
|
|
643
|
+
const letters = "abcdefghijklmnopqrstuvwxyz";
|
|
644
|
+
pools.forEach((pool, index) => {
|
|
645
|
+
poolObject[letters[index]] = pool;
|
|
646
|
+
});
|
|
647
|
+
return poolObject;
|
|
648
|
+
}
|
|
649
|
+
if (typeof pools === "object" && pools !== null) {
|
|
650
|
+
return pools;
|
|
651
|
+
}
|
|
652
|
+
return {};
|
|
653
|
+
};
|
|
654
|
+
if (swapData.parameters["xyk-pools"]) {
|
|
655
|
+
actionFunctionArgs.xykPoolList = transformPoolList(swapData.parameters["xyk-pools"]);
|
|
656
|
+
}
|
|
657
|
+
else if (swapData.parameters["pool-trait"]) {
|
|
658
|
+
actionFunctionArgs.xykPoolList = transformPoolList(swapData.parameters["pool-trait"]);
|
|
659
|
+
}
|
|
660
|
+
if (swapData.parameters["stableswap-pools"]) {
|
|
661
|
+
actionFunctionArgs.stableswapPoolList =
|
|
662
|
+
swapData.parameters["stableswap-pools"];
|
|
663
|
+
}
|
|
664
|
+
if ("swaps-reversed" in swapData.parameters) {
|
|
665
|
+
actionFunctionArgs.boolList = {
|
|
666
|
+
a: swapData.parameters["swaps-reversed"].toString(),
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
delete actionFunctionArgs.boolList;
|
|
671
|
+
}
|
|
672
|
+
const dexPath = route.dexPath;
|
|
673
|
+
const trait = this.mapDexPathToActionTrait(dexPath);
|
|
674
|
+
actionFunctionArgs.actionTrait = trait;
|
|
675
|
+
return actionFunctionArgs;
|
|
676
|
+
}
|
|
677
|
+
async getKeeperAggregatorRouteData(tokenX, tokenY, amountX) {
|
|
678
|
+
const quoteResult = await this.getKeeperQuoteForRoute(tokenX, tokenY, amountX);
|
|
679
|
+
if (!quoteResult ||
|
|
680
|
+
!quoteResult.allRoutes ||
|
|
681
|
+
quoteResult.allRoutes.length === 0) {
|
|
682
|
+
throw new Error("No routes found");
|
|
683
|
+
}
|
|
684
|
+
const { bestRoute } = quoteResult;
|
|
685
|
+
if (!bestRoute) {
|
|
686
|
+
throw new Error("No best route found for keeper-compatible DEX paths");
|
|
687
|
+
}
|
|
688
|
+
const actionFunctionArgs = this.transformRouteToActionArgs(bestRoute);
|
|
689
|
+
return actionFunctionArgs;
|
|
690
|
+
}
|
|
691
|
+
async createGroupOrder(params) {
|
|
692
|
+
try {
|
|
693
|
+
return await (0, keeperAPI_1.createGroupOrderAPI)(params);
|
|
694
|
+
}
|
|
695
|
+
catch (error) {
|
|
696
|
+
console.error("Error in BitflowSDK.createGroupOrder:", error);
|
|
697
|
+
throw error;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
async getGroupOrder(groupId, includeOrders) {
|
|
701
|
+
try {
|
|
702
|
+
return await (0, keeperAPI_1.getGroupOrderAPI)(groupId, includeOrders);
|
|
703
|
+
}
|
|
704
|
+
catch (error) {
|
|
705
|
+
console.error("Error in BitflowSDK.getGroupOrder:", error);
|
|
706
|
+
throw error;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
async cancelOrder(orderId) {
|
|
710
|
+
try {
|
|
711
|
+
return await (0, keeperAPI_1.cancelOrderAPI)(orderId);
|
|
712
|
+
}
|
|
713
|
+
catch (error) {
|
|
714
|
+
console.error("Error in BitflowSDK.cancelOrder:", error);
|
|
715
|
+
throw error;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
async cancelGroupOrder(groupId) {
|
|
719
|
+
try {
|
|
720
|
+
return await (0, keeperAPI_1.cancelGroupOrderAPI)(groupId);
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
console.error("Error in BitflowSDK.cancelGroupOrder:", error);
|
|
724
|
+
throw error;
|
|
725
|
+
}
|
|
272
726
|
}
|
|
273
727
|
}
|
|
274
728
|
exports.BitflowSDK = BitflowSDK;
|