@sun-protocol/sun-sdk-sunswap-v2 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -0
- package/dist/index.cjs +1194 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +356 -0
- package/dist/index.d.ts +356 -0
- package/dist/index.js +1108 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
BASIS_POINTS: () => BASIS_POINTS,
|
|
34
|
+
FACTORY_ADDRESS: () => FACTORY_ADDRESS,
|
|
35
|
+
FACTORY_ADDRESS_MAP: () => FACTORY_ADDRESS_MAP,
|
|
36
|
+
FIVE: () => FIVE,
|
|
37
|
+
INIT_CODE_HASH: () => INIT_CODE_HASH,
|
|
38
|
+
INIT_CODE_HASH_MAP: () => INIT_CODE_HASH_MAP,
|
|
39
|
+
InsufficientInputAmountError: () => InsufficientInputAmountError,
|
|
40
|
+
InsufficientReservesError: () => InsufficientReservesError,
|
|
41
|
+
MINIMUM_LIQUIDITY: () => MINIMUM_LIQUIDITY,
|
|
42
|
+
ONE: () => ONE,
|
|
43
|
+
ONE_HUNDRED_PERCENT: () => ONE_HUNDRED_PERCENT,
|
|
44
|
+
Pair: () => Pair,
|
|
45
|
+
Route: () => Route,
|
|
46
|
+
Router: () => Router,
|
|
47
|
+
Trade: () => Trade,
|
|
48
|
+
V2_FACTORY_READ_SELECTORS: () => V2_FACTORY_READ_SELECTORS,
|
|
49
|
+
V2_INIT_CODE_HASH: () => V2_INIT_CODE_HASH,
|
|
50
|
+
V2_PAIR_READ_SELECTORS: () => V2_PAIR_READ_SELECTORS,
|
|
51
|
+
V2_ROUTER_READ_SELECTORS: () => V2_ROUTER_READ_SELECTORS,
|
|
52
|
+
V2_ROUTER_SELECTORS: () => V2_ROUTER_SELECTORS,
|
|
53
|
+
ZERO: () => ZERO,
|
|
54
|
+
ZERO_PERCENT: () => ZERO_PERCENT,
|
|
55
|
+
_1000: () => _1000,
|
|
56
|
+
_997: () => _997,
|
|
57
|
+
applyV2SlippageMin: () => applyV2SlippageMin,
|
|
58
|
+
buildV2AddLiquidityAction: () => buildV2AddLiquidityAction,
|
|
59
|
+
buildV2AddLiquidityEthAction: () => buildV2AddLiquidityEthAction,
|
|
60
|
+
buildV2FactoryFeeToRead: () => buildV2FactoryFeeToRead,
|
|
61
|
+
buildV2FactoryPairRead: () => buildV2FactoryPairRead,
|
|
62
|
+
buildV2LpApproveAction: () => buildV2LpApproveAction,
|
|
63
|
+
buildV2PairAllowanceRead: () => buildV2PairAllowanceRead,
|
|
64
|
+
buildV2PairBalanceRead: () => buildV2PairBalanceRead,
|
|
65
|
+
buildV2PairKLastRead: () => buildV2PairKLastRead,
|
|
66
|
+
buildV2PairReservesRead: () => buildV2PairReservesRead,
|
|
67
|
+
buildV2PairTotalSupplyRead: () => buildV2PairTotalSupplyRead,
|
|
68
|
+
buildV2RemoveLiquidityAction: () => buildV2RemoveLiquidityAction,
|
|
69
|
+
buildV2RemoveLiquidityEthAction: () => buildV2RemoveLiquidityEthAction,
|
|
70
|
+
buildV2RouterAllowedTradingPairRead: () => buildV2RouterAllowedTradingPairRead,
|
|
71
|
+
buildV2RouterAmountsInRead: () => buildV2RouterAmountsInRead,
|
|
72
|
+
buildV2RouterAmountsOutRead: () => buildV2RouterAmountsOutRead,
|
|
73
|
+
buildV2SwapEthForExactTokensAction: () => buildV2SwapEthForExactTokensAction,
|
|
74
|
+
buildV2SwapExactEthForTokensAction: () => buildV2SwapExactEthForTokensAction,
|
|
75
|
+
buildV2SwapExactTokensForEthAction: () => buildV2SwapExactTokensForEthAction,
|
|
76
|
+
buildV2SwapExactTokensForTokensAction: () => buildV2SwapExactTokensForTokensAction,
|
|
77
|
+
buildV2SwapTokensForExactEthAction: () => buildV2SwapTokensForExactEthAction,
|
|
78
|
+
buildV2SwapTokensForExactTokensAction: () => buildV2SwapTokensForExactTokensAction,
|
|
79
|
+
computePairAddress: () => computePairAddress,
|
|
80
|
+
computeV2PairAddress: () => computeV2PairAddress,
|
|
81
|
+
createV2PairKey: () => createV2PairKey,
|
|
82
|
+
evmHexToTronAddress: () => evmHexToTronAddress,
|
|
83
|
+
getV2AddLiquidityMinimums: () => getV2AddLiquidityMinimums,
|
|
84
|
+
getV2RemoveLiquidityMinimums: () => getV2RemoveLiquidityMinimums,
|
|
85
|
+
inputOutputComparator: () => inputOutputComparator,
|
|
86
|
+
normalizeV2AmountsResult: () => normalizeV2AmountsResult,
|
|
87
|
+
normalizeV2ReserveResult: () => normalizeV2ReserveResult,
|
|
88
|
+
quoteV2LiquidityAmount: () => quoteV2LiquidityAmount,
|
|
89
|
+
sortV2Tokens: () => sortV2Tokens,
|
|
90
|
+
tradeComparator: () => tradeComparator,
|
|
91
|
+
tronAddressToEvmHex: () => tronAddressToEvmHex,
|
|
92
|
+
tronCreate2Address: () => tronCreate2Address
|
|
93
|
+
});
|
|
94
|
+
module.exports = __toCommonJS(index_exports);
|
|
95
|
+
|
|
96
|
+
// src/actions.ts
|
|
97
|
+
var import_sun_sdk_chains2 = require("@sun-protocol/sun-sdk-chains");
|
|
98
|
+
var import_sun_sdk_core2 = require("@sun-protocol/sun-sdk-core");
|
|
99
|
+
|
|
100
|
+
// src/utils.ts
|
|
101
|
+
var import_sun_sdk_chains = require("@sun-protocol/sun-sdk-chains");
|
|
102
|
+
var import_keccak256 = require("@ethersproject/keccak256");
|
|
103
|
+
var import_sha256 = require("@noble/hashes/sha256");
|
|
104
|
+
var import_sun_sdk_core = require("@sun-protocol/sun-sdk-core");
|
|
105
|
+
var V2_INIT_CODE_HASH = {
|
|
106
|
+
mainnet: "0x6d3f89421f83e4b62e628de8fc7ff2b014a79bf8fd8e8b0ea46e4a1d9409b67d",
|
|
107
|
+
nile: "0x9dd9bfc2f6c1103a6c01d9c6a4044e4b8a9361f92df2728cdc3729922d56748e"
|
|
108
|
+
};
|
|
109
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
110
|
+
var BASE58_ZERO = "1";
|
|
111
|
+
var HEX_20_BYTES_PATTERN = /^0x[a-fA-F0-9]{40}$/;
|
|
112
|
+
var HEX_20_BYTES_NO_PREFIX_PATTERN = /^[a-fA-F0-9]{40}$/;
|
|
113
|
+
var HEX_32_BYTES_PATTERN = /^(?:0x)?[a-fA-F0-9]{64}$/;
|
|
114
|
+
var TRON_ADDRESS_PAYLOAD_BYTES = 25;
|
|
115
|
+
var TRON_ADDRESS_BYTES = 21;
|
|
116
|
+
var TRON_PREFIX_HEX = "41";
|
|
117
|
+
function toBigInt(value) {
|
|
118
|
+
return BigInt(value.toString());
|
|
119
|
+
}
|
|
120
|
+
function validatePositive(value, label) {
|
|
121
|
+
(0, import_sun_sdk_core.sdkInvariant)(value > 0n, import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be positive`, {
|
|
122
|
+
[label]: value.toString()
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function sortV2Tokens(tokenA, tokenB) {
|
|
126
|
+
return tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA];
|
|
127
|
+
}
|
|
128
|
+
function decodeBase58(value) {
|
|
129
|
+
let decoded = 0n;
|
|
130
|
+
for (const char of value) {
|
|
131
|
+
const index = BASE58_ALPHABET.indexOf(char);
|
|
132
|
+
(0, import_sun_sdk_core.sdkInvariant)(index >= 0, import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "Invalid base58 character", { value, char });
|
|
133
|
+
decoded = decoded * 58n + BigInt(index);
|
|
134
|
+
}
|
|
135
|
+
const bytes = [];
|
|
136
|
+
while (decoded > 0n) {
|
|
137
|
+
bytes.unshift(Number(decoded & 0xffn));
|
|
138
|
+
decoded >>= 8n;
|
|
139
|
+
}
|
|
140
|
+
for (const char of value) {
|
|
141
|
+
if (char !== "1") break;
|
|
142
|
+
bytes.unshift(0);
|
|
143
|
+
}
|
|
144
|
+
return Uint8Array.from(bytes);
|
|
145
|
+
}
|
|
146
|
+
function encodeBase58(bytes) {
|
|
147
|
+
let value = 0n;
|
|
148
|
+
for (const byte of bytes) {
|
|
149
|
+
value = (value << 8n) + BigInt(byte);
|
|
150
|
+
}
|
|
151
|
+
let encoded = "";
|
|
152
|
+
while (value > 0n) {
|
|
153
|
+
const mod = Number(value % 58n);
|
|
154
|
+
const char = BASE58_ALPHABET[mod];
|
|
155
|
+
(0, import_sun_sdk_core.sdkInvariant)(char !== void 0, import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "Invalid base58 remainder", { mod });
|
|
156
|
+
encoded = char + encoded;
|
|
157
|
+
value /= 58n;
|
|
158
|
+
}
|
|
159
|
+
for (const byte of bytes) {
|
|
160
|
+
if (byte !== 0) break;
|
|
161
|
+
encoded = `${BASE58_ZERO}${encoded}`;
|
|
162
|
+
}
|
|
163
|
+
return encoded || BASE58_ZERO;
|
|
164
|
+
}
|
|
165
|
+
function bytesToHex(bytes) {
|
|
166
|
+
return Array.from(bytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
167
|
+
}
|
|
168
|
+
function hexToBytes(hex, label) {
|
|
169
|
+
const normalized = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
170
|
+
(0, import_sun_sdk_core.sdkInvariant)(/^[a-fA-F0-9]*$/.test(normalized) && normalized.length % 2 === 0, import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be even-length hex`, {
|
|
171
|
+
label,
|
|
172
|
+
value: hex
|
|
173
|
+
});
|
|
174
|
+
const bytes = new Uint8Array(normalized.length / 2);
|
|
175
|
+
for (let i = 0; i < bytes.length; i += 1) {
|
|
176
|
+
bytes[i] = Number.parseInt(normalized.slice(i * 2, i * 2 + 2), 16);
|
|
177
|
+
}
|
|
178
|
+
return bytes;
|
|
179
|
+
}
|
|
180
|
+
function checksum(payload) {
|
|
181
|
+
return (0, import_sha256.sha256)((0, import_sha256.sha256)(payload)).slice(0, 4);
|
|
182
|
+
}
|
|
183
|
+
function tronPayloadToBase58(payload) {
|
|
184
|
+
const bytes = new Uint8Array(TRON_ADDRESS_PAYLOAD_BYTES);
|
|
185
|
+
bytes.set(payload, 0);
|
|
186
|
+
bytes.set(checksum(payload), TRON_ADDRESS_BYTES);
|
|
187
|
+
return encodeBase58(bytes);
|
|
188
|
+
}
|
|
189
|
+
function tronAddressToEvmHex(address, label = "address") {
|
|
190
|
+
if (HEX_20_BYTES_PATTERN.test(address)) return address.slice(2).toLowerCase();
|
|
191
|
+
if (HEX_20_BYTES_NO_PREFIX_PATTERN.test(address)) return address.toLowerCase();
|
|
192
|
+
const decoded = decodeBase58(address);
|
|
193
|
+
(0, import_sun_sdk_core.sdkInvariant)(
|
|
194
|
+
decoded.length === TRON_ADDRESS_PAYLOAD_BYTES,
|
|
195
|
+
import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
|
|
196
|
+
`${label} must be a TRON base58 address or 20-byte EVM hex address`,
|
|
197
|
+
{ label, value: address }
|
|
198
|
+
);
|
|
199
|
+
const body = decoded.slice(0, TRON_ADDRESS_BYTES);
|
|
200
|
+
const expectedChecksum = checksum(body);
|
|
201
|
+
const actualChecksum = decoded.slice(TRON_ADDRESS_BYTES);
|
|
202
|
+
(0, import_sun_sdk_core.sdkInvariant)(
|
|
203
|
+
bytesToHex(expectedChecksum) === bytesToHex(actualChecksum),
|
|
204
|
+
import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
|
|
205
|
+
`${label} has invalid TRON base58 checksum`,
|
|
206
|
+
{ label, value: address }
|
|
207
|
+
);
|
|
208
|
+
(0, import_sun_sdk_core.sdkInvariant)(body[0] === 65, import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must use TRON 0x41 prefix`, {
|
|
209
|
+
label,
|
|
210
|
+
value: address
|
|
211
|
+
});
|
|
212
|
+
return bytesToHex(body.slice(1));
|
|
213
|
+
}
|
|
214
|
+
function evmHexToTronAddress(address, label = "address") {
|
|
215
|
+
(0, import_sun_sdk_core.sdkInvariant)(HEX_20_BYTES_PATTERN.test(address), import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be a 20-byte EVM hex address`, {
|
|
216
|
+
label,
|
|
217
|
+
value: address
|
|
218
|
+
});
|
|
219
|
+
return tronPayloadToBase58(hexToBytes(`${TRON_PREFIX_HEX}${address.slice(2)}`, label));
|
|
220
|
+
}
|
|
221
|
+
function tronCreate2Address(params) {
|
|
222
|
+
const factory = tronAddressToEvmHex(params.factoryAddress, "factory");
|
|
223
|
+
const salt = normalizeV2InitCodeHash(params.salt);
|
|
224
|
+
const initCodeHash = normalizeV2InitCodeHash(params.initCodeHash);
|
|
225
|
+
const hash = (0, import_keccak256.keccak256)(hexToBytes(`${TRON_PREFIX_HEX}${factory}${salt}${initCodeHash}`, "CREATE2 input")).slice(2);
|
|
226
|
+
return tronPayloadToBase58(hexToBytes(`${TRON_PREFIX_HEX}${hash.slice(-40)}`, "contract address"));
|
|
227
|
+
}
|
|
228
|
+
function normalizeV2InitCodeHash(value) {
|
|
229
|
+
(0, import_sun_sdk_core.sdkInvariant)(HEX_32_BYTES_PATTERN.test(value), import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "V2 initCodeHash must be bytes32 hex", {
|
|
230
|
+
value
|
|
231
|
+
});
|
|
232
|
+
return value.startsWith("0x") ? value.slice(2).toLowerCase() : value.toLowerCase();
|
|
233
|
+
}
|
|
234
|
+
function normalizeV2TokenAddress(address, wrappedNative, label) {
|
|
235
|
+
const normalized = address === "T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb" ? wrappedNative : address;
|
|
236
|
+
return tronAddressToEvmHex(normalized, label);
|
|
237
|
+
}
|
|
238
|
+
function computeV2PairAddress(params) {
|
|
239
|
+
const wrappedNative = params.wrappedNative ?? (0, import_sun_sdk_chains.getWrappedNativeAddress)(params.network);
|
|
240
|
+
const tokenA = normalizeV2TokenAddress(params.tokenA, wrappedNative, "tokenA");
|
|
241
|
+
const tokenB = normalizeV2TokenAddress(params.tokenB, wrappedNative, "tokenB");
|
|
242
|
+
(0, import_sun_sdk_core.sdkInvariant)(tokenA !== tokenB, import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "V2 pair tokens must be different", {
|
|
243
|
+
tokenA: params.tokenA,
|
|
244
|
+
tokenB: params.tokenB
|
|
245
|
+
});
|
|
246
|
+
const [token0, token1] = tokenA < tokenB ? [tokenA, tokenB] : [tokenB, tokenA];
|
|
247
|
+
const factory = tronAddressToEvmHex(params.factory ?? (0, import_sun_sdk_chains.getContractAddress)(params.network, "sunswapV2Factory"), "factory");
|
|
248
|
+
const tokenHash = (0, import_keccak256.keccak256)(hexToBytes(`${token0}${token1}`, "token salt")).slice(2);
|
|
249
|
+
const initCodeHash = normalizeV2InitCodeHash(params.initCodeHash ?? V2_INIT_CODE_HASH[params.network]);
|
|
250
|
+
return tronCreate2Address({ factoryAddress: factory, salt: tokenHash, initCodeHash });
|
|
251
|
+
}
|
|
252
|
+
function createV2PairKey(input) {
|
|
253
|
+
const [token0, token1] = sortV2Tokens(input.tokenA, input.tokenB);
|
|
254
|
+
return { network: input.network, token0, token1 };
|
|
255
|
+
}
|
|
256
|
+
function quoteV2LiquidityAmount(amountA, reserveA, reserveB) {
|
|
257
|
+
const amount = toBigInt(amountA);
|
|
258
|
+
const reserveIn = toBigInt(reserveA);
|
|
259
|
+
const reserveOut = toBigInt(reserveB);
|
|
260
|
+
validatePositive(amount, "amountA");
|
|
261
|
+
validatePositive(reserveIn, "reserveA");
|
|
262
|
+
validatePositive(reserveOut, "reserveB");
|
|
263
|
+
return (amount * reserveOut / reserveIn).toString();
|
|
264
|
+
}
|
|
265
|
+
function applyV2SlippageMin(amount, slippageTolerance) {
|
|
266
|
+
(0, import_sun_sdk_core.sdkInvariant)(
|
|
267
|
+
!slippageTolerance.lessThan(0),
|
|
268
|
+
import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
|
|
269
|
+
"Slippage tolerance cannot be negative",
|
|
270
|
+
{ slippageTolerance: slippageTolerance.toSignificant() }
|
|
271
|
+
);
|
|
272
|
+
(0, import_sun_sdk_core.sdkInvariant)(
|
|
273
|
+
!slippageTolerance.greaterThan(1),
|
|
274
|
+
import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
|
|
275
|
+
"Slippage tolerance cannot exceed 100%",
|
|
276
|
+
{ slippageTolerance: slippageTolerance.toSignificant() }
|
|
277
|
+
);
|
|
278
|
+
return new import_sun_sdk_core.Percent(1).subtract(slippageTolerance).multiply(amount.toString()).quotient.toString();
|
|
279
|
+
}
|
|
280
|
+
function getV2AddLiquidityMinimums(amounts, slippageTolerance) {
|
|
281
|
+
return {
|
|
282
|
+
amountAMin: applyV2SlippageMin(amounts.amountA, slippageTolerance),
|
|
283
|
+
amountBMin: applyV2SlippageMin(amounts.amountB, slippageTolerance)
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function getV2RemoveLiquidityMinimums(amounts, slippageTolerance) {
|
|
287
|
+
return getV2AddLiquidityMinimums(amounts, slippageTolerance);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/actions.ts
|
|
291
|
+
var V2_ROUTER_SELECTORS = {
|
|
292
|
+
addLiquidity: "addLiquidity(address,address,uint256,uint256,uint256,uint256,address,uint256)",
|
|
293
|
+
addLiquidityETH: "addLiquidityETH(address,uint256,uint256,uint256,address,uint256)",
|
|
294
|
+
removeLiquidity: "removeLiquidity(address,address,uint256,uint256,uint256,address,uint256)",
|
|
295
|
+
removeLiquidityETH: "removeLiquidityETH(address,uint256,uint256,uint256,address,uint256)",
|
|
296
|
+
swapExactETHForTokens: "swapExactETHForTokens(uint256,address[],address,uint256)",
|
|
297
|
+
swapETHForExactTokens: "swapETHForExactTokens(uint256,address[],address,uint256)",
|
|
298
|
+
swapExactTokensForETH: "swapExactTokensForETH(uint256,uint256,address[],address,uint256)",
|
|
299
|
+
swapExactTokensForTokens: "swapExactTokensForTokens(uint256,uint256,address[],address,uint256)",
|
|
300
|
+
swapTokensForExactETH: "swapTokensForExactETH(uint256,uint256,address[],address,uint256)",
|
|
301
|
+
swapTokensForExactTokens: "swapTokensForExactTokens(uint256,uint256,address[],address,uint256)"
|
|
302
|
+
};
|
|
303
|
+
function routerTarget(params) {
|
|
304
|
+
return params.router ?? (0, import_sun_sdk_chains2.getContractAddress)(params.network, "sunswapV2Router");
|
|
305
|
+
}
|
|
306
|
+
function valueOf(value) {
|
|
307
|
+
return value.toString();
|
|
308
|
+
}
|
|
309
|
+
function actionId(params, suffix) {
|
|
310
|
+
return params.id ?? `sunswap-v2-${suffix}-${params.network}`;
|
|
311
|
+
}
|
|
312
|
+
function buildV2AddLiquidityAction(params) {
|
|
313
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
314
|
+
id: actionId(params, "add-liquidity"),
|
|
315
|
+
target: routerTarget(params),
|
|
316
|
+
functionSelector: V2_ROUTER_SELECTORS.addLiquidity,
|
|
317
|
+
parameters: [
|
|
318
|
+
{ type: "address", value: evmHexToTronAddress(params.tokenA.address, "tokenA") },
|
|
319
|
+
{ type: "address", value: evmHexToTronAddress(params.tokenB.address, "tokenB") },
|
|
320
|
+
{ type: "uint256", value: valueOf(params.amountADesired) },
|
|
321
|
+
{ type: "uint256", value: valueOf(params.amountBDesired) },
|
|
322
|
+
{ type: "uint256", value: valueOf(params.amountAMin) },
|
|
323
|
+
{ type: "uint256", value: valueOf(params.amountBMin) },
|
|
324
|
+
{ type: "address", value: params.recipient },
|
|
325
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
326
|
+
],
|
|
327
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
function buildV2RemoveLiquidityAction(params) {
|
|
331
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
332
|
+
id: actionId(params, "remove-liquidity"),
|
|
333
|
+
target: routerTarget(params),
|
|
334
|
+
functionSelector: V2_ROUTER_SELECTORS.removeLiquidity,
|
|
335
|
+
parameters: [
|
|
336
|
+
{ type: "address", value: evmHexToTronAddress(params.tokenA.address, "tokenA") },
|
|
337
|
+
{ type: "address", value: evmHexToTronAddress(params.tokenB.address, "tokenB") },
|
|
338
|
+
{ type: "uint256", value: valueOf(params.liquidity) },
|
|
339
|
+
{ type: "uint256", value: valueOf(params.amountAMin) },
|
|
340
|
+
{ type: "uint256", value: valueOf(params.amountBMin) },
|
|
341
|
+
{ type: "address", value: params.recipient },
|
|
342
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
343
|
+
],
|
|
344
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function buildV2AddLiquidityEthAction(params) {
|
|
348
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
349
|
+
id: actionId(params, "add-liquidity-eth"),
|
|
350
|
+
target: routerTarget(params),
|
|
351
|
+
functionSelector: V2_ROUTER_SELECTORS.addLiquidityETH,
|
|
352
|
+
parameters: [
|
|
353
|
+
{ type: "address", value: evmHexToTronAddress(params.token.address, "token") },
|
|
354
|
+
{ type: "uint256", value: valueOf(params.amountTokenDesired) },
|
|
355
|
+
{ type: "uint256", value: valueOf(params.amountTokenMin) },
|
|
356
|
+
{ type: "uint256", value: valueOf(params.amountEthMin) },
|
|
357
|
+
{ type: "address", value: params.recipient },
|
|
358
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
359
|
+
],
|
|
360
|
+
callValue: BigInt(valueOf(params.amountEthDesired)),
|
|
361
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
function buildV2RemoveLiquidityEthAction(params) {
|
|
365
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
366
|
+
id: actionId(params, "remove-liquidity-eth"),
|
|
367
|
+
target: routerTarget(params),
|
|
368
|
+
functionSelector: V2_ROUTER_SELECTORS.removeLiquidityETH,
|
|
369
|
+
parameters: [
|
|
370
|
+
{ type: "address", value: evmHexToTronAddress(params.token.address, "token") },
|
|
371
|
+
{ type: "uint256", value: valueOf(params.liquidity) },
|
|
372
|
+
{ type: "uint256", value: valueOf(params.amountTokenMin) },
|
|
373
|
+
{ type: "uint256", value: valueOf(params.amountEthMin) },
|
|
374
|
+
{ type: "address", value: params.recipient },
|
|
375
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
376
|
+
],
|
|
377
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
function buildV2SwapExactEthForTokensAction(params) {
|
|
381
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
382
|
+
id: actionId(params, "swap-exact-eth-for-tokens"),
|
|
383
|
+
target: routerTarget(params),
|
|
384
|
+
functionSelector: V2_ROUTER_SELECTORS.swapExactETHForTokens,
|
|
385
|
+
parameters: [
|
|
386
|
+
{ type: "uint256", value: valueOf(params.amountOutMin) },
|
|
387
|
+
{ type: "address[]", value: params.path },
|
|
388
|
+
{ type: "address", value: params.recipient },
|
|
389
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
390
|
+
],
|
|
391
|
+
callValue: BigInt(valueOf(params.amountIn)),
|
|
392
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
function buildV2SwapEthForExactTokensAction(params) {
|
|
396
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
397
|
+
id: actionId(params, "swap-eth-for-exact-tokens"),
|
|
398
|
+
target: routerTarget(params),
|
|
399
|
+
functionSelector: V2_ROUTER_SELECTORS.swapETHForExactTokens,
|
|
400
|
+
parameters: [
|
|
401
|
+
{ type: "uint256", value: valueOf(params.amountOut) },
|
|
402
|
+
{ type: "address[]", value: params.path },
|
|
403
|
+
{ type: "address", value: params.recipient },
|
|
404
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
405
|
+
],
|
|
406
|
+
callValue: BigInt(valueOf(params.amountInMax)),
|
|
407
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
function buildV2SwapExactTokensForEthAction(params) {
|
|
411
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
412
|
+
id: actionId(params, "swap-exact-tokens-for-eth"),
|
|
413
|
+
target: routerTarget(params),
|
|
414
|
+
functionSelector: V2_ROUTER_SELECTORS.swapExactTokensForETH,
|
|
415
|
+
parameters: [
|
|
416
|
+
{ type: "uint256", value: valueOf(params.amountIn) },
|
|
417
|
+
{ type: "uint256", value: valueOf(params.amountOutMin) },
|
|
418
|
+
{ type: "address[]", value: params.path },
|
|
419
|
+
{ type: "address", value: params.recipient },
|
|
420
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
421
|
+
],
|
|
422
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
function buildV2SwapExactTokensForTokensAction(params) {
|
|
426
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
427
|
+
id: actionId(params, "swap-exact-tokens-for-tokens"),
|
|
428
|
+
target: routerTarget(params),
|
|
429
|
+
functionSelector: V2_ROUTER_SELECTORS.swapExactTokensForTokens,
|
|
430
|
+
parameters: [
|
|
431
|
+
{ type: "uint256", value: valueOf(params.amountIn) },
|
|
432
|
+
{ type: "uint256", value: valueOf(params.amountOutMin) },
|
|
433
|
+
{ type: "address[]", value: params.path },
|
|
434
|
+
{ type: "address", value: params.recipient },
|
|
435
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
436
|
+
],
|
|
437
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
function buildV2SwapTokensForExactEthAction(params) {
|
|
441
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
442
|
+
id: actionId(params, "swap-tokens-for-exact-eth"),
|
|
443
|
+
target: routerTarget(params),
|
|
444
|
+
functionSelector: V2_ROUTER_SELECTORS.swapTokensForExactETH,
|
|
445
|
+
parameters: [
|
|
446
|
+
{ type: "uint256", value: valueOf(params.amountOut) },
|
|
447
|
+
{ type: "uint256", value: valueOf(params.amountInMax) },
|
|
448
|
+
{ type: "address[]", value: params.path },
|
|
449
|
+
{ type: "address", value: params.recipient },
|
|
450
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
451
|
+
],
|
|
452
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
function buildV2SwapTokensForExactTokensAction(params) {
|
|
456
|
+
return (0, import_sun_sdk_core2.createContractCallAction)({
|
|
457
|
+
id: actionId(params, "swap-tokens-for-exact-tokens"),
|
|
458
|
+
target: routerTarget(params),
|
|
459
|
+
functionSelector: V2_ROUTER_SELECTORS.swapTokensForExactTokens,
|
|
460
|
+
parameters: [
|
|
461
|
+
{ type: "uint256", value: valueOf(params.amountOut) },
|
|
462
|
+
{ type: "uint256", value: valueOf(params.amountInMax) },
|
|
463
|
+
{ type: "address[]", value: params.path },
|
|
464
|
+
{ type: "address", value: params.recipient },
|
|
465
|
+
{ type: "uint256", value: valueOf(params.deadline) }
|
|
466
|
+
],
|
|
467
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
function buildV2LpApproveAction(params) {
|
|
471
|
+
return (0, import_sun_sdk_core2.createApproveAction)({
|
|
472
|
+
id: params.id ?? `sunswap-v2-lp-approve-${params.pair}`,
|
|
473
|
+
target: params.pair,
|
|
474
|
+
spender: params.spender,
|
|
475
|
+
amount: valueOf(params.amount),
|
|
476
|
+
...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {}
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// src/constants.ts
|
|
481
|
+
var import_sun_sdk_core3 = require("@sun-protocol/sun-sdk-core");
|
|
482
|
+
var import_jsbi = __toESM(require("jsbi"), 1);
|
|
483
|
+
var FACTORY_ADDRESS = "0x689abaeeed3f0bb3585773192e23224cac25dd41";
|
|
484
|
+
var FACTORY_ADDRESS_MAP = {
|
|
485
|
+
728126428: FACTORY_ADDRESS,
|
|
486
|
+
3448148188: "0x55f7d5d874a73f21c0851c62d374307985f440fc"
|
|
487
|
+
};
|
|
488
|
+
var INIT_CODE_HASH = "0x6d3f89421f83e4b62e628de8fc7ff2b014a79bf8fd8e8b0ea46e4a1d9409b67d";
|
|
489
|
+
var INIT_CODE_HASH_MAP = {
|
|
490
|
+
728126428: INIT_CODE_HASH,
|
|
491
|
+
3448148188: "0x9dd9bfc2f6c1103a6c01d9c6a4044e4b8a9361f92df2728cdc3729922d56748e"
|
|
492
|
+
};
|
|
493
|
+
var MINIMUM_LIQUIDITY = import_jsbi.default.BigInt(1e3);
|
|
494
|
+
var ZERO = import_jsbi.default.BigInt(0);
|
|
495
|
+
var ONE = import_jsbi.default.BigInt(1);
|
|
496
|
+
var FIVE = import_jsbi.default.BigInt(5);
|
|
497
|
+
var _997 = import_jsbi.default.BigInt(997);
|
|
498
|
+
var _1000 = import_jsbi.default.BigInt(1e3);
|
|
499
|
+
var BASIS_POINTS = import_jsbi.default.BigInt(1e4);
|
|
500
|
+
var ZERO_PERCENT = new import_sun_sdk_core3.Percent(ZERO);
|
|
501
|
+
var ONE_HUNDRED_PERCENT = new import_sun_sdk_core3.Percent(ONE);
|
|
502
|
+
|
|
503
|
+
// src/errors.ts
|
|
504
|
+
var InsufficientReservesError = class extends Error {
|
|
505
|
+
isInsufficientReservesError = true;
|
|
506
|
+
constructor() {
|
|
507
|
+
super("Insufficient reserves");
|
|
508
|
+
this.name = this.constructor.name;
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
var InsufficientInputAmountError = class extends Error {
|
|
512
|
+
isInsufficientInputAmountError = true;
|
|
513
|
+
constructor() {
|
|
514
|
+
super("Insufficient input amount");
|
|
515
|
+
this.name = this.constructor.name;
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// src/entities/pair.ts
|
|
520
|
+
var import_bignumber = require("@ethersproject/bignumber");
|
|
521
|
+
var import_solidity = require("@ethersproject/solidity");
|
|
522
|
+
var import_sun_sdk_core4 = require("@sun-protocol/sun-sdk-core");
|
|
523
|
+
var import_jsbi2 = __toESM(require("jsbi"), 1);
|
|
524
|
+
var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
|
|
525
|
+
var computePairAddress = ({
|
|
526
|
+
factoryAddress,
|
|
527
|
+
tokenA,
|
|
528
|
+
tokenB,
|
|
529
|
+
initCodeHashManualOverride
|
|
530
|
+
}) => {
|
|
531
|
+
const [token0, token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA];
|
|
532
|
+
const salt = (0, import_solidity.keccak256)(["bytes"], [(0, import_solidity.pack)(["address", "address"], [token0.address, token1.address])]);
|
|
533
|
+
const tronAddress = tronCreate2Address({
|
|
534
|
+
factoryAddress,
|
|
535
|
+
salt,
|
|
536
|
+
initCodeHash: initCodeHashManualOverride ?? INIT_CODE_HASH_MAP[tokenA.chainId] ?? INIT_CODE_HASH
|
|
537
|
+
});
|
|
538
|
+
return `0x${tronAddressToEvmHex(tronAddress)}`;
|
|
539
|
+
};
|
|
540
|
+
var Pair = class _Pair {
|
|
541
|
+
liquidityToken;
|
|
542
|
+
tokenAmounts;
|
|
543
|
+
static getAddress(tokenA, tokenB) {
|
|
544
|
+
const factoryAddress = FACTORY_ADDRESS_MAP[tokenA.chainId] ?? FACTORY_ADDRESS;
|
|
545
|
+
return computePairAddress({ factoryAddress, tokenA, tokenB });
|
|
546
|
+
}
|
|
547
|
+
constructor(currencyAmountA, tokenAmountB) {
|
|
548
|
+
const tokenAmounts = currencyAmountA.currency.sortsBefore(tokenAmountB.currency) ? [currencyAmountA, tokenAmountB] : [tokenAmountB, currencyAmountA];
|
|
549
|
+
this.liquidityToken = new import_sun_sdk_core4.Token(
|
|
550
|
+
tokenAmounts[0].currency.chainId,
|
|
551
|
+
_Pair.getAddress(tokenAmounts[0].currency, tokenAmounts[1].currency),
|
|
552
|
+
18,
|
|
553
|
+
"UNI-V2",
|
|
554
|
+
"Uniswap V2"
|
|
555
|
+
);
|
|
556
|
+
this.tokenAmounts = tokenAmounts;
|
|
557
|
+
}
|
|
558
|
+
involvesToken(token) {
|
|
559
|
+
return token.equals(this.token0) || token.equals(this.token1);
|
|
560
|
+
}
|
|
561
|
+
get token0Price() {
|
|
562
|
+
const result = this.tokenAmounts[1].divide(this.tokenAmounts[0]);
|
|
563
|
+
return new import_sun_sdk_core4.Price(this.token0, this.token1, result.denominator, result.numerator);
|
|
564
|
+
}
|
|
565
|
+
get token1Price() {
|
|
566
|
+
const result = this.tokenAmounts[0].divide(this.tokenAmounts[1]);
|
|
567
|
+
return new import_sun_sdk_core4.Price(this.token1, this.token0, result.denominator, result.numerator);
|
|
568
|
+
}
|
|
569
|
+
priceOf(token) {
|
|
570
|
+
(0, import_tiny_invariant.default)(this.involvesToken(token), "TOKEN");
|
|
571
|
+
return token.equals(this.token0) ? this.token0Price : this.token1Price;
|
|
572
|
+
}
|
|
573
|
+
get chainId() {
|
|
574
|
+
return this.token0.chainId;
|
|
575
|
+
}
|
|
576
|
+
get token0() {
|
|
577
|
+
return this.tokenAmounts[0].currency;
|
|
578
|
+
}
|
|
579
|
+
get token1() {
|
|
580
|
+
return this.tokenAmounts[1].currency;
|
|
581
|
+
}
|
|
582
|
+
get reserve0() {
|
|
583
|
+
return this.tokenAmounts[0];
|
|
584
|
+
}
|
|
585
|
+
get reserve1() {
|
|
586
|
+
return this.tokenAmounts[1];
|
|
587
|
+
}
|
|
588
|
+
reserveOf(token) {
|
|
589
|
+
(0, import_tiny_invariant.default)(this.involvesToken(token), "TOKEN");
|
|
590
|
+
return token.equals(this.token0) ? this.reserve0 : this.reserve1;
|
|
591
|
+
}
|
|
592
|
+
getOutputAmount(inputAmount, calculateFotFees = true) {
|
|
593
|
+
(0, import_tiny_invariant.default)(this.involvesToken(inputAmount.currency), "TOKEN");
|
|
594
|
+
if (import_jsbi2.default.equal(this.reserve0.quotient, ZERO) || import_jsbi2.default.equal(this.reserve1.quotient, ZERO)) {
|
|
595
|
+
throw new InsufficientReservesError();
|
|
596
|
+
}
|
|
597
|
+
const inputReserve = this.reserveOf(inputAmount.currency);
|
|
598
|
+
const outputReserve = this.reserveOf(inputAmount.currency.equals(this.token0) ? this.token1 : this.token0);
|
|
599
|
+
const percentAfterSellFees = calculateFotFees ? this.derivePercentAfterSellFees(inputAmount) : ZERO_PERCENT;
|
|
600
|
+
const inputAmountAfterTax = percentAfterSellFees.greaterThan(ZERO_PERCENT) ? import_sun_sdk_core4.CurrencyAmount.fromRawAmount(inputAmount.currency, percentAfterSellFees.multiply(inputAmount).quotient) : inputAmount;
|
|
601
|
+
const inputAmountWithFeeAndAfterTax = import_jsbi2.default.multiply(inputAmountAfterTax.quotient, _997);
|
|
602
|
+
const numerator = import_jsbi2.default.multiply(inputAmountWithFeeAndAfterTax, outputReserve.quotient);
|
|
603
|
+
const denominator = import_jsbi2.default.add(import_jsbi2.default.multiply(inputReserve.quotient, _1000), inputAmountWithFeeAndAfterTax);
|
|
604
|
+
const outputAmount = import_sun_sdk_core4.CurrencyAmount.fromRawAmount(
|
|
605
|
+
inputAmount.currency.equals(this.token0) ? this.token1 : this.token0,
|
|
606
|
+
import_jsbi2.default.divide(numerator, denominator)
|
|
607
|
+
);
|
|
608
|
+
if (import_jsbi2.default.equal(outputAmount.quotient, ZERO)) {
|
|
609
|
+
throw new InsufficientInputAmountError();
|
|
610
|
+
}
|
|
611
|
+
const percentAfterBuyFees = calculateFotFees ? this.derivePercentAfterBuyFees(outputAmount) : ZERO_PERCENT;
|
|
612
|
+
const outputAmountAfterTax = percentAfterBuyFees.greaterThan(ZERO_PERCENT) ? import_sun_sdk_core4.CurrencyAmount.fromRawAmount(outputAmount.currency, outputAmount.multiply(percentAfterBuyFees).quotient) : outputAmount;
|
|
613
|
+
if (import_jsbi2.default.equal(outputAmountAfterTax.quotient, ZERO)) {
|
|
614
|
+
throw new InsufficientInputAmountError();
|
|
615
|
+
}
|
|
616
|
+
return [outputAmountAfterTax, new _Pair(inputReserve.add(inputAmountAfterTax), outputReserve.subtract(outputAmountAfterTax))];
|
|
617
|
+
}
|
|
618
|
+
getInputAmount(outputAmount, calculateFotFees = true) {
|
|
619
|
+
(0, import_tiny_invariant.default)(this.involvesToken(outputAmount.currency), "TOKEN");
|
|
620
|
+
const percentAfterBuyFees = calculateFotFees ? this.derivePercentAfterBuyFees(outputAmount) : ZERO_PERCENT;
|
|
621
|
+
const outputAmountBeforeTax = percentAfterBuyFees.greaterThan(ZERO_PERCENT) ? import_sun_sdk_core4.CurrencyAmount.fromRawAmount(outputAmount.currency, import_jsbi2.default.add(outputAmount.divide(percentAfterBuyFees).quotient, ONE)) : outputAmount;
|
|
622
|
+
if (import_jsbi2.default.equal(this.reserve0.quotient, ZERO) || import_jsbi2.default.equal(this.reserve1.quotient, ZERO) || import_jsbi2.default.greaterThanOrEqual(outputAmount.quotient, this.reserveOf(outputAmount.currency).quotient) || import_jsbi2.default.greaterThanOrEqual(outputAmountBeforeTax.quotient, this.reserveOf(outputAmount.currency).quotient)) {
|
|
623
|
+
throw new InsufficientReservesError();
|
|
624
|
+
}
|
|
625
|
+
const outputReserve = this.reserveOf(outputAmount.currency);
|
|
626
|
+
const inputReserve = this.reserveOf(outputAmount.currency.equals(this.token0) ? this.token1 : this.token0);
|
|
627
|
+
const numerator = import_jsbi2.default.multiply(import_jsbi2.default.multiply(inputReserve.quotient, outputAmountBeforeTax.quotient), _1000);
|
|
628
|
+
const denominator = import_jsbi2.default.multiply(import_jsbi2.default.subtract(outputReserve.quotient, outputAmountBeforeTax.quotient), _997);
|
|
629
|
+
const inputAmount = import_sun_sdk_core4.CurrencyAmount.fromRawAmount(
|
|
630
|
+
outputAmount.currency.equals(this.token0) ? this.token1 : this.token0,
|
|
631
|
+
import_jsbi2.default.add(import_jsbi2.default.divide(numerator, denominator), ONE)
|
|
632
|
+
);
|
|
633
|
+
const percentAfterSellFees = calculateFotFees ? this.derivePercentAfterSellFees(inputAmount) : ZERO_PERCENT;
|
|
634
|
+
const inputAmountBeforeTax = percentAfterSellFees.greaterThan(ZERO_PERCENT) ? import_sun_sdk_core4.CurrencyAmount.fromRawAmount(inputAmount.currency, import_jsbi2.default.add(inputAmount.divide(percentAfterSellFees).quotient, ONE)) : inputAmount;
|
|
635
|
+
return [inputAmountBeforeTax, new _Pair(inputReserve.add(inputAmount), outputReserve.subtract(outputAmount))];
|
|
636
|
+
}
|
|
637
|
+
getLiquidityMinted(totalSupply, tokenAmountA, tokenAmountB) {
|
|
638
|
+
(0, import_tiny_invariant.default)(totalSupply.currency.equals(this.liquidityToken), "LIQUIDITY");
|
|
639
|
+
const tokenAmounts = tokenAmountA.currency.sortsBefore(tokenAmountB.currency) ? [tokenAmountA, tokenAmountB] : [tokenAmountB, tokenAmountA];
|
|
640
|
+
(0, import_tiny_invariant.default)(tokenAmounts[0].currency.equals(this.token0) && tokenAmounts[1].currency.equals(this.token1), "TOKEN");
|
|
641
|
+
let liquidity;
|
|
642
|
+
if (import_jsbi2.default.equal(totalSupply.quotient, ZERO)) {
|
|
643
|
+
liquidity = import_jsbi2.default.subtract((0, import_sun_sdk_core4.sqrt)(import_jsbi2.default.multiply(tokenAmounts[0].quotient, tokenAmounts[1].quotient)), MINIMUM_LIQUIDITY);
|
|
644
|
+
} else {
|
|
645
|
+
const amount0 = import_jsbi2.default.divide(import_jsbi2.default.multiply(tokenAmounts[0].quotient, totalSupply.quotient), this.reserve0.quotient);
|
|
646
|
+
const amount1 = import_jsbi2.default.divide(import_jsbi2.default.multiply(tokenAmounts[1].quotient, totalSupply.quotient), this.reserve1.quotient);
|
|
647
|
+
liquidity = import_jsbi2.default.lessThanOrEqual(amount0, amount1) ? amount0 : amount1;
|
|
648
|
+
}
|
|
649
|
+
if (!import_jsbi2.default.greaterThan(liquidity, ZERO)) {
|
|
650
|
+
throw new InsufficientInputAmountError();
|
|
651
|
+
}
|
|
652
|
+
return import_sun_sdk_core4.CurrencyAmount.fromRawAmount(this.liquidityToken, liquidity);
|
|
653
|
+
}
|
|
654
|
+
getLiquidityValue(token, totalSupply, liquidity, feeOn = false, kLast) {
|
|
655
|
+
(0, import_tiny_invariant.default)(this.involvesToken(token), "TOKEN");
|
|
656
|
+
(0, import_tiny_invariant.default)(totalSupply.currency.equals(this.liquidityToken), "TOTAL_SUPPLY");
|
|
657
|
+
(0, import_tiny_invariant.default)(liquidity.currency.equals(this.liquidityToken), "LIQUIDITY");
|
|
658
|
+
(0, import_tiny_invariant.default)(import_jsbi2.default.lessThanOrEqual(liquidity.quotient, totalSupply.quotient), "LIQUIDITY");
|
|
659
|
+
let totalSupplyAdjusted;
|
|
660
|
+
if (!feeOn) {
|
|
661
|
+
totalSupplyAdjusted = totalSupply;
|
|
662
|
+
} else {
|
|
663
|
+
(0, import_tiny_invariant.default)(!!kLast, "K_LAST");
|
|
664
|
+
const kLastParsed = import_jsbi2.default.BigInt(kLast);
|
|
665
|
+
if (!import_jsbi2.default.equal(kLastParsed, ZERO)) {
|
|
666
|
+
const rootK = (0, import_sun_sdk_core4.sqrt)(import_jsbi2.default.multiply(this.reserve0.quotient, this.reserve1.quotient));
|
|
667
|
+
const rootKLast = (0, import_sun_sdk_core4.sqrt)(kLastParsed);
|
|
668
|
+
if (import_jsbi2.default.greaterThan(rootK, rootKLast)) {
|
|
669
|
+
const numerator = import_jsbi2.default.multiply(totalSupply.quotient, import_jsbi2.default.subtract(rootK, rootKLast));
|
|
670
|
+
const denominator = import_jsbi2.default.add(import_jsbi2.default.multiply(rootK, FIVE), rootKLast);
|
|
671
|
+
const feeLiquidity = import_jsbi2.default.divide(numerator, denominator);
|
|
672
|
+
totalSupplyAdjusted = totalSupply.add(import_sun_sdk_core4.CurrencyAmount.fromRawAmount(this.liquidityToken, feeLiquidity));
|
|
673
|
+
} else {
|
|
674
|
+
totalSupplyAdjusted = totalSupply;
|
|
675
|
+
}
|
|
676
|
+
} else {
|
|
677
|
+
totalSupplyAdjusted = totalSupply;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return import_sun_sdk_core4.CurrencyAmount.fromRawAmount(
|
|
681
|
+
token,
|
|
682
|
+
import_jsbi2.default.divide(import_jsbi2.default.multiply(liquidity.quotient, this.reserveOf(token).quotient), totalSupplyAdjusted.quotient)
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
derivePercentAfterSellFees(inputAmount) {
|
|
686
|
+
const sellFeeBips = this.token0.wrapped.equals(inputAmount.wrapped.currency) ? this.token0.wrapped.sellFeeBps : this.token1.wrapped.sellFeeBps;
|
|
687
|
+
if (sellFeeBips?.gt(import_bignumber.BigNumber.from(0))) {
|
|
688
|
+
return ONE_HUNDRED_PERCENT.subtract(new import_sun_sdk_core4.Percent(import_jsbi2.default.BigInt(sellFeeBips)).divide(BASIS_POINTS));
|
|
689
|
+
}
|
|
690
|
+
return ZERO_PERCENT;
|
|
691
|
+
}
|
|
692
|
+
derivePercentAfterBuyFees(outputAmount) {
|
|
693
|
+
const buyFeeBps = this.token0.wrapped.equals(outputAmount.wrapped.currency) ? this.token0.wrapped.buyFeeBps : this.token1.wrapped.buyFeeBps;
|
|
694
|
+
if (buyFeeBps?.gt(import_bignumber.BigNumber.from(0))) {
|
|
695
|
+
return ONE_HUNDRED_PERCENT.subtract(new import_sun_sdk_core4.Percent(import_jsbi2.default.BigInt(buyFeeBps)).divide(BASIS_POINTS));
|
|
696
|
+
}
|
|
697
|
+
return ZERO_PERCENT;
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
// src/entities/route.ts
|
|
702
|
+
var import_sun_sdk_core5 = require("@sun-protocol/sun-sdk-core");
|
|
703
|
+
var import_tiny_invariant2 = __toESM(require("tiny-invariant"), 1);
|
|
704
|
+
var Route = class {
|
|
705
|
+
pairs;
|
|
706
|
+
path;
|
|
707
|
+
input;
|
|
708
|
+
output;
|
|
709
|
+
_midPrice = null;
|
|
710
|
+
constructor(pairs, input, output) {
|
|
711
|
+
(0, import_tiny_invariant2.default)(pairs.length > 0, "PAIRS");
|
|
712
|
+
const firstPair = pairs[0];
|
|
713
|
+
const chainId = firstPair.chainId;
|
|
714
|
+
(0, import_tiny_invariant2.default)(pairs.every((pair) => pair.chainId === chainId), "CHAIN_IDS");
|
|
715
|
+
const wrappedInput = input.wrapped;
|
|
716
|
+
(0, import_tiny_invariant2.default)(firstPair.involvesToken(wrappedInput), "INPUT");
|
|
717
|
+
(0, import_tiny_invariant2.default)(typeof output === "undefined" || pairs[pairs.length - 1].involvesToken(output.wrapped), "OUTPUT");
|
|
718
|
+
const path = [wrappedInput];
|
|
719
|
+
for (const [i, pair] of pairs.entries()) {
|
|
720
|
+
const currentInput = path[i];
|
|
721
|
+
(0, import_tiny_invariant2.default)(currentInput.equals(pair.token0) || currentInput.equals(pair.token1), "PATH");
|
|
722
|
+
const currentOutput = currentInput.equals(pair.token0) ? pair.token1 : pair.token0;
|
|
723
|
+
path.push(currentOutput);
|
|
724
|
+
}
|
|
725
|
+
this.pairs = pairs;
|
|
726
|
+
this.path = path;
|
|
727
|
+
this.input = input;
|
|
728
|
+
this.output = output ?? path[path.length - 1];
|
|
729
|
+
}
|
|
730
|
+
get midPrice() {
|
|
731
|
+
if (this._midPrice !== null) return this._midPrice;
|
|
732
|
+
const prices = [];
|
|
733
|
+
for (const [i, pair] of this.pairs.entries()) {
|
|
734
|
+
prices.push(
|
|
735
|
+
this.path[i].equals(pair.token0) ? new import_sun_sdk_core5.Price(pair.reserve0.currency, pair.reserve1.currency, pair.reserve0.quotient, pair.reserve1.quotient) : new import_sun_sdk_core5.Price(pair.reserve1.currency, pair.reserve0.currency, pair.reserve1.quotient, pair.reserve0.quotient)
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
const reduced = prices.slice(1).reduce((accumulator, currentValue) => accumulator.multiply(currentValue), prices[0]);
|
|
739
|
+
return this._midPrice = new import_sun_sdk_core5.Price(this.input, this.output, reduced.denominator, reduced.numerator);
|
|
740
|
+
}
|
|
741
|
+
get chainId() {
|
|
742
|
+
return this.pairs[0].chainId;
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
// src/entities/trade.ts
|
|
747
|
+
var import_sun_sdk_core6 = require("@sun-protocol/sun-sdk-core");
|
|
748
|
+
var import_jsbi3 = __toESM(require("jsbi"), 1);
|
|
749
|
+
var import_tiny_invariant3 = __toESM(require("tiny-invariant"), 1);
|
|
750
|
+
function inputOutputComparator(a, b) {
|
|
751
|
+
(0, import_tiny_invariant3.default)(a.inputAmount.currency.equals(b.inputAmount.currency), "INPUT_CURRENCY");
|
|
752
|
+
(0, import_tiny_invariant3.default)(a.outputAmount.currency.equals(b.outputAmount.currency), "OUTPUT_CURRENCY");
|
|
753
|
+
if (a.outputAmount.equalTo(b.outputAmount)) {
|
|
754
|
+
if (a.inputAmount.equalTo(b.inputAmount)) return 0;
|
|
755
|
+
return a.inputAmount.lessThan(b.inputAmount) ? -1 : 1;
|
|
756
|
+
}
|
|
757
|
+
return a.outputAmount.lessThan(b.outputAmount) ? 1 : -1;
|
|
758
|
+
}
|
|
759
|
+
function tradeComparator(a, b) {
|
|
760
|
+
const ioComp = inputOutputComparator(a, b);
|
|
761
|
+
if (ioComp !== 0) return ioComp;
|
|
762
|
+
if (a.priceImpact.lessThan(b.priceImpact)) return -1;
|
|
763
|
+
if (a.priceImpact.greaterThan(b.priceImpact)) return 1;
|
|
764
|
+
return a.route.path.length - b.route.path.length;
|
|
765
|
+
}
|
|
766
|
+
var Trade = class _Trade {
|
|
767
|
+
route;
|
|
768
|
+
tradeType;
|
|
769
|
+
inputAmount;
|
|
770
|
+
outputAmount;
|
|
771
|
+
executionPrice;
|
|
772
|
+
priceImpact;
|
|
773
|
+
static exactIn(route, amountIn) {
|
|
774
|
+
return new _Trade(route, amountIn, import_sun_sdk_core6.TradeType.EXACT_INPUT);
|
|
775
|
+
}
|
|
776
|
+
static exactOut(route, amountOut) {
|
|
777
|
+
return new _Trade(route, amountOut, import_sun_sdk_core6.TradeType.EXACT_OUTPUT);
|
|
778
|
+
}
|
|
779
|
+
constructor(route, amount, tradeType) {
|
|
780
|
+
this.route = route;
|
|
781
|
+
this.tradeType = tradeType;
|
|
782
|
+
const tokenAmounts = new Array(route.path.length);
|
|
783
|
+
if (tradeType === import_sun_sdk_core6.TradeType.EXACT_INPUT) {
|
|
784
|
+
(0, import_tiny_invariant3.default)(amount.currency.equals(route.input), "INPUT");
|
|
785
|
+
tokenAmounts[0] = amount.wrapped;
|
|
786
|
+
for (let i = 0; i < route.path.length - 1; i += 1) {
|
|
787
|
+
const pair = route.pairs[i];
|
|
788
|
+
const [outputAmount] = pair.getOutputAmount(tokenAmounts[i].wrapped);
|
|
789
|
+
tokenAmounts[i + 1] = outputAmount;
|
|
790
|
+
}
|
|
791
|
+
this.inputAmount = import_sun_sdk_core6.CurrencyAmount.fromFractionalAmount(route.input, amount.numerator, amount.denominator);
|
|
792
|
+
this.outputAmount = import_sun_sdk_core6.CurrencyAmount.fromFractionalAmount(
|
|
793
|
+
route.output,
|
|
794
|
+
tokenAmounts[tokenAmounts.length - 1].numerator,
|
|
795
|
+
tokenAmounts[tokenAmounts.length - 1].denominator
|
|
796
|
+
);
|
|
797
|
+
} else {
|
|
798
|
+
(0, import_tiny_invariant3.default)(amount.currency.equals(route.output), "OUTPUT");
|
|
799
|
+
tokenAmounts[tokenAmounts.length - 1] = amount.wrapped;
|
|
800
|
+
for (let i = route.path.length - 1; i > 0; i -= 1) {
|
|
801
|
+
const pair = route.pairs[i - 1];
|
|
802
|
+
const [inputAmount] = pair.getInputAmount(tokenAmounts[i].wrapped);
|
|
803
|
+
tokenAmounts[i - 1] = inputAmount;
|
|
804
|
+
}
|
|
805
|
+
this.inputAmount = import_sun_sdk_core6.CurrencyAmount.fromFractionalAmount(route.input, tokenAmounts[0].numerator, tokenAmounts[0].denominator);
|
|
806
|
+
this.outputAmount = import_sun_sdk_core6.CurrencyAmount.fromFractionalAmount(route.output, amount.numerator, amount.denominator);
|
|
807
|
+
}
|
|
808
|
+
this.executionPrice = new import_sun_sdk_core6.Price(this.inputAmount.currency, this.outputAmount.currency, this.inputAmount.quotient, this.outputAmount.quotient);
|
|
809
|
+
this.priceImpact = (0, import_sun_sdk_core6.computePriceImpact)(route.midPrice, this.inputAmount, this.outputAmount);
|
|
810
|
+
}
|
|
811
|
+
minimumAmountOut(slippageTolerance) {
|
|
812
|
+
(0, import_tiny_invariant3.default)(!slippageTolerance.lessThan(ZERO), "SLIPPAGE_TOLERANCE");
|
|
813
|
+
if (this.tradeType === import_sun_sdk_core6.TradeType.EXACT_OUTPUT) return this.outputAmount;
|
|
814
|
+
const slippageAdjustedAmountOut = new import_sun_sdk_core6.Fraction(ONE).subtract(slippageTolerance).multiply(this.outputAmount.quotient).quotient;
|
|
815
|
+
const clampedAmount = import_jsbi3.default.greaterThan(slippageAdjustedAmountOut, import_jsbi3.default.BigInt(0)) ? slippageAdjustedAmountOut : import_jsbi3.default.BigInt(0);
|
|
816
|
+
return import_sun_sdk_core6.CurrencyAmount.fromRawAmount(this.outputAmount.currency, clampedAmount);
|
|
817
|
+
}
|
|
818
|
+
maximumAmountIn(slippageTolerance) {
|
|
819
|
+
(0, import_tiny_invariant3.default)(!slippageTolerance.lessThan(ZERO), "SLIPPAGE_TOLERANCE");
|
|
820
|
+
if (this.tradeType === import_sun_sdk_core6.TradeType.EXACT_INPUT) return this.inputAmount;
|
|
821
|
+
const slippageAdjustedAmountIn = new import_sun_sdk_core6.Fraction(ONE).add(slippageTolerance).multiply(this.inputAmount.quotient).quotient;
|
|
822
|
+
return import_sun_sdk_core6.CurrencyAmount.fromRawAmount(this.inputAmount.currency, slippageAdjustedAmountIn);
|
|
823
|
+
}
|
|
824
|
+
static bestTradeExactIn(pairs, currencyAmountIn, currencyOut, { maxNumResults = 3, maxHops = 3 } = {}, currentPairs = [], nextAmountIn = currencyAmountIn, bestTrades = []) {
|
|
825
|
+
(0, import_tiny_invariant3.default)(pairs.length > 0, "PAIRS");
|
|
826
|
+
(0, import_tiny_invariant3.default)(maxHops > 0, "MAX_HOPS");
|
|
827
|
+
(0, import_tiny_invariant3.default)(currencyAmountIn === nextAmountIn || currentPairs.length > 0, "INVALID_RECURSION");
|
|
828
|
+
const amountIn = nextAmountIn.wrapped;
|
|
829
|
+
const tokenOut = currencyOut.wrapped;
|
|
830
|
+
for (let i = 0; i < pairs.length; i += 1) {
|
|
831
|
+
const pair = pairs[i];
|
|
832
|
+
if (!pair.token0.equals(amountIn.currency) && !pair.token1.equals(amountIn.currency)) continue;
|
|
833
|
+
if (pair.reserve0.equalTo(ZERO) || pair.reserve1.equalTo(ZERO)) continue;
|
|
834
|
+
let amountOut;
|
|
835
|
+
try {
|
|
836
|
+
;
|
|
837
|
+
[amountOut] = pair.getOutputAmount(amountIn);
|
|
838
|
+
} catch (error) {
|
|
839
|
+
if (error.isInsufficientInputAmountError) continue;
|
|
840
|
+
throw error;
|
|
841
|
+
}
|
|
842
|
+
if (amountOut.currency.equals(tokenOut)) {
|
|
843
|
+
(0, import_sun_sdk_core6.sortedInsert)(
|
|
844
|
+
bestTrades,
|
|
845
|
+
new _Trade(new Route([...currentPairs, pair], currencyAmountIn.currency, currencyOut), currencyAmountIn, import_sun_sdk_core6.TradeType.EXACT_INPUT),
|
|
846
|
+
maxNumResults,
|
|
847
|
+
tradeComparator
|
|
848
|
+
);
|
|
849
|
+
} else if (maxHops > 1 && pairs.length > 1) {
|
|
850
|
+
const pairsExcludingThisPair = pairs.slice(0, i).concat(pairs.slice(i + 1));
|
|
851
|
+
_Trade.bestTradeExactIn(
|
|
852
|
+
pairsExcludingThisPair,
|
|
853
|
+
currencyAmountIn,
|
|
854
|
+
currencyOut,
|
|
855
|
+
{ maxNumResults, maxHops: maxHops - 1 },
|
|
856
|
+
[...currentPairs, pair],
|
|
857
|
+
amountOut,
|
|
858
|
+
bestTrades
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
return bestTrades;
|
|
863
|
+
}
|
|
864
|
+
worstExecutionPrice(slippageTolerance) {
|
|
865
|
+
return new import_sun_sdk_core6.Price(
|
|
866
|
+
this.inputAmount.currency,
|
|
867
|
+
this.outputAmount.currency,
|
|
868
|
+
this.maximumAmountIn(slippageTolerance).quotient,
|
|
869
|
+
this.minimumAmountOut(slippageTolerance).quotient
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
static bestTradeExactOut(pairs, currencyIn, currencyAmountOut, { maxNumResults = 3, maxHops = 3 } = {}, currentPairs = [], nextAmountOut = currencyAmountOut, bestTrades = []) {
|
|
873
|
+
(0, import_tiny_invariant3.default)(pairs.length > 0, "PAIRS");
|
|
874
|
+
(0, import_tiny_invariant3.default)(maxHops > 0, "MAX_HOPS");
|
|
875
|
+
(0, import_tiny_invariant3.default)(currencyAmountOut === nextAmountOut || currentPairs.length > 0, "INVALID_RECURSION");
|
|
876
|
+
const amountOut = nextAmountOut.wrapped;
|
|
877
|
+
const tokenIn = currencyIn.wrapped;
|
|
878
|
+
for (let i = 0; i < pairs.length; i += 1) {
|
|
879
|
+
const pair = pairs[i];
|
|
880
|
+
if (!pair.token0.equals(amountOut.currency) && !pair.token1.equals(amountOut.currency)) continue;
|
|
881
|
+
if (pair.reserve0.equalTo(ZERO) || pair.reserve1.equalTo(ZERO)) continue;
|
|
882
|
+
let amountIn;
|
|
883
|
+
try {
|
|
884
|
+
;
|
|
885
|
+
[amountIn] = pair.getInputAmount(amountOut);
|
|
886
|
+
} catch (error) {
|
|
887
|
+
if (error.isInsufficientReservesError) continue;
|
|
888
|
+
throw error;
|
|
889
|
+
}
|
|
890
|
+
if (amountIn.currency.equals(tokenIn)) {
|
|
891
|
+
(0, import_sun_sdk_core6.sortedInsert)(
|
|
892
|
+
bestTrades,
|
|
893
|
+
new _Trade(new Route([pair, ...currentPairs], currencyIn, currencyAmountOut.currency), currencyAmountOut, import_sun_sdk_core6.TradeType.EXACT_OUTPUT),
|
|
894
|
+
maxNumResults,
|
|
895
|
+
tradeComparator
|
|
896
|
+
);
|
|
897
|
+
} else if (maxHops > 1 && pairs.length > 1) {
|
|
898
|
+
const pairsExcludingThisPair = pairs.slice(0, i).concat(pairs.slice(i + 1));
|
|
899
|
+
_Trade.bestTradeExactOut(
|
|
900
|
+
pairsExcludingThisPair,
|
|
901
|
+
currencyIn,
|
|
902
|
+
currencyAmountOut,
|
|
903
|
+
{ maxNumResults, maxHops: maxHops - 1 },
|
|
904
|
+
[pair, ...currentPairs],
|
|
905
|
+
amountIn,
|
|
906
|
+
bestTrades
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
return bestTrades;
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
// src/reads.ts
|
|
915
|
+
var import_sun_sdk_chains3 = require("@sun-protocol/sun-sdk-chains");
|
|
916
|
+
var V2_PAIR_READ_SELECTORS = {
|
|
917
|
+
getReserves: "getReserves()",
|
|
918
|
+
totalSupply: "totalSupply()",
|
|
919
|
+
kLast: "kLast()",
|
|
920
|
+
balanceOf: "balanceOf(address)",
|
|
921
|
+
allowance: "allowance(address,address)"
|
|
922
|
+
};
|
|
923
|
+
var V2_FACTORY_READ_SELECTORS = {
|
|
924
|
+
getPair: "getPair(address,address)",
|
|
925
|
+
feeTo: "feeTo()"
|
|
926
|
+
};
|
|
927
|
+
var V2_ROUTER_READ_SELECTORS = {
|
|
928
|
+
getAmountsOut: "getAmountsOut(uint256,address[])",
|
|
929
|
+
getAmountsIn: "getAmountsIn(uint256,address[])",
|
|
930
|
+
isAllowedTradingPair: "isAllowedTradingPair(address,address)"
|
|
931
|
+
};
|
|
932
|
+
function valueOf2(value) {
|
|
933
|
+
return value.toString();
|
|
934
|
+
}
|
|
935
|
+
function buildV2PairReservesRead(pair) {
|
|
936
|
+
return {
|
|
937
|
+
target: pair,
|
|
938
|
+
functionSelector: V2_PAIR_READ_SELECTORS.getReserves,
|
|
939
|
+
metadata: { protocol: "sunswap-v2", contract: "pair", action: "get-reserves" }
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
function buildV2PairTotalSupplyRead(pair) {
|
|
943
|
+
return {
|
|
944
|
+
target: pair,
|
|
945
|
+
functionSelector: V2_PAIR_READ_SELECTORS.totalSupply,
|
|
946
|
+
metadata: { protocol: "sunswap-v2", contract: "pair", action: "total-supply" }
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
function buildV2PairKLastRead(pair) {
|
|
950
|
+
return {
|
|
951
|
+
target: pair,
|
|
952
|
+
functionSelector: V2_PAIR_READ_SELECTORS.kLast,
|
|
953
|
+
outputs: [{ type: "uint256", name: "kLast" }],
|
|
954
|
+
metadata: { protocol: "sunswap-v2", contract: "pair", action: "k-last" }
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
function buildV2PairBalanceRead(pair, owner) {
|
|
958
|
+
return {
|
|
959
|
+
target: pair,
|
|
960
|
+
functionSelector: V2_PAIR_READ_SELECTORS.balanceOf,
|
|
961
|
+
parameters: [{ type: "address", value: owner }],
|
|
962
|
+
metadata: { protocol: "sunswap-v2", contract: "pair", action: "balance-of" }
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
function buildV2PairAllowanceRead(pair, owner, spender) {
|
|
966
|
+
return {
|
|
967
|
+
target: pair,
|
|
968
|
+
functionSelector: V2_PAIR_READ_SELECTORS.allowance,
|
|
969
|
+
parameters: [
|
|
970
|
+
{ type: "address", value: owner },
|
|
971
|
+
{ type: "address", value: spender }
|
|
972
|
+
],
|
|
973
|
+
metadata: { protocol: "sunswap-v2", contract: "pair", action: "allowance" }
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
function routerTarget2(params) {
|
|
977
|
+
return params.router ?? (0, import_sun_sdk_chains3.getContractAddress)(params.network, "sunswapV2Router");
|
|
978
|
+
}
|
|
979
|
+
function factoryTarget(params) {
|
|
980
|
+
return params.factory ?? (0, import_sun_sdk_chains3.getContractAddress)(params.network, "sunswapV2Factory");
|
|
981
|
+
}
|
|
982
|
+
function buildV2FactoryPairRead(params) {
|
|
983
|
+
return {
|
|
984
|
+
target: factoryTarget(params),
|
|
985
|
+
functionSelector: V2_FACTORY_READ_SELECTORS.getPair,
|
|
986
|
+
parameters: [
|
|
987
|
+
{ type: "address", value: params.tokenA },
|
|
988
|
+
{ type: "address", value: params.tokenB }
|
|
989
|
+
],
|
|
990
|
+
outputs: [{ type: "address", name: "pair" }],
|
|
991
|
+
metadata: {
|
|
992
|
+
protocol: "sunswap-v2",
|
|
993
|
+
contract: "factory",
|
|
994
|
+
action: "get-pair",
|
|
995
|
+
network: params.network
|
|
996
|
+
}
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
function buildV2FactoryFeeToRead(params) {
|
|
1000
|
+
return {
|
|
1001
|
+
target: factoryTarget(params),
|
|
1002
|
+
functionSelector: V2_FACTORY_READ_SELECTORS.feeTo,
|
|
1003
|
+
outputs: [{ type: "address", name: "feeTo" }],
|
|
1004
|
+
metadata: {
|
|
1005
|
+
protocol: "sunswap-v2",
|
|
1006
|
+
contract: "factory",
|
|
1007
|
+
action: "fee-to",
|
|
1008
|
+
network: params.network
|
|
1009
|
+
}
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
function buildV2RouterAmountsOutRead(params) {
|
|
1013
|
+
return {
|
|
1014
|
+
target: routerTarget2(params),
|
|
1015
|
+
functionSelector: V2_ROUTER_READ_SELECTORS.getAmountsOut,
|
|
1016
|
+
parameters: [
|
|
1017
|
+
{ type: "uint256", value: valueOf2(params.amountIn) },
|
|
1018
|
+
{ type: "address[]", value: params.path }
|
|
1019
|
+
],
|
|
1020
|
+
metadata: {
|
|
1021
|
+
protocol: "sunswap-v2",
|
|
1022
|
+
contract: "router",
|
|
1023
|
+
action: "get-amounts-out",
|
|
1024
|
+
network: params.network
|
|
1025
|
+
}
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
function buildV2RouterAmountsInRead(params) {
|
|
1029
|
+
return {
|
|
1030
|
+
target: routerTarget2(params),
|
|
1031
|
+
functionSelector: V2_ROUTER_READ_SELECTORS.getAmountsIn,
|
|
1032
|
+
parameters: [
|
|
1033
|
+
{ type: "uint256", value: valueOf2(params.amountOut) },
|
|
1034
|
+
{ type: "address[]", value: params.path }
|
|
1035
|
+
],
|
|
1036
|
+
metadata: {
|
|
1037
|
+
protocol: "sunswap-v2",
|
|
1038
|
+
contract: "router",
|
|
1039
|
+
action: "get-amounts-in",
|
|
1040
|
+
network: params.network
|
|
1041
|
+
}
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
function buildV2RouterAllowedTradingPairRead(params) {
|
|
1045
|
+
return {
|
|
1046
|
+
target: routerTarget2(params),
|
|
1047
|
+
functionSelector: V2_ROUTER_READ_SELECTORS.isAllowedTradingPair,
|
|
1048
|
+
parameters: [
|
|
1049
|
+
{ type: "address", value: params.tokenA },
|
|
1050
|
+
{ type: "address", value: params.tokenB }
|
|
1051
|
+
],
|
|
1052
|
+
metadata: {
|
|
1053
|
+
protocol: "sunswap-v2",
|
|
1054
|
+
contract: "router",
|
|
1055
|
+
action: "is-allowed-trading-pair",
|
|
1056
|
+
network: params.network
|
|
1057
|
+
}
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
function normalizeV2ReserveResult(result) {
|
|
1061
|
+
return {
|
|
1062
|
+
reserve0: valueOf2(result[0]),
|
|
1063
|
+
reserve1: valueOf2(result[1])
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
function normalizeV2AmountsResult(result) {
|
|
1067
|
+
const values = Array.isArray(result?.amounts) ? result.amounts : Array.isArray(result) ? result : [];
|
|
1068
|
+
return values.map((value) => valueOf2(value));
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
// src/router.ts
|
|
1072
|
+
var import_sun_sdk_core7 = require("@sun-protocol/sun-sdk-core");
|
|
1073
|
+
var import_tiny_invariant4 = __toESM(require("tiny-invariant"), 1);
|
|
1074
|
+
function toHex(currencyAmount) {
|
|
1075
|
+
return `0x${currencyAmount.quotient.toString(16)}`;
|
|
1076
|
+
}
|
|
1077
|
+
var ZERO_HEX = "0x0";
|
|
1078
|
+
var Router = class {
|
|
1079
|
+
constructor() {
|
|
1080
|
+
}
|
|
1081
|
+
static swapCallParameters(trade, options) {
|
|
1082
|
+
const etherIn = trade.inputAmount.currency.isNative;
|
|
1083
|
+
const etherOut = trade.outputAmount.currency.isNative;
|
|
1084
|
+
(0, import_tiny_invariant4.default)(!(etherIn && etherOut), "ETHER_IN_OUT");
|
|
1085
|
+
(0, import_tiny_invariant4.default)(!("ttl" in options) || options.ttl > 0, "TTL");
|
|
1086
|
+
const to = (0, import_sun_sdk_core7.validateAndParseAddress)(options.recipient);
|
|
1087
|
+
const amountIn = toHex(trade.maximumAmountIn(options.allowedSlippage));
|
|
1088
|
+
const amountOut = toHex(trade.minimumAmountOut(options.allowedSlippage));
|
|
1089
|
+
const path = trade.route.path.map((token) => token.address);
|
|
1090
|
+
const deadline = "ttl" in options ? `0x${(Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) + options.ttl).toString(16)}` : `0x${options.deadline.toString(16)}`;
|
|
1091
|
+
const useFeeOnTransfer = Boolean(options.feeOnTransfer);
|
|
1092
|
+
let methodName = "";
|
|
1093
|
+
let args = [];
|
|
1094
|
+
let value = ZERO_HEX;
|
|
1095
|
+
switch (trade.tradeType) {
|
|
1096
|
+
case import_sun_sdk_core7.TradeType.EXACT_INPUT:
|
|
1097
|
+
if (etherIn) {
|
|
1098
|
+
methodName = useFeeOnTransfer ? "swapExactETHForTokensSupportingFeeOnTransferTokens" : "swapExactETHForTokens";
|
|
1099
|
+
args = [amountOut, path, to, deadline];
|
|
1100
|
+
value = amountIn;
|
|
1101
|
+
} else if (etherOut) {
|
|
1102
|
+
methodName = useFeeOnTransfer ? "swapExactTokensForETHSupportingFeeOnTransferTokens" : "swapExactTokensForETH";
|
|
1103
|
+
args = [amountIn, amountOut, path, to, deadline];
|
|
1104
|
+
value = ZERO_HEX;
|
|
1105
|
+
} else {
|
|
1106
|
+
methodName = useFeeOnTransfer ? "swapExactTokensForTokensSupportingFeeOnTransferTokens" : "swapExactTokensForTokens";
|
|
1107
|
+
args = [amountIn, amountOut, path, to, deadline];
|
|
1108
|
+
value = ZERO_HEX;
|
|
1109
|
+
}
|
|
1110
|
+
break;
|
|
1111
|
+
case import_sun_sdk_core7.TradeType.EXACT_OUTPUT:
|
|
1112
|
+
(0, import_tiny_invariant4.default)(!useFeeOnTransfer, "EXACT_OUT_FOT");
|
|
1113
|
+
if (etherIn) {
|
|
1114
|
+
methodName = "swapETHForExactTokens";
|
|
1115
|
+
args = [amountOut, path, to, deadline];
|
|
1116
|
+
value = amountIn;
|
|
1117
|
+
} else if (etherOut) {
|
|
1118
|
+
methodName = "swapTokensForExactETH";
|
|
1119
|
+
args = [amountOut, amountIn, path, to, deadline];
|
|
1120
|
+
value = ZERO_HEX;
|
|
1121
|
+
} else {
|
|
1122
|
+
methodName = "swapTokensForExactTokens";
|
|
1123
|
+
args = [amountOut, amountIn, path, to, deadline];
|
|
1124
|
+
value = ZERO_HEX;
|
|
1125
|
+
}
|
|
1126
|
+
break;
|
|
1127
|
+
}
|
|
1128
|
+
return { methodName, args, value };
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1132
|
+
0 && (module.exports = {
|
|
1133
|
+
BASIS_POINTS,
|
|
1134
|
+
FACTORY_ADDRESS,
|
|
1135
|
+
FACTORY_ADDRESS_MAP,
|
|
1136
|
+
FIVE,
|
|
1137
|
+
INIT_CODE_HASH,
|
|
1138
|
+
INIT_CODE_HASH_MAP,
|
|
1139
|
+
InsufficientInputAmountError,
|
|
1140
|
+
InsufficientReservesError,
|
|
1141
|
+
MINIMUM_LIQUIDITY,
|
|
1142
|
+
ONE,
|
|
1143
|
+
ONE_HUNDRED_PERCENT,
|
|
1144
|
+
Pair,
|
|
1145
|
+
Route,
|
|
1146
|
+
Router,
|
|
1147
|
+
Trade,
|
|
1148
|
+
V2_FACTORY_READ_SELECTORS,
|
|
1149
|
+
V2_INIT_CODE_HASH,
|
|
1150
|
+
V2_PAIR_READ_SELECTORS,
|
|
1151
|
+
V2_ROUTER_READ_SELECTORS,
|
|
1152
|
+
V2_ROUTER_SELECTORS,
|
|
1153
|
+
ZERO,
|
|
1154
|
+
ZERO_PERCENT,
|
|
1155
|
+
_1000,
|
|
1156
|
+
_997,
|
|
1157
|
+
applyV2SlippageMin,
|
|
1158
|
+
buildV2AddLiquidityAction,
|
|
1159
|
+
buildV2AddLiquidityEthAction,
|
|
1160
|
+
buildV2FactoryFeeToRead,
|
|
1161
|
+
buildV2FactoryPairRead,
|
|
1162
|
+
buildV2LpApproveAction,
|
|
1163
|
+
buildV2PairAllowanceRead,
|
|
1164
|
+
buildV2PairBalanceRead,
|
|
1165
|
+
buildV2PairKLastRead,
|
|
1166
|
+
buildV2PairReservesRead,
|
|
1167
|
+
buildV2PairTotalSupplyRead,
|
|
1168
|
+
buildV2RemoveLiquidityAction,
|
|
1169
|
+
buildV2RemoveLiquidityEthAction,
|
|
1170
|
+
buildV2RouterAllowedTradingPairRead,
|
|
1171
|
+
buildV2RouterAmountsInRead,
|
|
1172
|
+
buildV2RouterAmountsOutRead,
|
|
1173
|
+
buildV2SwapEthForExactTokensAction,
|
|
1174
|
+
buildV2SwapExactEthForTokensAction,
|
|
1175
|
+
buildV2SwapExactTokensForEthAction,
|
|
1176
|
+
buildV2SwapExactTokensForTokensAction,
|
|
1177
|
+
buildV2SwapTokensForExactEthAction,
|
|
1178
|
+
buildV2SwapTokensForExactTokensAction,
|
|
1179
|
+
computePairAddress,
|
|
1180
|
+
computeV2PairAddress,
|
|
1181
|
+
createV2PairKey,
|
|
1182
|
+
evmHexToTronAddress,
|
|
1183
|
+
getV2AddLiquidityMinimums,
|
|
1184
|
+
getV2RemoveLiquidityMinimums,
|
|
1185
|
+
inputOutputComparator,
|
|
1186
|
+
normalizeV2AmountsResult,
|
|
1187
|
+
normalizeV2ReserveResult,
|
|
1188
|
+
quoteV2LiquidityAmount,
|
|
1189
|
+
sortV2Tokens,
|
|
1190
|
+
tradeComparator,
|
|
1191
|
+
tronAddressToEvmHex,
|
|
1192
|
+
tronCreate2Address
|
|
1193
|
+
});
|
|
1194
|
+
//# sourceMappingURL=index.cjs.map
|