@kaspacom/swap-sdk 1.1.6 → 1.1.7
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 +11 -5
- package/dist/index.cjs +179 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -34
- package/dist/index.d.ts +54 -34
- package/dist/index.global.js +179 -84
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +179 -84
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -36,11 +36,11 @@ import {
|
|
|
36
36
|
} from 'swap-widget';
|
|
37
37
|
|
|
38
38
|
const controller = createKaspaComSwapController({
|
|
39
|
-
networkConfig: 'kasplex
|
|
39
|
+
networkConfig: 'kasplex',
|
|
40
40
|
walletProvider: window.ethereum, // any EIP-1193 provider
|
|
41
41
|
onChange: async (state, patch) => {
|
|
42
42
|
console.log('state changed', patch, state);
|
|
43
|
-
// Render your UI from state.computed, state.
|
|
43
|
+
// Render your UI from state.computed, state.loader, etc.
|
|
44
44
|
},
|
|
45
45
|
});
|
|
46
46
|
```
|
|
@@ -101,10 +101,12 @@ console.log(tokens);
|
|
|
101
101
|
### createKaspaComSwapController(options)
|
|
102
102
|
Creates and returns a `SwapSdkController` instance. Accepts either a preset string for `networkConfig` or a full `SwapSdkNetworkConfig` object.
|
|
103
103
|
|
|
104
|
-
- **options.networkConfig**: `'kasplex-testnet'` or `SwapSdkNetworkConfig`
|
|
104
|
+
- **options.networkConfig**: `'kasplex-testnet'`, `'kasplex'` or `SwapSdkNetworkConfig`
|
|
105
105
|
- **options.walletProvider**: EIP-1193 provider (e.g., `window.ethereum`)
|
|
106
106
|
- **options.partnerKey?**: Optional partner key string
|
|
107
107
|
- **options.onChange?**: `(state, patch) => Promise<void>` callback invoked on any state change
|
|
108
|
+
- **options.refreshPairsInterval?**: Optional Number of milliseconds to refresh pairs from the subgraph (for updated quotes)
|
|
109
|
+
- **options.updateQuoteAfterRefreshPairs?**: Optional boolean to update quote after refreshing pairs
|
|
108
110
|
|
|
109
111
|
Returns: `SwapSdkController`
|
|
110
112
|
|
|
@@ -132,6 +134,10 @@ Returns: `SwapSdkController`
|
|
|
132
134
|
- Fetches the current partner fee in percentage (bps/divisor).
|
|
133
135
|
- **getTokensFromGraph(limit?: number, search?: string): Promise<any[]>**
|
|
134
136
|
- Queries the subgraph for tokens. Use for token lists/search.
|
|
137
|
+
- **refreshTokensAndUpdateQuote(forceQuoteUpdate = false): Promise<void>**
|
|
138
|
+
- Refreshes tokens from the subgraph and updates quote if configured. Needed to be called after swap completed or once in a while to get updated quotes.
|
|
139
|
+
- **destroy(): void**
|
|
140
|
+
- Releases all resources from the controller, needs to be called after done using the controller.
|
|
135
141
|
|
|
136
142
|
## Types
|
|
137
143
|
|
|
@@ -195,7 +201,7 @@ All types are exported from `swap-widget`.
|
|
|
195
201
|
- `error?: string`
|
|
196
202
|
- `txHash?: string` (Swap tx hash)
|
|
197
203
|
- `approveTxHash?: string` (Approval transaction tx hash)
|
|
198
|
-
- `
|
|
204
|
+
- `path?: Token[]` (Trade path)
|
|
199
205
|
- `computed?: ComputedAmounts`
|
|
200
206
|
- `loader: LoaderStatuses | null`
|
|
201
207
|
|
|
@@ -215,7 +221,7 @@ All types are exported from `swap-widget`.
|
|
|
215
221
|
The wrapped native token (WKAS).
|
|
216
222
|
|
|
217
223
|
- **NETWORKS**
|
|
218
|
-
- Preset map of network keys to `SwapSdkNetworkConfig` objects. Includes `'kasplex-testnet'`.
|
|
224
|
+
- Preset map of network keys to `SwapSdkNetworkConfig` objects. Includes `'kasplex-testnet'`, `'kasplex'`.
|
|
219
225
|
|
|
220
226
|
|
|
221
227
|
## Usage Patterns
|
package/dist/index.cjs
CHANGED
|
@@ -127,6 +127,12 @@ var WalletService = class {
|
|
|
127
127
|
getProvider() {
|
|
128
128
|
return this.walletProvider || this.networkProvider;
|
|
129
129
|
}
|
|
130
|
+
destroy() {
|
|
131
|
+
if (this.walletProvider) {
|
|
132
|
+
this.networkProvider.destroy();
|
|
133
|
+
this.disconnect();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
130
136
|
getSigner() {
|
|
131
137
|
return this.signer;
|
|
132
138
|
}
|
|
@@ -162,11 +168,6 @@ var WalletService = class {
|
|
|
162
168
|
throw new Error("No Ethereum wallet detected. Please connect a wallet provider.");
|
|
163
169
|
}
|
|
164
170
|
}
|
|
165
|
-
// Disconnect wallet and emit event
|
|
166
|
-
disconnectWallet() {
|
|
167
|
-
this.address = null;
|
|
168
|
-
this.signer = null;
|
|
169
|
-
}
|
|
170
171
|
};
|
|
171
172
|
|
|
172
173
|
// src/services/swap.service.ts
|
|
@@ -1255,12 +1256,30 @@ var SwapService = class {
|
|
|
1255
1256
|
this.signer = null;
|
|
1256
1257
|
this.pairs = [];
|
|
1257
1258
|
this.resolvePairsLoaded = null;
|
|
1259
|
+
this.rejectPairsLoaded = null;
|
|
1258
1260
|
this.resolvePartnerFeeLoaded = null;
|
|
1261
|
+
this.rejectPartnerFeeLoaded = null;
|
|
1259
1262
|
this.partnerFee = 0n;
|
|
1260
1263
|
this.provider = provider;
|
|
1261
|
-
this.wethAddress = config.wrappedToken.address;
|
|
1262
1264
|
this.chainId = config.chainId;
|
|
1263
|
-
|
|
1265
|
+
this.routerContract = new import_ethers2.Contract(config.routerAddress, this.routerAbi, provider);
|
|
1266
|
+
this.factoryContract = new import_ethers2.Contract(config.factoryAddress, this.factoryAbi, provider);
|
|
1267
|
+
if (config.proxyAddress) {
|
|
1268
|
+
this.proxyContract = new import_ethers2.Contract(config.proxyAddress, this.proxyAbi, provider);
|
|
1269
|
+
}
|
|
1270
|
+
this.pairsLoadedPromise = new Promise((resolve, reject) => {
|
|
1271
|
+
this.resolvePairsLoaded = resolve;
|
|
1272
|
+
this.rejectPairsLoaded = reject;
|
|
1273
|
+
});
|
|
1274
|
+
this.partnerFeeLoadedPromise = new Promise((resolve, reject) => {
|
|
1275
|
+
this.resolvePartnerFeeLoaded = resolve;
|
|
1276
|
+
this.rejectPartnerFeeLoaded = reject;
|
|
1277
|
+
});
|
|
1278
|
+
this.loadAllPairs();
|
|
1279
|
+
this.loadPartnerFee();
|
|
1280
|
+
}
|
|
1281
|
+
get routerAbi() {
|
|
1282
|
+
return [
|
|
1264
1283
|
// Swaps (ERC20 <-> ERC20)
|
|
1265
1284
|
"function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)",
|
|
1266
1285
|
"function swapTokensForExactTokens(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)",
|
|
@@ -1273,47 +1292,49 @@ var SwapService = class {
|
|
|
1273
1292
|
"function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)",
|
|
1274
1293
|
"function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut)",
|
|
1275
1294
|
"function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn)",
|
|
1276
|
-
"function getAmountsIn(
|
|
1295
|
+
"function getAmountsIn(uint amountOut, address[] memory path) internal view returns (uint[] memory amounts)",
|
|
1277
1296
|
// Get WETH
|
|
1278
1297
|
"function WETH() external pure returns (address)"
|
|
1279
1298
|
];
|
|
1280
|
-
|
|
1299
|
+
}
|
|
1300
|
+
get factoryAbi() {
|
|
1301
|
+
return [
|
|
1281
1302
|
"function getPair(address tokenA, address tokenB) external view returns (address pair)",
|
|
1282
1303
|
"function allPairs(uint) external view returns (address pair)",
|
|
1283
1304
|
"function allPairsLength() external view returns (uint)"
|
|
1284
1305
|
];
|
|
1285
|
-
|
|
1286
|
-
|
|
1306
|
+
}
|
|
1307
|
+
get proxyAbi() {
|
|
1308
|
+
return [
|
|
1309
|
+
...this.routerAbi,
|
|
1287
1310
|
"function partners(bytes32) external view returns (address feeRecipient, uint16 feeBps)"
|
|
1288
1311
|
];
|
|
1289
|
-
this.routerContract = new import_ethers2.Contract(config.routerAddress, routerAbi, provider);
|
|
1290
|
-
this.factoryContract = new import_ethers2.Contract(config.factoryAddress, factoryAbi, provider);
|
|
1291
|
-
if (config.proxyAddress) {
|
|
1292
|
-
this.proxyContract = new import_ethers2.Contract(config.proxyAddress, proxyAbi, provider);
|
|
1293
|
-
}
|
|
1294
|
-
this.pairsLoadedPromise = new Promise((resolve) => {
|
|
1295
|
-
this.resolvePairsLoaded = resolve;
|
|
1296
|
-
});
|
|
1297
|
-
this.partnerFeeLoadedPromise = new Promise((resolve) => {
|
|
1298
|
-
this.resolvePartnerFeeLoaded = resolve;
|
|
1299
|
-
});
|
|
1300
|
-
this.loadAllPairsFromGraph();
|
|
1301
|
-
this.loadPartnerFee();
|
|
1302
1312
|
}
|
|
1303
1313
|
// parnter fee is BPS_DIVISOR = 10_000n;
|
|
1304
1314
|
async loadPartnerFee() {
|
|
1305
1315
|
if (!this.resolvePairsLoaded) {
|
|
1306
1316
|
return this.partnerFee;
|
|
1307
1317
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
this.resolvePartnerFeeLoaded
|
|
1314
|
-
|
|
1318
|
+
try {
|
|
1319
|
+
if (this.swapOptions.partnerKey && this.proxyContract) {
|
|
1320
|
+
const [, fee] = await this.proxyContract?.partners(this.swapOptions.partnerKey);
|
|
1321
|
+
this.partnerFee = fee;
|
|
1322
|
+
}
|
|
1323
|
+
if (this.resolvePartnerFeeLoaded) {
|
|
1324
|
+
this.resolvePartnerFeeLoaded();
|
|
1325
|
+
this.resolvePartnerFeeLoaded = null;
|
|
1326
|
+
}
|
|
1327
|
+
return this.partnerFee;
|
|
1328
|
+
} catch (error) {
|
|
1329
|
+
if (this.rejectPartnerFeeLoaded) {
|
|
1330
|
+
this.rejectPartnerFeeLoaded(error);
|
|
1331
|
+
this.partnerFeeLoadedPromise = new Promise((resolve, reject) => {
|
|
1332
|
+
this.resolvePartnerFeeLoaded = resolve;
|
|
1333
|
+
this.rejectPartnerFeeLoaded = reject;
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
throw error;
|
|
1315
1337
|
}
|
|
1316
|
-
return this.partnerFee;
|
|
1317
1338
|
}
|
|
1318
1339
|
setSigner(signer) {
|
|
1319
1340
|
this.signer = signer;
|
|
@@ -1333,11 +1354,7 @@ var SwapService = class {
|
|
|
1333
1354
|
}
|
|
1334
1355
|
return num.toFixed(decimals);
|
|
1335
1356
|
}
|
|
1336
|
-
|
|
1337
|
-
* Loads all pairs from The Graph and caches them as Uniswap SDK Pair instances.
|
|
1338
|
-
* @param graphEndpoint The GraphQL endpoint URL
|
|
1339
|
-
*/
|
|
1340
|
-
async loadAllPairsFromGraph() {
|
|
1357
|
+
async refreshPairsFromGraph() {
|
|
1341
1358
|
const query = `{
|
|
1342
1359
|
pairs(first: 1000) {
|
|
1343
1360
|
id
|
|
@@ -1347,46 +1364,47 @@ var SwapService = class {
|
|
|
1347
1364
|
token1 { id symbol name decimals }
|
|
1348
1365
|
}
|
|
1349
1366
|
}`;
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
const wethPair = data.pairs.find(
|
|
1367
|
-
(pair) => pair.token0.id.toLowerCase() === this.wethAddress.toLowerCase() || pair.token1.id.toLowerCase() === this.wethAddress.toLowerCase()
|
|
1367
|
+
const response = await fetch(this.config.graphEndpoint, {
|
|
1368
|
+
method: "POST",
|
|
1369
|
+
headers: { "Content-Type": "application/json" },
|
|
1370
|
+
body: JSON.stringify({ query })
|
|
1371
|
+
});
|
|
1372
|
+
if (!response.ok) throw new Error(`Network error: ${response.status}`);
|
|
1373
|
+
const { data } = await response.json();
|
|
1374
|
+
if (!data || !data.pairs) throw new Error(`No pairs found: ${data}`);
|
|
1375
|
+
return data.pairs;
|
|
1376
|
+
}
|
|
1377
|
+
async refreshPairs() {
|
|
1378
|
+
const pairsResult = this.swapOptions.getPairsData ? await this.swapOptions.getPairsData() : await this.refreshPairsFromGraph();
|
|
1379
|
+
const pairs = [];
|
|
1380
|
+
for (const pair of pairsResult) {
|
|
1381
|
+
pairs.push(
|
|
1382
|
+
this.createSDKPair(pair)
|
|
1368
1383
|
);
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
}
|
|
1384
|
+
}
|
|
1385
|
+
this.pairs = pairs;
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* Loads all pairs from The Graph and caches them as Uniswap SDK Pair instances.
|
|
1389
|
+
* @param graphEndpoint The GraphQL endpoint URL
|
|
1390
|
+
*/
|
|
1391
|
+
async loadAllPairs() {
|
|
1392
|
+
try {
|
|
1393
|
+
await this.refreshPairs();
|
|
1380
1394
|
if (this.resolvePairsLoaded) {
|
|
1381
1395
|
this.resolvePairsLoaded();
|
|
1382
1396
|
this.resolvePairsLoaded = null;
|
|
1383
1397
|
}
|
|
1384
1398
|
} catch (error) {
|
|
1385
1399
|
console.error("Error loading pairs from graph:", error);
|
|
1386
|
-
if (this.
|
|
1387
|
-
this.
|
|
1388
|
-
this.resolvePairsLoaded = null;
|
|
1400
|
+
if (this.rejectPairsLoaded) {
|
|
1401
|
+
this.rejectPairsLoaded(error);
|
|
1389
1402
|
}
|
|
1403
|
+
this.pairsLoadedPromise = new Promise((resolve, reject) => {
|
|
1404
|
+
this.resolvePairsLoaded = resolve;
|
|
1405
|
+
this.rejectPairsLoaded = reject;
|
|
1406
|
+
});
|
|
1407
|
+
setTimeout(this.loadAllPairs.bind(this), 1e3);
|
|
1390
1408
|
}
|
|
1391
1409
|
}
|
|
1392
1410
|
async waitForPairsLoaded() {
|
|
@@ -1396,7 +1414,7 @@ var SwapService = class {
|
|
|
1396
1414
|
return await this.partnerFeeLoadedPromise;
|
|
1397
1415
|
}
|
|
1398
1416
|
createSDKPair(pair) {
|
|
1399
|
-
const { token0, token1,
|
|
1417
|
+
const { token0, token1, reserve0, reserve1 } = pair;
|
|
1400
1418
|
const sdkToken0 = new import_sdk_core2.Token(
|
|
1401
1419
|
this.chainId,
|
|
1402
1420
|
token0.id,
|
|
@@ -1459,8 +1477,6 @@ var SwapService = class {
|
|
|
1459
1477
|
isOutputAmount ? sdkToToken : sdkFromToken,
|
|
1460
1478
|
amountInWei
|
|
1461
1479
|
);
|
|
1462
|
-
await this.waitForPairsLoaded();
|
|
1463
|
-
await this.waitForPartnerFeeLoaded();
|
|
1464
1480
|
const pairs = this.getPairs();
|
|
1465
1481
|
if (!pairs || pairs.length === 0) {
|
|
1466
1482
|
throw new Error("Pairs not loaded yet. Please wait for initialization.");
|
|
@@ -1486,6 +1502,14 @@ var SwapService = class {
|
|
|
1486
1502
|
value = value.replace(/\.?0+$/, "");
|
|
1487
1503
|
return value;
|
|
1488
1504
|
}
|
|
1505
|
+
async getAmountsIn(sellAmountWei, pathAddresses) {
|
|
1506
|
+
const [aIn] = await this.routerContract.getAmountsIn(sellAmountWei, pathAddresses);
|
|
1507
|
+
return aIn;
|
|
1508
|
+
}
|
|
1509
|
+
async getAmountsOut(buyAmountWei, pathAddresses) {
|
|
1510
|
+
const [, aOut] = await this.routerContract.getAmountsOut(buyAmountWei, pathAddresses);
|
|
1511
|
+
return aOut;
|
|
1512
|
+
}
|
|
1489
1513
|
/**
|
|
1490
1514
|
*
|
|
1491
1515
|
* @param sellToken
|
|
@@ -1497,6 +1521,8 @@ var SwapService = class {
|
|
|
1497
1521
|
*/
|
|
1498
1522
|
async calculateTrade(sellToken, buyToken, targetAmount, isOutputAmount, slippage) {
|
|
1499
1523
|
try {
|
|
1524
|
+
await this.waitForPairsLoaded();
|
|
1525
|
+
await this.waitForPartnerFeeLoaded();
|
|
1500
1526
|
const roundedAmountIn = this.roundToDecimals(targetAmount, isOutputAmount ? buyToken.decimals : sellToken.decimals);
|
|
1501
1527
|
let sellAmountWei = (0, import_ethers2.parseUnits)(
|
|
1502
1528
|
roundedAmountIn,
|
|
@@ -1507,8 +1533,8 @@ var SwapService = class {
|
|
|
1507
1533
|
const denominator = PARTNER_FEE_BPS_DIVISOR - this.partnerFee;
|
|
1508
1534
|
sellAmountWei = (numerator + denominator - 1n) / denominator;
|
|
1509
1535
|
}
|
|
1510
|
-
const sellTokenForContracts = sellToken.address == import_ethers2.ethers.ZeroAddress ? this.
|
|
1511
|
-
const buyTokenForContracts = buyToken.address == import_ethers2.ethers.ZeroAddress ? this.
|
|
1536
|
+
const sellTokenForContracts = sellToken.address == import_ethers2.ethers.ZeroAddress ? this.config.wrappedToken : sellToken;
|
|
1537
|
+
const buyTokenForContracts = buyToken.address == import_ethers2.ethers.ZeroAddress ? this.config.wrappedToken : buyToken;
|
|
1512
1538
|
const trade = await this.getBestTrade(
|
|
1513
1539
|
sellTokenForContracts,
|
|
1514
1540
|
buyTokenForContracts,
|
|
@@ -1518,8 +1544,16 @@ var SwapService = class {
|
|
|
1518
1544
|
if (!trade) {
|
|
1519
1545
|
throw new Error("No trade path found for the given tokens and amount.");
|
|
1520
1546
|
}
|
|
1521
|
-
const
|
|
1522
|
-
|
|
1547
|
+
const pathAddresses = trade.route.path.map((token) => token.address);
|
|
1548
|
+
let amountIn = "0";
|
|
1549
|
+
let amountOut = "0";
|
|
1550
|
+
if (isOutputAmount) {
|
|
1551
|
+
amountIn = String(await this.getAmountsIn(sellAmountWei, pathAddresses));
|
|
1552
|
+
amountOut = String((0, import_ethers2.parseUnits)(targetAmount, buyToken.decimals));
|
|
1553
|
+
} else {
|
|
1554
|
+
amountOut = String(await this.getAmountsOut(sellAmountWei, pathAddresses));
|
|
1555
|
+
amountIn = String((0, import_ethers2.parseUnits)(targetAmount, sellToken.decimals));
|
|
1556
|
+
}
|
|
1523
1557
|
let amounts = {
|
|
1524
1558
|
amountIn: (0, import_ethers2.formatUnits)(amountIn, sellToken.decimals),
|
|
1525
1559
|
amountOut: isOutputAmount ? this.trimTrailingZeros(roundedAmountIn) : (0, import_ethers2.formatUnits)(amountOut, buyToken.decimals),
|
|
@@ -1529,18 +1563,23 @@ var SwapService = class {
|
|
|
1529
1563
|
const slippagePercent = new import_sdk_core2.Percent(Math.round(parseFloat(slippage) * 100), 1e4);
|
|
1530
1564
|
let maxAmountIn, minAmountOut;
|
|
1531
1565
|
if (isOutputAmount) {
|
|
1532
|
-
|
|
1566
|
+
const slippageAmount = BigInt(amountIn) * BigInt(slippagePercent.numerator.toString()) / BigInt(slippagePercent.denominator.toString());
|
|
1567
|
+
const maxAmountInBigInt = BigInt(amountIn) + slippageAmount;
|
|
1568
|
+
maxAmountIn = maxAmountInBigInt.toString();
|
|
1533
1569
|
amounts.maxAmountInRaw = maxAmountIn;
|
|
1534
1570
|
amounts.maxAmountIn = (0, import_ethers2.formatUnits)(maxAmountIn, sellToken.decimals);
|
|
1535
1571
|
} else {
|
|
1536
|
-
|
|
1572
|
+
const amountOutBigInt = BigInt(amountOut);
|
|
1573
|
+
const slippageAmount = amountOutBigInt * BigInt(slippagePercent.numerator.toString()) / BigInt(slippagePercent.denominator.toString());
|
|
1574
|
+
const minAmountOutBigInt = amountOutBigInt - slippageAmount;
|
|
1575
|
+
minAmountOut = minAmountOutBigInt.toString();
|
|
1537
1576
|
amounts.minAmountOutRaw = minAmountOut;
|
|
1538
1577
|
amounts.minAmountOut = (0, import_ethers2.formatUnits)(minAmountOut, buyToken.decimals);
|
|
1539
1578
|
}
|
|
1540
1579
|
if (this.partnerFee && this.partnerFee > 0n) {
|
|
1541
1580
|
if (!isOutputAmount) {
|
|
1542
|
-
const
|
|
1543
|
-
const amountOutMinusFee =
|
|
1581
|
+
const amountOutBigInt = BigInt(amountOut);
|
|
1582
|
+
const amountOutMinusFee = amountOutBigInt * (PARTNER_FEE_BPS_DIVISOR - this.partnerFee) / PARTNER_FEE_BPS_DIVISOR;
|
|
1544
1583
|
amounts.amountOutRaw = amountOutMinusFee.toString();
|
|
1545
1584
|
amounts.amountOut = (0, import_ethers2.formatUnits)(amountOutMinusFee, buyToken.decimals);
|
|
1546
1585
|
if (minAmountOut) {
|
|
@@ -1834,6 +1873,7 @@ var DEFAULT_SETTINGS = {
|
|
|
1834
1873
|
};
|
|
1835
1874
|
var SwapSdkController = class {
|
|
1836
1875
|
constructor(options) {
|
|
1876
|
+
this.refreshPairsTimeout = null;
|
|
1837
1877
|
this.state = {
|
|
1838
1878
|
loader: null
|
|
1839
1879
|
};
|
|
@@ -1852,11 +1892,16 @@ var SwapSdkController = class {
|
|
|
1852
1892
|
this.options.networkConfig,
|
|
1853
1893
|
this.options.walletProvider
|
|
1854
1894
|
);
|
|
1855
|
-
this.swapService = new SwapService(
|
|
1895
|
+
this.swapService = new (this.options.swapServiceClass || SwapService)(
|
|
1856
1896
|
this.walletService.getProvider(),
|
|
1857
1897
|
this.options.networkConfig,
|
|
1858
1898
|
this.options
|
|
1859
1899
|
);
|
|
1900
|
+
if (this.options.refreshPairsInterval) {
|
|
1901
|
+
this.swapService.waitForPairsLoaded().finally(() => {
|
|
1902
|
+
this.refreshPairsTimeout = setTimeout(this.refreshTokensAndUpdateQuoteAndSetTimeout.bind(this), this.options.refreshPairsInterval);
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1860
1905
|
}
|
|
1861
1906
|
async setChange(patch) {
|
|
1862
1907
|
const next = {
|
|
@@ -1905,6 +1950,7 @@ var SwapSdkController = class {
|
|
|
1905
1950
|
await this.setChange({
|
|
1906
1951
|
computed: tradeResult.computed,
|
|
1907
1952
|
tradeInfo: tradeResult.trade,
|
|
1953
|
+
path: tradeResult.trade.route.path,
|
|
1908
1954
|
loader: null
|
|
1909
1955
|
});
|
|
1910
1956
|
} catch (error) {
|
|
@@ -1962,9 +2008,8 @@ var SwapSdkController = class {
|
|
|
1962
2008
|
if (!fromToken || !toToken || amount === void 0) throw new Error("Tokens or amount not set");
|
|
1963
2009
|
await this.approveIfNeeded();
|
|
1964
2010
|
await this.setChange({ loader: 3 /* SWAPPING */ });
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
const path = trade.route.path.map((token) => token.address);
|
|
2011
|
+
if (!this.state.path) throw new Error("Trade info missing - calculate quote first");
|
|
2012
|
+
const path = this.state.path.map((token) => token.address);
|
|
1968
2013
|
if (path.length === 0) throw new Error("Trade path missing");
|
|
1969
2014
|
const computed = this.state.computed;
|
|
1970
2015
|
if (!computed) throw new Error("Computed amounts missing");
|
|
@@ -2006,6 +2051,29 @@ var SwapSdkController = class {
|
|
|
2006
2051
|
get currentNetworkConfig() {
|
|
2007
2052
|
return this.options.networkConfig;
|
|
2008
2053
|
}
|
|
2054
|
+
async destroy() {
|
|
2055
|
+
if (this.walletService) {
|
|
2056
|
+
this.walletService.destroy();
|
|
2057
|
+
}
|
|
2058
|
+
if (this.refreshPairsTimeout) {
|
|
2059
|
+
clearTimeout(this.refreshPairsTimeout);
|
|
2060
|
+
this.refreshPairsTimeout = null;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
async refreshTokensAndUpdateQuote(forceQuoteUpdate = false) {
|
|
2064
|
+
await this.swapService?.refreshPairsFromGraph();
|
|
2065
|
+
if ((this.options.updateQuoteAfterRefreshPairs || forceQuoteUpdate) && !this.state.loader) {
|
|
2066
|
+
await this.calculateQuoteIfNeeded();
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
async refreshTokensAndUpdateQuoteAndSetTimeout() {
|
|
2070
|
+
try {
|
|
2071
|
+
await this.refreshTokensAndUpdateQuote();
|
|
2072
|
+
} catch (error) {
|
|
2073
|
+
console.error(error);
|
|
2074
|
+
}
|
|
2075
|
+
this.refreshPairsTimeout = setTimeout(this.refreshTokensAndUpdateQuoteAndSetTimeout.bind(this), this.options.refreshPairsInterval);
|
|
2076
|
+
}
|
|
2009
2077
|
};
|
|
2010
2078
|
|
|
2011
2079
|
// src/config/networks.ts
|
|
@@ -2037,6 +2105,33 @@ var NETWORKS = {
|
|
|
2037
2105
|
name: "Kasplex Kaspa",
|
|
2038
2106
|
symbol: "KAS"
|
|
2039
2107
|
}
|
|
2108
|
+
},
|
|
2109
|
+
"kasplex": {
|
|
2110
|
+
name: "Kasplex",
|
|
2111
|
+
chainId: 202555,
|
|
2112
|
+
rpcUrl: "https://evmrpc.kasplex.org",
|
|
2113
|
+
routerAddress: "0x3a1f0bD164fe9D8fa18Da5abAB352dC634CA5F10",
|
|
2114
|
+
factoryAddress: "0xa9CBa43A407c9Eb30933EA21f7b9D74A128D613c",
|
|
2115
|
+
proxyAddress: "0x4c5BEaAE83577E3a117ce2F477fC42a1EA39A8a3",
|
|
2116
|
+
graphEndpoint: "https://graph-kasplex.kaspa.com/subgraphs/name/kasplex-v2-core",
|
|
2117
|
+
blockExplorerUrl: "https://explorer.kasplex.org",
|
|
2118
|
+
additionalJsonRpcApiProviderOptionsOptions: {
|
|
2119
|
+
batchMaxCount: 1,
|
|
2120
|
+
batchMaxSize: 1,
|
|
2121
|
+
batchStallTime: 0
|
|
2122
|
+
},
|
|
2123
|
+
wrappedToken: {
|
|
2124
|
+
address: "0x2c2Ae87Ba178F48637acAe54B87c3924F544a83e",
|
|
2125
|
+
decimals: 18,
|
|
2126
|
+
name: "Wrapped KAS",
|
|
2127
|
+
symbol: "WKAS"
|
|
2128
|
+
},
|
|
2129
|
+
nativeToken: {
|
|
2130
|
+
address: import_ethers3.ethers.ZeroAddress,
|
|
2131
|
+
decimals: 18,
|
|
2132
|
+
name: "Kasplex Kaspa",
|
|
2133
|
+
symbol: "KAS"
|
|
2134
|
+
}
|
|
2040
2135
|
}
|
|
2041
2136
|
// Add more networks as needed
|
|
2042
2137
|
};
|