@dhedge/v2-sdk 2.1.5 → 2.1.6
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 +180 -45
- package/dist/config.d.ts +2 -0
- package/dist/entities/pool.d.ts +110 -1
- package/dist/services/hyperliquid/constants.d.ts +16 -0
- package/dist/services/hyperliquid/index.d.ts +6 -0
- package/dist/services/hyperliquid/marketData.d.ts +12 -0
- package/dist/services/hyperliquid/positionData.d.ts +1 -0
- package/dist/services/toros/limitOrder.d.ts +8 -0
- package/dist/test/constants.d.ts +7 -1
- package/dist/test/wallet.d.ts +1 -0
- package/dist/types.d.ts +12 -2
- package/dist/v2-sdk.cjs.development.js +1470 -32
- package/dist/v2-sdk.cjs.development.js.map +1 -1
- package/dist/v2-sdk.cjs.production.min.js +1 -1
- package/dist/v2-sdk.cjs.production.min.js.map +1 -1
- package/dist/v2-sdk.esm.js +1449 -12
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +3 -2
- package/src/abi/hyperliquid/ICoreDepositWallet.json +130 -0
- package/src/abi/hyperliquid/ICoreWriter.json +1 -0
- package/src/abi/toros/IPoolLimitOrderManager.json +78 -0
- package/src/config.ts +31 -9
- package/src/entities/pool.ts +348 -4
- package/src/services/hyperliquid/constants.ts +23 -0
- package/src/services/hyperliquid/index.ts +176 -0
- package/src/services/hyperliquid/marketData.ts +157 -0
- package/src/services/hyperliquid/positionData.ts +33 -0
- package/src/services/toros/limitOrder.ts +86 -0
- package/src/test/constants.ts +11 -5
- package/src/test/hyperliquid.test.ts +107 -0
- package/src/test/pool.test.ts +37 -45
- package/src/test/torosLimitOrder.test.ts +130 -0
- package/src/test/wallet.ts +2 -1
- package/src/types.ts +13 -2
package/src/entities/pool.ts
CHANGED
|
@@ -19,7 +19,8 @@ import {
|
|
|
19
19
|
nonfungiblePositionManagerAddress,
|
|
20
20
|
routerAddress,
|
|
21
21
|
stakingAddress,
|
|
22
|
-
SYNTHETIX_TRACKING_CODE
|
|
22
|
+
SYNTHETIX_TRACKING_CODE,
|
|
23
|
+
limitOrderAddress
|
|
23
24
|
} from "../config";
|
|
24
25
|
import {
|
|
25
26
|
Dapp,
|
|
@@ -31,7 +32,8 @@ import {
|
|
|
31
32
|
LyraOptionType,
|
|
32
33
|
LyraTradeType,
|
|
33
34
|
LyraPosition,
|
|
34
|
-
SDKOptions
|
|
35
|
+
SDKOptions,
|
|
36
|
+
LimitOrderInfo
|
|
35
37
|
} from "../types";
|
|
36
38
|
|
|
37
39
|
import { Utils } from "./utils";
|
|
@@ -57,8 +59,8 @@ import { getLyraOptionTxData } from "../services/lyra/trade";
|
|
|
57
59
|
import { getOptionPositions } from "../services/lyra/positions";
|
|
58
60
|
import { getDeadline } from "../utils/deadline";
|
|
59
61
|
import {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
getFuturesChangeMarginTxData,
|
|
63
|
+
getFuturesChangePositionTxData
|
|
62
64
|
} from "../services/futures";
|
|
63
65
|
import { getFuturesCancelOrderTxData } from "../services/futures/trade";
|
|
64
66
|
import { getOneInchSwapTxData } from "../services/oneInch";
|
|
@@ -86,7 +88,22 @@ import {
|
|
|
86
88
|
import { getOdosSwapTxData } from "../services/odos";
|
|
87
89
|
import { getPendleMintTxData, getPendleSwapTxData } from "../services/pendle";
|
|
88
90
|
import { getCompleteWithdrawalTxData } from "../services/toros/completeWithdrawal";
|
|
91
|
+
import {
|
|
92
|
+
getCreateLimitOrderTxData,
|
|
93
|
+
getModifyLimitOrderTxData,
|
|
94
|
+
getDeleteLimitOrderTxData,
|
|
95
|
+
getTorosLimitOrder,
|
|
96
|
+
hasActiveTorosLimitOrder
|
|
97
|
+
} from "../services/toros/limitOrder";
|
|
89
98
|
import { getKyberSwapTxData } from "../services/kyberSwap";
|
|
99
|
+
import {
|
|
100
|
+
getClosePositionHyperliquidTxData,
|
|
101
|
+
getDepositHyperliquidTxData,
|
|
102
|
+
getLimitOrderHyperliquidTxData,
|
|
103
|
+
getPerpToSpotHyperliquidTxData,
|
|
104
|
+
getWithdrawSpotHyperliquidTxData
|
|
105
|
+
} from "../services/hyperliquid";
|
|
106
|
+
import { CORE_WRITER_ADDRESS } from "../services/hyperliquid/constants";
|
|
90
107
|
|
|
91
108
|
export class Pool {
|
|
92
109
|
public readonly poolLogic: Contract;
|
|
@@ -2147,4 +2164,331 @@ export class Pool {
|
|
|
2147
2164
|
);
|
|
2148
2165
|
return tx;
|
|
2149
2166
|
}
|
|
2167
|
+
|
|
2168
|
+
/** Deposit USDC from EVM to a HyperCore trading dex via the CoreDepositWallet.
|
|
2169
|
+
* This bridges USDC on-chain to Hyperliquid for perp/spot trading.
|
|
2170
|
+
*
|
|
2171
|
+
* @param {BigNumber | string} amount USDC amount to deposit (6 decimals, e.g. "1000000" = 1 USDC)
|
|
2172
|
+
* @param {number} dexId Destination dex ID where USDC will be available (default 0)
|
|
2173
|
+
* - 0: Core Perp dex (standard perps like BTC, ETH)
|
|
2174
|
+
* - 1: xyz HIP-3 dex (builder perps like TSLA, GOLD)
|
|
2175
|
+
* @param {any} options Transaction options
|
|
2176
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2177
|
+
* @returns {Promise<any>} Transaction
|
|
2178
|
+
*/
|
|
2179
|
+
async depositHyperliquid(
|
|
2180
|
+
amount: BigNumber | string,
|
|
2181
|
+
dexId = 0,
|
|
2182
|
+
options: any = null,
|
|
2183
|
+
sdkOptions: SDKOptions = {
|
|
2184
|
+
estimateGas: false
|
|
2185
|
+
}
|
|
2186
|
+
): Promise<any> {
|
|
2187
|
+
const tx = await getPoolTxOrGasEstimate(
|
|
2188
|
+
this,
|
|
2189
|
+
[
|
|
2190
|
+
routerAddress[this.network][Dapp.HYPERLIQUID],
|
|
2191
|
+
getDepositHyperliquidTxData(dexId, amount),
|
|
2192
|
+
options
|
|
2193
|
+
],
|
|
2194
|
+
sdkOptions
|
|
2195
|
+
);
|
|
2196
|
+
return tx;
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
/** Move USDC from a HyperCore trading dex to the Spot wallet.
|
|
2200
|
+
* Required before calling withdrawHyperliquid() to bridge USDC back to EVM.
|
|
2201
|
+
*
|
|
2202
|
+
* @param {number} dexId Source dex ID where USDC currently sits
|
|
2203
|
+
* - 0: Core Perp dex (standard perps like BTC, ETH)
|
|
2204
|
+
* - 1: xyz HIP-3 dex (builder perps like TSLA, GOLD)
|
|
2205
|
+
* @param {BigNumber | string} amount USDC amount to transfer (6 decimals, e.g. "1000000" = 1 USDC)
|
|
2206
|
+
* @param {any} options Transaction options
|
|
2207
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2208
|
+
* @returns {Promise<any>} Transaction
|
|
2209
|
+
*/
|
|
2210
|
+
|
|
2211
|
+
async perpToSpotHyperliquid(
|
|
2212
|
+
dexId: number,
|
|
2213
|
+
amount: BigNumber | string,
|
|
2214
|
+
options: any = null,
|
|
2215
|
+
sdkOptions: SDKOptions = {
|
|
2216
|
+
estimateGas: false
|
|
2217
|
+
}
|
|
2218
|
+
): Promise<any> {
|
|
2219
|
+
const tx = await getPoolTxOrGasEstimate(
|
|
2220
|
+
this,
|
|
2221
|
+
[
|
|
2222
|
+
CORE_WRITER_ADDRESS,
|
|
2223
|
+
getPerpToSpotHyperliquidTxData(dexId, this.address, amount),
|
|
2224
|
+
options
|
|
2225
|
+
],
|
|
2226
|
+
sdkOptions
|
|
2227
|
+
);
|
|
2228
|
+
return tx;
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
/** Withdraw USDC from Hyperliquid Spot wallet back to EVM.
|
|
2232
|
+
* USDC must be in the Spot wallet first — use perpToSpotHyperliquid() to move it from a trading dex.
|
|
2233
|
+
*
|
|
2234
|
+
* @param {BigNumber | string} amount USDC amount to withdraw (6 decimals, e.g. "1000000" = 1 USDC)
|
|
2235
|
+
* @param {any} options Transaction options
|
|
2236
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2237
|
+
* @returns {Promise<any>} Transaction
|
|
2238
|
+
*/
|
|
2239
|
+
|
|
2240
|
+
async withdrawHyperliquid(
|
|
2241
|
+
amount: BigNumber | string,
|
|
2242
|
+
options: any = null,
|
|
2243
|
+
sdkOptions: SDKOptions = {
|
|
2244
|
+
estimateGas: false
|
|
2245
|
+
}
|
|
2246
|
+
): Promise<any> {
|
|
2247
|
+
const tx = await getPoolTxOrGasEstimate(
|
|
2248
|
+
this,
|
|
2249
|
+
[CORE_WRITER_ADDRESS, getWithdrawSpotHyperliquidTxData(amount), options],
|
|
2250
|
+
sdkOptions
|
|
2251
|
+
);
|
|
2252
|
+
return tx;
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
/** Open a market order on Hyperliquid
|
|
2256
|
+
* @param {number} assetId Asset id
|
|
2257
|
+
* @param {boolean} isLong Long or short (Note: Spot assets only support long positions)
|
|
2258
|
+
* @param {number} value Order value in base asset units (positive for opening/increasing,
|
|
2259
|
+
* negative for closing/reducing or selling spot)
|
|
2260
|
+
* @param {number } slippage Slippage tolerance in %
|
|
2261
|
+
* @param {any} options Transaction options
|
|
2262
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2263
|
+
* @returns {Promise<any>} Transaction
|
|
2264
|
+
*/
|
|
2265
|
+
async openMarketOrderHyperliquid(
|
|
2266
|
+
assetId: number,
|
|
2267
|
+
isLong: boolean,
|
|
2268
|
+
value: number,
|
|
2269
|
+
slippage = 0.5,
|
|
2270
|
+
options: any = null,
|
|
2271
|
+
sdkOptions: SDKOptions = {
|
|
2272
|
+
estimateGas: false
|
|
2273
|
+
}
|
|
2274
|
+
): Promise<any> {
|
|
2275
|
+
const tx = await getPoolTxOrGasEstimate(
|
|
2276
|
+
this,
|
|
2277
|
+
[
|
|
2278
|
+
CORE_WRITER_ADDRESS,
|
|
2279
|
+
await getLimitOrderHyperliquidTxData(assetId, isLong, value, slippage),
|
|
2280
|
+
options
|
|
2281
|
+
],
|
|
2282
|
+
sdkOptions
|
|
2283
|
+
);
|
|
2284
|
+
return tx;
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
/** Close a position on Hyperliquid
|
|
2288
|
+
* @param {number} assetId Asset id
|
|
2289
|
+
* @param {number} percentageToClose Percentage of position to close (0-100)
|
|
2290
|
+
* @param {number } slippage Slippage tolerance in %
|
|
2291
|
+
* @param {any} options Transaction options
|
|
2292
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2293
|
+
* @returns {Promise<any>} Transaction
|
|
2294
|
+
*/
|
|
2295
|
+
async closePositionHyperliquid(
|
|
2296
|
+
assetId: number,
|
|
2297
|
+
percentageToClose = 100,
|
|
2298
|
+
slippage = 0.5,
|
|
2299
|
+
options: any = null,
|
|
2300
|
+
sdkOptions: SDKOptions = {
|
|
2301
|
+
estimateGas: false
|
|
2302
|
+
}
|
|
2303
|
+
): Promise<any> {
|
|
2304
|
+
const tx = await getPoolTxOrGasEstimate(
|
|
2305
|
+
this,
|
|
2306
|
+
[
|
|
2307
|
+
CORE_WRITER_ADDRESS,
|
|
2308
|
+
await getClosePositionHyperliquidTxData(
|
|
2309
|
+
assetId,
|
|
2310
|
+
percentageToClose,
|
|
2311
|
+
slippage,
|
|
2312
|
+
this.address
|
|
2313
|
+
),
|
|
2314
|
+
options
|
|
2315
|
+
],
|
|
2316
|
+
sdkOptions
|
|
2317
|
+
);
|
|
2318
|
+
return tx;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
/**
|
|
2322
|
+
* Approve the Toros vault token for the PoolLimitOrderManager
|
|
2323
|
+
* Must be called before createTorosLimitOrder
|
|
2324
|
+
* @param {string} vaultAddress Address of the Toros vault token to approve
|
|
2325
|
+
* @param {BigNumber | string} amount Amount to approve
|
|
2326
|
+
* @param {any} options Transaction options
|
|
2327
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2328
|
+
* @returns {Promise<any>} Transaction
|
|
2329
|
+
*/
|
|
2330
|
+
async approveTorosLimitOrder(
|
|
2331
|
+
vaultAddress: string,
|
|
2332
|
+
amount: BigNumber | string,
|
|
2333
|
+
options: any = null,
|
|
2334
|
+
sdkOptions: SDKOptions = { estimateGas: false }
|
|
2335
|
+
): Promise<any> {
|
|
2336
|
+
const managerAddress = limitOrderAddress[this.network];
|
|
2337
|
+
const iERC20 = new ethers.utils.Interface(IERC20.abi);
|
|
2338
|
+
const approveTxData = iERC20.encodeFunctionData("approve", [
|
|
2339
|
+
managerAddress,
|
|
2340
|
+
amount
|
|
2341
|
+
]);
|
|
2342
|
+
return getPoolTxOrGasEstimate(
|
|
2343
|
+
this,
|
|
2344
|
+
[vaultAddress, approveTxData, options],
|
|
2345
|
+
sdkOptions
|
|
2346
|
+
);
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
/**
|
|
2350
|
+
* Create a Toros limit order (stop-loss / take-profit)
|
|
2351
|
+
* @param {string} vaultAddress Address of the Toros vault token
|
|
2352
|
+
* @param {BigNumber | string} amount Vault token amount (18 decimals)
|
|
2353
|
+
* @param {BigNumber | string | null | undefined} stopLossPriceD18 Stop-loss price in D18 (0 or null/undefined = disabled)
|
|
2354
|
+
* @param {BigNumber | string | null | undefined} takeProfitPriceD18 Take-profit price in D18 (MaxUint256 or null/undefined = disabled)
|
|
2355
|
+
* @param {string} pricingAsset Address of the pricing asset (e.g. USDC)
|
|
2356
|
+
* @param {any} options Transaction options
|
|
2357
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2358
|
+
* @returns {Promise<any>} Transaction
|
|
2359
|
+
*/
|
|
2360
|
+
async createTorosLimitOrder(
|
|
2361
|
+
vaultAddress: string,
|
|
2362
|
+
amount: BigNumber | string,
|
|
2363
|
+
stopLossPriceD18: BigNumber | string | null | undefined,
|
|
2364
|
+
takeProfitPriceD18: BigNumber | string | null | undefined,
|
|
2365
|
+
pricingAsset: string,
|
|
2366
|
+
options: any = null,
|
|
2367
|
+
sdkOptions: SDKOptions = { estimateGas: false }
|
|
2368
|
+
): Promise<any> {
|
|
2369
|
+
const managerAddress = limitOrderAddress[this.network];
|
|
2370
|
+
if (!managerAddress) {
|
|
2371
|
+
throw new Error(`Limit orders not supported on ${this.network}`);
|
|
2372
|
+
}
|
|
2373
|
+
const resolvedStopLoss =
|
|
2374
|
+
stopLossPriceD18 == null
|
|
2375
|
+
? BigNumber.from(0)
|
|
2376
|
+
: BigNumber.from(stopLossPriceD18);
|
|
2377
|
+
const resolvedTakeProfit =
|
|
2378
|
+
takeProfitPriceD18 == null
|
|
2379
|
+
? ethers.constants.MaxUint256
|
|
2380
|
+
: BigNumber.from(takeProfitPriceD18);
|
|
2381
|
+
const info: LimitOrderInfo = {
|
|
2382
|
+
amount: BigNumber.from(amount),
|
|
2383
|
+
stopLossPriceD18: resolvedStopLoss,
|
|
2384
|
+
takeProfitPriceD18: resolvedTakeProfit,
|
|
2385
|
+
user: this.address,
|
|
2386
|
+
pool: vaultAddress,
|
|
2387
|
+
pricingAsset
|
|
2388
|
+
};
|
|
2389
|
+
const txData = getCreateLimitOrderTxData(info);
|
|
2390
|
+
return getPoolTxOrGasEstimate(
|
|
2391
|
+
this,
|
|
2392
|
+
[managerAddress, txData, options],
|
|
2393
|
+
sdkOptions
|
|
2394
|
+
);
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
/**
|
|
2398
|
+
* Modify an existing Toros limit order
|
|
2399
|
+
* @param {string} vaultAddress Address of the Toros vault token
|
|
2400
|
+
* @param {BigNumber | string} amount New vault token amount (18 decimals)
|
|
2401
|
+
* @param {BigNumber | string | null | undefined} stopLossPriceD18 New stop-loss price in D18 (0 or null/undefined = disabled)
|
|
2402
|
+
* @param {BigNumber | string | null | undefined} takeProfitPriceD18 New take-profit price in D18 (MaxUint256 or null/undefined = disabled)
|
|
2403
|
+
* @param {string} pricingAsset Address of the pricing asset
|
|
2404
|
+
* @param {any} options Transaction options
|
|
2405
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2406
|
+
* @returns {Promise<any>} Transaction
|
|
2407
|
+
*/
|
|
2408
|
+
async modifyTorosLimitOrder(
|
|
2409
|
+
vaultAddress: string,
|
|
2410
|
+
amount: BigNumber | string,
|
|
2411
|
+
stopLossPriceD18: BigNumber | string | null | undefined,
|
|
2412
|
+
takeProfitPriceD18: BigNumber | string | null | undefined,
|
|
2413
|
+
pricingAsset: string,
|
|
2414
|
+
options: any = null,
|
|
2415
|
+
sdkOptions: SDKOptions = { estimateGas: false }
|
|
2416
|
+
): Promise<any> {
|
|
2417
|
+
const managerAddress = limitOrderAddress[this.network];
|
|
2418
|
+
if (!managerAddress) {
|
|
2419
|
+
throw new Error(`Limit orders not supported on ${this.network}`);
|
|
2420
|
+
}
|
|
2421
|
+
const resolvedStopLoss =
|
|
2422
|
+
stopLossPriceD18 == null
|
|
2423
|
+
? BigNumber.from(0)
|
|
2424
|
+
: BigNumber.from(stopLossPriceD18);
|
|
2425
|
+
const resolvedTakeProfit =
|
|
2426
|
+
takeProfitPriceD18 == null
|
|
2427
|
+
? ethers.constants.MaxUint256
|
|
2428
|
+
: BigNumber.from(takeProfitPriceD18);
|
|
2429
|
+
const info: LimitOrderInfo = {
|
|
2430
|
+
amount: BigNumber.from(amount),
|
|
2431
|
+
stopLossPriceD18: resolvedStopLoss,
|
|
2432
|
+
takeProfitPriceD18: resolvedTakeProfit,
|
|
2433
|
+
user: this.address,
|
|
2434
|
+
pool: vaultAddress,
|
|
2435
|
+
pricingAsset
|
|
2436
|
+
};
|
|
2437
|
+
const txData = getModifyLimitOrderTxData(info);
|
|
2438
|
+
return getPoolTxOrGasEstimate(
|
|
2439
|
+
this,
|
|
2440
|
+
[managerAddress, txData, options],
|
|
2441
|
+
sdkOptions
|
|
2442
|
+
);
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
/**
|
|
2446
|
+
* Delete an existing Toros limit order
|
|
2447
|
+
* @param {string} vaultAddress Address of the Toros vault token
|
|
2448
|
+
* @param {any} options Transaction options
|
|
2449
|
+
* @param {SDKOptions} sdkOptions SDK options including estimateGas
|
|
2450
|
+
* @returns {Promise<any>} Transaction
|
|
2451
|
+
*/
|
|
2452
|
+
async deleteTorosLimitOrder(
|
|
2453
|
+
vaultAddress: string,
|
|
2454
|
+
options: any = null,
|
|
2455
|
+
sdkOptions: SDKOptions = { estimateGas: false }
|
|
2456
|
+
): Promise<any> {
|
|
2457
|
+
const managerAddress = limitOrderAddress[this.network];
|
|
2458
|
+
if (!managerAddress) {
|
|
2459
|
+
throw new Error(`Limit orders not supported on ${this.network}`);
|
|
2460
|
+
}
|
|
2461
|
+
const txData = getDeleteLimitOrderTxData(vaultAddress);
|
|
2462
|
+
return getPoolTxOrGasEstimate(
|
|
2463
|
+
this,
|
|
2464
|
+
[managerAddress, txData, options],
|
|
2465
|
+
sdkOptions
|
|
2466
|
+
);
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
/**
|
|
2470
|
+
* Fetch a Toros limit order for a given user and vault
|
|
2471
|
+
* @param {string} userAddress Address of the order owner (the dHEDGE pool)
|
|
2472
|
+
* @param {string} vaultAddress Address of the Toros vault token
|
|
2473
|
+
* @returns {Promise<LimitOrderInfo | null>} Order info, or null if none exists
|
|
2474
|
+
*/
|
|
2475
|
+
async getTorosLimitOrder(
|
|
2476
|
+
userAddress: string,
|
|
2477
|
+
vaultAddress: string
|
|
2478
|
+
): Promise<LimitOrderInfo | null> {
|
|
2479
|
+
return getTorosLimitOrder(this, userAddress, vaultAddress);
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
/**
|
|
2483
|
+
* Check whether an active Toros limit order exists for a given user and vault
|
|
2484
|
+
* @param {string} userAddress Address of the order owner (the dHEDGE pool)
|
|
2485
|
+
* @param {string} vaultAddress Address of the Toros vault token
|
|
2486
|
+
* @returns {Promise<boolean>}
|
|
2487
|
+
*/
|
|
2488
|
+
async hasActiveTorosLimitOrder(
|
|
2489
|
+
userAddress: string,
|
|
2490
|
+
vaultAddress: string
|
|
2491
|
+
): Promise<boolean> {
|
|
2492
|
+
return hasActiveTorosLimitOrder(this, userAddress, vaultAddress);
|
|
2493
|
+
}
|
|
2150
2494
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const USDC_TOKEN_ID = 0;
|
|
2
|
+
export const USDC_CORE_ADDRESS = "0x2000000000000000000000000000000000000000";
|
|
3
|
+
export const CORE_WRITER_ADDRESS = "0x3333333333333333333333333333333333333333";
|
|
4
|
+
export const PERP_DEX_ID = 0;
|
|
5
|
+
export const SPOT_DEX_ID = 4294967295; // max uint32;
|
|
6
|
+
export const HYPERLIQUID_VERSION = 1;
|
|
7
|
+
|
|
8
|
+
//Action IDs
|
|
9
|
+
export const SPOT_SEND_ACTION = 6;
|
|
10
|
+
export const SEND_ASSET_ACTION = 13;
|
|
11
|
+
export const LIMIT_ORDER_ACTION = 1;
|
|
12
|
+
|
|
13
|
+
//Order Time In Force options
|
|
14
|
+
export const LIMIT_ORDER_TIF_ALO = 1;
|
|
15
|
+
export const LIMIT_ORDER_TIF_GTC = 2;
|
|
16
|
+
export const LIMIT_ORDER_TIF_IOC = 3;
|
|
17
|
+
|
|
18
|
+
export const dexIdNameMap: { [key: number]: string } = {
|
|
19
|
+
0: "",
|
|
20
|
+
1: "xyz"
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const API_URL = "https://api.hyperliquid.xyz/info";
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
import ICoreDepositWalletAbi from "../../abi/hyperliquid/ICoreDepositWallet.json";
|
|
3
|
+
import ICoreWriterAbi from "../../abi/hyperliquid/ICoreWriter.json";
|
|
4
|
+
import {
|
|
5
|
+
HYPERLIQUID_VERSION,
|
|
6
|
+
LIMIT_ORDER_ACTION,
|
|
7
|
+
LIMIT_ORDER_TIF_IOC,
|
|
8
|
+
SEND_ASSET_ACTION,
|
|
9
|
+
SPOT_DEX_ID,
|
|
10
|
+
SPOT_SEND_ACTION,
|
|
11
|
+
USDC_CORE_ADDRESS,
|
|
12
|
+
USDC_TOKEN_ID
|
|
13
|
+
} from "./constants";
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
calculatePrice,
|
|
17
|
+
calculateSize,
|
|
18
|
+
getAssetInfo,
|
|
19
|
+
getMidPrice,
|
|
20
|
+
isSpotAsset,
|
|
21
|
+
scaleSize
|
|
22
|
+
} from "./marketData";
|
|
23
|
+
import { getPositionSize } from "./positionData";
|
|
24
|
+
|
|
25
|
+
const depositWallet = new ethers.utils.Interface(ICoreDepositWalletAbi);
|
|
26
|
+
const coreWriter = new ethers.utils.Interface(ICoreWriterAbi);
|
|
27
|
+
|
|
28
|
+
export const getDepositHyperliquidTxData = (
|
|
29
|
+
dexId: number,
|
|
30
|
+
amount: ethers.BigNumber | string
|
|
31
|
+
): string => {
|
|
32
|
+
return depositWallet.encodeFunctionData("deposit", [amount, dexId]);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const getWithdrawSpotHyperliquidTxData = (
|
|
36
|
+
amount: ethers.BigNumber | string
|
|
37
|
+
): string => {
|
|
38
|
+
const coreAmount = ethers.BigNumber.from(amount).mul(100); //USDC on Core has two more decimals
|
|
39
|
+
//Hardcoded to USDC address and id on Hyperliquid Core
|
|
40
|
+
//From Spot to EVM
|
|
41
|
+
const innerEncoded = ethers.utils.defaultAbiCoder.encode(
|
|
42
|
+
//to, token, amount
|
|
43
|
+
["address", "uint64", "uint64"],
|
|
44
|
+
[USDC_CORE_ADDRESS, USDC_TOKEN_ID, coreAmount]
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const rawTXData = ethers.utils.solidityPack(
|
|
48
|
+
["uint8", "uint24", "bytes"],
|
|
49
|
+
[HYPERLIQUID_VERSION, SPOT_SEND_ACTION, innerEncoded]
|
|
50
|
+
);
|
|
51
|
+
return coreWriter.encodeFunctionData("sendRawAction", [rawTXData]);
|
|
52
|
+
};
|
|
53
|
+
export const getPerpToSpotHyperliquidTxData = (
|
|
54
|
+
dexId: number,
|
|
55
|
+
receiver: string,
|
|
56
|
+
amount: ethers.BigNumber | string
|
|
57
|
+
): string => {
|
|
58
|
+
const coreAmount = ethers.BigNumber.from(amount).mul(100); //USDC on Core has two more decimals
|
|
59
|
+
//From Perp to Spot
|
|
60
|
+
const innerEncoded = ethers.utils.defaultAbiCoder.encode(
|
|
61
|
+
//destination, subAccount, sourceDex, destinationDex, token, amount
|
|
62
|
+
["address", "address", "uint32", "uint32", "uint64", "uint64"],
|
|
63
|
+
[
|
|
64
|
+
receiver,
|
|
65
|
+
ethers.constants.AddressZero,
|
|
66
|
+
dexId,
|
|
67
|
+
SPOT_DEX_ID,
|
|
68
|
+
USDC_TOKEN_ID,
|
|
69
|
+
coreAmount
|
|
70
|
+
]
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const rawTXData = ethers.utils.solidityPack(
|
|
74
|
+
["uint8", "uint24", "bytes"],
|
|
75
|
+
[HYPERLIQUID_VERSION, SEND_ASSET_ACTION, innerEncoded]
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return coreWriter.encodeFunctionData("sendRawAction", [rawTXData]);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const getLimitOrderHyperliquidTxData = async (
|
|
82
|
+
assetId: number,
|
|
83
|
+
isLong: boolean,
|
|
84
|
+
changeAmount: number,
|
|
85
|
+
slippage: number
|
|
86
|
+
): Promise<string> => {
|
|
87
|
+
let isBuy = isLong;
|
|
88
|
+
let reduceOnly = false;
|
|
89
|
+
if (changeAmount < 0) {
|
|
90
|
+
changeAmount = changeAmount * -1;
|
|
91
|
+
isBuy = !isLong;
|
|
92
|
+
reduceOnly = !isSpotAsset(assetId);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//Calculate price with slippage
|
|
96
|
+
const { assetName, szDecimals } = await getAssetInfo(assetId);
|
|
97
|
+
const midPrice = await getMidPrice(assetId, assetName);
|
|
98
|
+
const price = calculatePrice(
|
|
99
|
+
isSpotAsset(assetId),
|
|
100
|
+
szDecimals,
|
|
101
|
+
midPrice,
|
|
102
|
+
isBuy,
|
|
103
|
+
slippage
|
|
104
|
+
);
|
|
105
|
+
const size = calculateSize(szDecimals, changeAmount, midPrice);
|
|
106
|
+
|
|
107
|
+
const innerEncoded = ethers.utils.defaultAbiCoder.encode(
|
|
108
|
+
//assetIndex, isBuy, price, size, reduceOnly, tif, clientOrderId
|
|
109
|
+
["uint32", "bool", "uint64", "uint64", "bool", "uint8", "uint128"],
|
|
110
|
+
[
|
|
111
|
+
assetId,
|
|
112
|
+
isBuy,
|
|
113
|
+
price,
|
|
114
|
+
size,
|
|
115
|
+
reduceOnly,
|
|
116
|
+
LIMIT_ORDER_TIF_IOC, // immediate or cancel
|
|
117
|
+
ethers.BigNumber.from(0) //client order id
|
|
118
|
+
]
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const rawTXData = ethers.utils.solidityPack(
|
|
122
|
+
["uint8", "uint24", "bytes"],
|
|
123
|
+
[HYPERLIQUID_VERSION, LIMIT_ORDER_ACTION, innerEncoded]
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
return coreWriter.encodeFunctionData("sendRawAction", [rawTXData]);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const getClosePositionHyperliquidTxData = async (
|
|
130
|
+
assetId: number,
|
|
131
|
+
percentageToClose: number,
|
|
132
|
+
slippage: number,
|
|
133
|
+
poolAddress: string
|
|
134
|
+
): Promise<string> => {
|
|
135
|
+
const isSpot = isSpotAsset(assetId);
|
|
136
|
+
const { assetName, szDecimals, baseTokenName } = await getAssetInfo(assetId);
|
|
137
|
+
const positionSize = await getPositionSize(
|
|
138
|
+
assetId,
|
|
139
|
+
isSpot,
|
|
140
|
+
baseTokenName ?? assetName,
|
|
141
|
+
poolAddress
|
|
142
|
+
);
|
|
143
|
+
const isBuy = positionSize < 0; // if position size is negative, we need to buy to close, otherwise sell
|
|
144
|
+
const sizeRaw = scaleSize(szDecimals, positionSize, percentageToClose);
|
|
145
|
+
|
|
146
|
+
//Calculate price with slippage
|
|
147
|
+
const midPrice = await getMidPrice(assetId, assetName);
|
|
148
|
+
const price = calculatePrice(
|
|
149
|
+
isSpotAsset(assetId),
|
|
150
|
+
szDecimals,
|
|
151
|
+
midPrice,
|
|
152
|
+
isBuy,
|
|
153
|
+
slippage
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
const innerEncoded = ethers.utils.defaultAbiCoder.encode(
|
|
157
|
+
//assetIndex, isBuy, price, size, reduceOnly, tif, clientOrderId
|
|
158
|
+
["uint32", "bool", "uint64", "uint64", "bool", "uint8", "uint128"],
|
|
159
|
+
[
|
|
160
|
+
assetId,
|
|
161
|
+
positionSize < 0, // if position size is negative, we need to buy to close, otherwise sell
|
|
162
|
+
price,
|
|
163
|
+
sizeRaw,
|
|
164
|
+
!isSpot,
|
|
165
|
+
LIMIT_ORDER_TIF_IOC, // immediate or cancel
|
|
166
|
+
ethers.BigNumber.from(0) //client order id
|
|
167
|
+
]
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const rawTXData = ethers.utils.solidityPack(
|
|
171
|
+
["uint8", "uint24", "bytes"],
|
|
172
|
+
[HYPERLIQUID_VERSION, LIMIT_ORDER_ACTION, innerEncoded]
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
return coreWriter.encodeFunctionData("sendRawAction", [rawTXData]);
|
|
176
|
+
};
|