@gainsnetwork/sdk 1.0.5-rc3 → 1.0.6-rc2
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/lib/backend/globalTrades/index.js +10 -10
- package/lib/backend/tradingVariables/converter.js +57 -57
- package/lib/backend/tradingVariables/index.js +6 -7
- package/lib/contracts/addresses.js +4 -1
- package/lib/contracts/index.d.ts +1 -1
- package/lib/contracts/index.js +3 -3
- package/lib/contracts/types/generated/GNSMultiCollatDiamond.d.ts +386 -260
- package/lib/contracts/types/generated/factories/GNSMultiCollatDiamond__factory.d.ts +2 -10
- package/lib/contracts/types/generated/factories/GNSMultiCollatDiamond__factory.js +1621 -219
- package/lib/contracts/utils/borrowingFees.js +9 -20
- package/lib/contracts/utils/openTrades.js +11 -20
- package/lib/contracts/utils/pairs.js +12 -21
- package/lib/markets/forex.js +1 -1
- package/lib/markets/leverage/builder.js +2 -2
- package/lib/markets/price/index.d.ts +1 -0
- package/lib/markets/price/index.js +1 -0
- package/lib/markets/price/signedPrices.d.ts +20 -4
- package/lib/markets/price/signedPrices.js +65 -21
- package/lib/markets/price/types.d.ts +23 -0
- package/lib/trade/fees/borrowing/builder.js +2 -3
- package/lib/trade/fees/borrowing/converter.js +5 -1
- package/lib/trade/fees/borrowing/index.js +5 -5
- package/lib/trade/fees/borrowingV2/builder.js +3 -4
- package/lib/trade/fees/borrowingV2/converter.js +1 -1
- package/lib/trade/fees/borrowingV2/fetcher.js +26 -32
- package/lib/trade/fees/borrowingV2/index.js +3 -3
- package/lib/trade/fees/converter.js +22 -22
- package/lib/trade/fees/fundingFees/builder.js +6 -7
- package/lib/trade/fees/fundingFees/converter.js +1 -1
- package/lib/trade/fees/fundingFees/fetcher.js +16 -25
- package/lib/trade/fees/fundingFees/index.js +2 -3
- package/lib/trade/fees/tiers/index.js +1 -2
- package/lib/trade/fees/trading/index.js +5 -3
- package/lib/trade/liquidation/builder.js +6 -3
- package/lib/trade/liquidation/index.js +4 -6
- package/lib/trade/oiWindows.js +1 -2
- package/lib/trade/pnl/builder.js +1 -2
- package/lib/trade/pnl/converter.js +1 -1
- package/lib/trade/pnl/index.js +4 -7
- package/lib/trade/priceImpact/close/builder.js +1 -2
- package/lib/trade/priceImpact/close/index.js +4 -1
- package/lib/trade/priceImpact/cumulVol/builder.js +18 -10
- package/lib/trade/priceImpact/cumulVol/index.js +21 -16
- package/lib/trade/priceImpact/open/builder.js +1 -2
- package/lib/trade/priceImpact/open/index.js +4 -1
- package/lib/trade/priceImpact/skew/builder.js +2 -3
- package/lib/trade/priceImpact/skew/converter.js +1 -1
- package/lib/trade/priceImpact/skew/fetcher.js +24 -33
- package/package.json +2 -2
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.fetchAllPairAndGroupBorrowingFees = exports.fetchGroupBorrowingFees = exports.fetchAllPairBorrowingFees = exports.getBorrowingGroupName = void 0;
|
|
13
4
|
const trade_1 = require("../../trade");
|
|
@@ -31,24 +22,22 @@ const getBorrowingGroupName = (groupIndex) => {
|
|
|
31
22
|
return groupNamesByIndex[groupIndex - 1] || "Unknown";
|
|
32
23
|
};
|
|
33
24
|
exports.getBorrowingGroupName = getBorrowingGroupName;
|
|
34
|
-
const fetchAllPairBorrowingFees = (contract, collateralIndex) =>
|
|
35
|
-
const [pairs, pairOi, pairGroups] =
|
|
36
|
-
const feeCaps =
|
|
25
|
+
const fetchAllPairBorrowingFees = async (contract, collateralIndex) => {
|
|
26
|
+
const [pairs, pairOi, pairGroups] = await contract.getAllBorrowingPairs(collateralIndex);
|
|
27
|
+
const feeCaps = await contract.getBorrowingPairFeePerBlockCaps(collateralIndex, [...Array(pairs.length).keys()]);
|
|
37
28
|
return (0, trade_1.convertPairBorrowingFees)([pairs, pairOi, pairGroups, feeCaps]);
|
|
38
|
-
}
|
|
29
|
+
};
|
|
39
30
|
exports.fetchAllPairBorrowingFees = fetchAllPairBorrowingFees;
|
|
40
|
-
const fetchGroupBorrowingFees = (contract, collateralIndex, groupIxs) =>
|
|
41
|
-
return (0, trade_1.convertGroupBorrowingFees)(yield contract.getBorrowingGroups(collateralIndex, groupIxs));
|
|
42
|
-
});
|
|
31
|
+
const fetchGroupBorrowingFees = async (contract, collateralIndex, groupIxs) => (0, trade_1.convertGroupBorrowingFees)(await contract.getBorrowingGroups(collateralIndex, groupIxs));
|
|
43
32
|
exports.fetchGroupBorrowingFees = fetchGroupBorrowingFees;
|
|
44
|
-
const fetchAllPairAndGroupBorrowingFees = (contract, collateralIndex) =>
|
|
45
|
-
const pairs =
|
|
33
|
+
const fetchAllPairAndGroupBorrowingFees = async (contract, collateralIndex) => {
|
|
34
|
+
const pairs = await (0, exports.fetchAllPairBorrowingFees)(contract, collateralIndex);
|
|
46
35
|
const groupIxs = [
|
|
47
36
|
...new Set(pairs
|
|
48
37
|
.map(value => value.groups.map(value => value.groupIndex))
|
|
49
38
|
.reduce((acc, value) => acc.concat(value), [])),
|
|
50
39
|
].sort((a, b) => a - b);
|
|
51
|
-
const groups =
|
|
40
|
+
const groups = await (0, exports.fetchGroupBorrowingFees)(contract, collateralIndex, groupIxs);
|
|
52
41
|
return { pairs, groups };
|
|
53
|
-
}
|
|
42
|
+
};
|
|
54
43
|
exports.fetchAllPairAndGroupBorrowingFees = fetchAllPairAndGroupBorrowingFees;
|
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.fetchOpenPairTradesRaw = exports.fetchOpenPairTrades = void 0;
|
|
13
4
|
const ethcall_1 = require("ethcall");
|
|
14
5
|
const trade_1 = require("../../trade");
|
|
15
|
-
const fetchOpenPairTrades = (contracts, overrides = {}) =>
|
|
16
|
-
const rawTrades =
|
|
17
|
-
const collaterals =
|
|
6
|
+
const fetchOpenPairTrades = async (contracts, overrides = {}) => {
|
|
7
|
+
const rawTrades = await (0, exports.fetchOpenPairTradesRaw)(contracts, overrides);
|
|
8
|
+
const collaterals = await contracts.gnsMultiCollatDiamond.getCollaterals();
|
|
18
9
|
const collateralConfigs = collaterals.map(c => ({
|
|
19
10
|
collateral: c.collateral,
|
|
20
11
|
isActive: c.isActive,
|
|
@@ -22,10 +13,10 @@ const fetchOpenPairTrades = (contracts, overrides = {}) => __awaiter(void 0, voi
|
|
|
22
13
|
precisionDelta: parseFloat(c.precisionDelta.toString()),
|
|
23
14
|
}));
|
|
24
15
|
return rawTrades.map(rawTrade => _prepareTradeContainer(rawTrade.trade, rawTrade.tradeInfo, rawTrade.liquidationParams, rawTrade.initialAccFees, rawTrade.tradeFeesData, rawTrade.uiRealizedPnlData, collateralConfigs[parseInt(rawTrade.trade.collateralIndex.toString()) - 1]));
|
|
25
|
-
}
|
|
16
|
+
};
|
|
26
17
|
exports.fetchOpenPairTrades = fetchOpenPairTrades;
|
|
27
18
|
// @todo rename
|
|
28
|
-
const fetchOpenPairTradesRaw = (contracts, overrides = {}) =>
|
|
19
|
+
const fetchOpenPairTradesRaw = async (contracts, overrides = {}) => {
|
|
29
20
|
if (!contracts) {
|
|
30
21
|
return [];
|
|
31
22
|
}
|
|
@@ -39,13 +30,13 @@ const fetchOpenPairTradesRaw = (contracts, overrides = {}) => __awaiter(void 0,
|
|
|
39
30
|
]),
|
|
40
31
|
};
|
|
41
32
|
if (useMulticall) {
|
|
42
|
-
|
|
33
|
+
await multicallCtx.provider.init(multiCollatDiamondContract.provider);
|
|
43
34
|
}
|
|
44
35
|
let allOpenPairTrades = [];
|
|
45
36
|
let running = true;
|
|
46
37
|
let offset = 0;
|
|
47
38
|
while (running) {
|
|
48
|
-
const [trades, tradeInfos, tradeLiquidationParams] =
|
|
39
|
+
const [trades, tradeInfos, tradeLiquidationParams] = await Promise.all([
|
|
49
40
|
multiCollatDiamondContract.getAllTrades(offset, offset + batchSize),
|
|
50
41
|
multiCollatDiamondContract.getAllTradeInfos(offset, offset + batchSize),
|
|
51
42
|
multiCollatDiamondContract.getAllTradesLiquidationParams(offset, offset + batchSize),
|
|
@@ -85,7 +76,7 @@ const fetchOpenPairTradesRaw = (contracts, overrides = {}) => __awaiter(void 0,
|
|
|
85
76
|
uiRealizedPnlData: undefined,
|
|
86
77
|
};
|
|
87
78
|
});
|
|
88
|
-
const [tradeFeesData, uiRealizedPnlData] =
|
|
79
|
+
const [tradeFeesData, uiRealizedPnlData] = await Promise.all([
|
|
89
80
|
multiCollatDiamondContract.getTradeFeesDataArray(...fundingFeesCallParams),
|
|
90
81
|
includeUIRealizedPnlData
|
|
91
82
|
? multiCollatDiamondContract.getTradeUiRealizedPnlDataArray(...fundingFeesCallParams)
|
|
@@ -100,13 +91,13 @@ const fetchOpenPairTradesRaw = (contracts, overrides = {}) => __awaiter(void 0,
|
|
|
100
91
|
.map(({ collateralIndex, user, index }) => (useMulticall
|
|
101
92
|
? multicallCtx.diamond
|
|
102
93
|
: multiCollatDiamondContract).getBorrowingInitialAccFees(collateralIndex, user, index));
|
|
103
|
-
const initialAccFees =
|
|
94
|
+
const initialAccFees = await (useMulticall
|
|
104
95
|
? multicallCtx.provider.all(initialAccFeesPromises)
|
|
105
96
|
: Promise.all(initialAccFeesPromises));
|
|
106
97
|
initialAccFees.forEach((accFees, ix) => {
|
|
107
98
|
openTrades[ix].initialAccFees = accFees;
|
|
108
99
|
openTrades[ix].tradeFeesData = tradeFeesData[ix];
|
|
109
|
-
openTrades[ix].uiRealizedPnlData = uiRealizedPnlData
|
|
100
|
+
openTrades[ix].uiRealizedPnlData = uiRealizedPnlData?.[ix];
|
|
110
101
|
});
|
|
111
102
|
allOpenPairTrades = allOpenPairTrades.concat(openTrades);
|
|
112
103
|
offset += batchSize + 1;
|
|
@@ -119,7 +110,7 @@ const fetchOpenPairTradesRaw = (contracts, overrides = {}) => __awaiter(void 0,
|
|
|
119
110
|
console.error(`Unexpected error while fetching open pair trades!`);
|
|
120
111
|
throw error;
|
|
121
112
|
}
|
|
122
|
-
}
|
|
113
|
+
};
|
|
123
114
|
exports.fetchOpenPairTradesRaw = fetchOpenPairTradesRaw;
|
|
124
115
|
const _prepareTradeContainer = (trade, tradeInfo, tradeLiquidationParams, tradeInitialAccFees, tradeFeesData, uiRealizedPnlData, collateralConfig) => {
|
|
125
116
|
const precision = collateralConfig.precision;
|
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.getPairDescription = exports.fetchOpenInterest = exports.fetchFees = exports.fetchPairDepths = exports.fetchPairs = void 0;
|
|
13
4
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
14
5
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
15
6
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
16
7
|
const types_1 = require("../../trade/types");
|
|
17
|
-
const fetchPairs = (contracts, pairIxs) =>
|
|
8
|
+
const fetchPairs = async (contracts, pairIxs) => {
|
|
18
9
|
if (!contracts) {
|
|
19
10
|
return [];
|
|
20
11
|
}
|
|
21
12
|
const { gnsMultiCollatDiamond: multiCollatContract } = contracts;
|
|
22
13
|
try {
|
|
23
|
-
const pairs =
|
|
14
|
+
const pairs = await Promise.all(pairIxs.map(pairIndex => multiCollatContract.pairs(pairIndex)));
|
|
24
15
|
return pairs.map((pair, index) => {
|
|
25
16
|
return {
|
|
26
17
|
name: pair.from + "/" + pair.to,
|
|
@@ -38,15 +29,15 @@ const fetchPairs = (contracts, pairIxs) => __awaiter(void 0, void 0, void 0, fun
|
|
|
38
29
|
console.error(`Unexpected error while fetching pairs!`);
|
|
39
30
|
throw error;
|
|
40
31
|
}
|
|
41
|
-
}
|
|
32
|
+
};
|
|
42
33
|
exports.fetchPairs = fetchPairs;
|
|
43
|
-
const fetchPairDepths = (contracts, pairIxs) =>
|
|
34
|
+
const fetchPairDepths = async (contracts, pairIxs) => {
|
|
44
35
|
if (!contracts) {
|
|
45
36
|
return [];
|
|
46
37
|
}
|
|
47
38
|
const { gnsMultiCollatDiamond: multiCollatContract } = contracts;
|
|
48
39
|
try {
|
|
49
|
-
const pairParams =
|
|
40
|
+
const pairParams = await multiCollatContract.getPairDepths(pairIxs);
|
|
50
41
|
return pairParams.map(pair => {
|
|
51
42
|
return {
|
|
52
43
|
onePercentDepthAboveUsd: parseFloat(pair.onePercentDepthAboveUsd.toString()),
|
|
@@ -58,15 +49,15 @@ const fetchPairDepths = (contracts, pairIxs) => __awaiter(void 0, void 0, void 0
|
|
|
58
49
|
console.error(`Unexpected error while fetching pairs!`);
|
|
59
50
|
throw error;
|
|
60
51
|
}
|
|
61
|
-
}
|
|
52
|
+
};
|
|
62
53
|
exports.fetchPairDepths = fetchPairDepths;
|
|
63
|
-
const fetchFees = (contracts, feeIxs) =>
|
|
54
|
+
const fetchFees = async (contracts, feeIxs) => {
|
|
64
55
|
if (!contracts) {
|
|
65
56
|
return [];
|
|
66
57
|
}
|
|
67
58
|
const { gnsMultiCollatDiamond: multiCollatContract } = contracts;
|
|
68
59
|
try {
|
|
69
|
-
const fees =
|
|
60
|
+
const fees = await Promise.all(feeIxs.map(pairIndex => multiCollatContract.fees(pairIndex)));
|
|
70
61
|
return fees.map(fee => {
|
|
71
62
|
return {
|
|
72
63
|
totalPositionSizeFeeP: parseFloat(fee.totalPositionSizeFeeP.toString()) / 1e12,
|
|
@@ -80,13 +71,13 @@ const fetchFees = (contracts, feeIxs) => __awaiter(void 0, void 0, void 0, funct
|
|
|
80
71
|
console.error(`Unexpected error while fetching pairs!`);
|
|
81
72
|
throw error;
|
|
82
73
|
}
|
|
83
|
-
}
|
|
74
|
+
};
|
|
84
75
|
exports.fetchFees = fetchFees;
|
|
85
|
-
const fetchOpenInterest = (contracts, collateralIndex, pairIxs) =>
|
|
76
|
+
const fetchOpenInterest = async (contracts, collateralIndex, pairIxs) => {
|
|
86
77
|
if (pairIxs.length === 0) {
|
|
87
78
|
return [];
|
|
88
79
|
}
|
|
89
|
-
const openInterests = (
|
|
80
|
+
const openInterests = (await contracts.gnsMultiCollatDiamond.getAllBorrowingPairs(collateralIndex))[1];
|
|
90
81
|
return pairIxs.map(pairIndex => {
|
|
91
82
|
const openInterest = openInterests[pairIndex];
|
|
92
83
|
if (!openInterest) {
|
|
@@ -98,7 +89,7 @@ const fetchOpenInterest = (contracts, collateralIndex, pairIxs) => __awaiter(voi
|
|
|
98
89
|
max: parseFloat(openInterest[2].toString()) / 1e10,
|
|
99
90
|
};
|
|
100
91
|
});
|
|
101
|
-
}
|
|
92
|
+
};
|
|
102
93
|
exports.fetchOpenInterest = fetchOpenInterest;
|
|
103
94
|
const getPairDescription = (pairIndex) => {
|
|
104
95
|
return PAIR_INDEX_TO_DESCRIPTION[pairIndex] || "";
|
package/lib/markets/forex.js
CHANGED
|
@@ -33,7 +33,7 @@ const isForexLowLiquidity = (timestampToCheck, pair) => {
|
|
|
33
33
|
const hour = now.hour;
|
|
34
34
|
const minute = now.minute;
|
|
35
35
|
const isInDST = now.isInDST;
|
|
36
|
-
const groupIndex = pair
|
|
36
|
+
const groupIndex = pair?.groupIndex;
|
|
37
37
|
if (groupIndex && extendedLowLiqGroupIds.includes(+groupIndex)) {
|
|
38
38
|
return ((isInDST &&
|
|
39
39
|
((hour == 14 && minute >= 45) || (hour >= 15 && hour < 21))) ||
|
|
@@ -18,8 +18,8 @@ const buildMarketLeverageRestrictionsContext = (globalTradingVariables, pairInde
|
|
|
18
18
|
return {
|
|
19
19
|
groupMinLeverage: group.minLeverage,
|
|
20
20
|
groupMaxLeverage: group.maxLeverage,
|
|
21
|
-
pairMaxLeverage: pairMaxLeverages
|
|
22
|
-
counterTradeSettings: counterTradeSettings
|
|
21
|
+
pairMaxLeverage: pairMaxLeverages?.[pairIndex],
|
|
22
|
+
counterTradeSettings: counterTradeSettings?.[pairIndex],
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
25
|
exports.buildMarketLeverageRestrictionsContext = buildMarketLeverageRestrictionsContext;
|
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
import { SignedPricesResponse } from "./types";
|
|
2
|
-
|
|
2
|
+
import { PendingOrderType } from "../../trade";
|
|
3
|
+
export interface FetchSignedPricesInput {
|
|
3
4
|
oracles: string[];
|
|
4
5
|
pairs: number[];
|
|
5
|
-
|
|
6
|
+
chain: number;
|
|
6
7
|
authKey?: string;
|
|
7
8
|
minAnswer?: number;
|
|
8
9
|
timeoutMs?: number;
|
|
9
10
|
}
|
|
10
|
-
export declare const fetchSignedPrices: (input:
|
|
11
|
-
export
|
|
11
|
+
export declare const fetchSignedPrices: (input: FetchSignedPricesInput) => Promise<SignedPricesResponse[] | null>;
|
|
12
|
+
export interface FetchSignedLookbackPricesInput {
|
|
13
|
+
oracles: string[];
|
|
14
|
+
trader: string;
|
|
15
|
+
tradeIndex: number;
|
|
16
|
+
pair: number;
|
|
17
|
+
orderType: PendingOrderType;
|
|
18
|
+
currentBlock: number;
|
|
19
|
+
fromBlock: number;
|
|
20
|
+
chain: number;
|
|
21
|
+
authKey?: string;
|
|
22
|
+
minAnswer?: number;
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
}
|
|
25
|
+
export declare const fetchSignedLookbackPrices: (input: FetchSignedLookbackPricesInput) => Promise<SignedPricesResponse[] | null>;
|
|
12
26
|
export declare const validateSignedPricesPairs: (pairs: number[]) => {
|
|
13
27
|
valid: boolean;
|
|
14
28
|
pairs: number[];
|
|
15
29
|
};
|
|
30
|
+
export declare const isValidSignedPricesChain: (chainId: number) => boolean;
|
|
31
|
+
export declare const isValidSignedPricesOrderType: (orderType: PendingOrderType) => boolean;
|
|
@@ -1,21 +1,54 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isValidSignedPricesOrderType = exports.isValidSignedPricesChain = exports.validateSignedPricesPairs = exports.fetchSignedLookbackPrices = exports.fetchSignedPrices = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
4
5
|
const types_1 = require("../../contracts/types");
|
|
6
|
+
const trade_1 = require("../../trade");
|
|
5
7
|
const fetchSignedPrices = async (input) => {
|
|
6
|
-
const { minAnswers, timeoutMs, oracles,
|
|
7
|
-
minAnswers: input.
|
|
8
|
+
const { minAnswers, timeoutMs, oracles, chain, authKey } = {
|
|
9
|
+
minAnswers: input.chain === types_1.ChainId.ARBITRUM_SEPOLIA ? 2 : 3,
|
|
8
10
|
timeoutMs: 1000,
|
|
9
11
|
...input,
|
|
10
12
|
};
|
|
11
|
-
if (!(0, exports.isValidSignedPricesChain)(
|
|
12
|
-
throw new Error(`Invalid
|
|
13
|
-
const { valid, pairs
|
|
13
|
+
if (!(0, exports.isValidSignedPricesChain)(chain))
|
|
14
|
+
throw new Error(`Invalid chain ${chain}`);
|
|
15
|
+
const { valid, pairs } = (0, exports.validateSignedPricesPairs)(input.pairs);
|
|
14
16
|
if (!valid)
|
|
15
17
|
throw new Error(`Invalid pairs array`);
|
|
18
|
+
return await initiateSignedPricesRequest(oracles, "signPrices", JSON.stringify({ pairs, chain }), minAnswers, authKey || "", timeoutMs);
|
|
19
|
+
};
|
|
20
|
+
exports.fetchSignedPrices = fetchSignedPrices;
|
|
21
|
+
const fetchSignedLookbackPrices = async (input) => {
|
|
22
|
+
const { minAnswers, timeoutMs, oracles, trader, tradeIndex, pair, orderType, currentBlock, fromBlock, chain, authKey, } = {
|
|
23
|
+
minAnswers: input.chain === types_1.ChainId.ARBITRUM_SEPOLIA ? 2 : 3,
|
|
24
|
+
timeoutMs: 6000,
|
|
25
|
+
...input,
|
|
26
|
+
};
|
|
27
|
+
if (!(0, exports.isValidSignedPricesChain)(chain))
|
|
28
|
+
throw new Error(`Invalid chain ${chain}`);
|
|
29
|
+
if (!(0, exports.isValidSignedPricesOrderType)(orderType))
|
|
30
|
+
throw new Error(`Invalid orderType ${orderType}`);
|
|
31
|
+
if (isNaN(pair))
|
|
32
|
+
throw new Error(`Invalid pair ${pair}`);
|
|
33
|
+
if (isNaN(tradeIndex) || tradeIndex < 0)
|
|
34
|
+
throw new Error(`Invalid tradeIndex ${tradeIndex}`);
|
|
35
|
+
if (!currentBlock || !fromBlock)
|
|
36
|
+
throw new Error(`Invalid block numbers`);
|
|
37
|
+
return await initiateSignedPricesRequest(oracles, "signLookbackPrices", JSON.stringify({
|
|
38
|
+
trader,
|
|
39
|
+
tradeIndex,
|
|
40
|
+
pair,
|
|
41
|
+
orderType,
|
|
42
|
+
currentBlock,
|
|
43
|
+
fromBlock,
|
|
44
|
+
chain,
|
|
45
|
+
}), minAnswers, authKey || "", timeoutMs);
|
|
46
|
+
};
|
|
47
|
+
exports.fetchSignedLookbackPrices = fetchSignedLookbackPrices;
|
|
48
|
+
const initiateSignedPricesRequest = async (oracles, request, requestBody, minAnswers, authKey, timeoutMs) => {
|
|
16
49
|
try {
|
|
17
50
|
// Fetch signed prices from all oracles in parallel
|
|
18
|
-
const signedPrices = await Promise.allSettled(oracles.map(signerUrl => _getSignedPricesFromSigner(signerUrl
|
|
51
|
+
const signedPrices = await Promise.allSettled(oracles.map(signerUrl => _getSignedPricesFromSigner(`${signerUrl}/${request}`, requestBody, authKey, timeoutMs)));
|
|
19
52
|
// Filter out failed requests and null responses, then sort by signerId
|
|
20
53
|
const successfulResponses = signedPrices.filter(res => res.status === "fulfilled" && res.value !== null // Filter out failed or null responses
|
|
21
54
|
)
|
|
@@ -34,34 +67,41 @@ const fetchSignedPrices = async (input) => {
|
|
|
34
67
|
throw e;
|
|
35
68
|
}
|
|
36
69
|
};
|
|
37
|
-
|
|
38
|
-
const _getSignedPricesFromSigner = async (signerUrl, pairIndices, chainId, authKey, timeoutMs) => {
|
|
70
|
+
const _getSignedPricesFromSigner = async (url, requestBody, authKey, timeoutMs) => {
|
|
39
71
|
try {
|
|
40
72
|
const controller = new AbortController();
|
|
41
73
|
const timeout = setTimeout(() => {
|
|
42
74
|
controller.abort();
|
|
43
|
-
}, timeoutMs ||
|
|
44
|
-
|
|
45
|
-
const response = await fetch(`${signerUrl}/signPrices`, {
|
|
75
|
+
}, timeoutMs || 2000);
|
|
76
|
+
const response = await fetch(`${url}`, {
|
|
46
77
|
method: "POST",
|
|
47
78
|
headers: {
|
|
48
79
|
"Content-Type": "application/json",
|
|
49
80
|
"x-api-key": authKey || "",
|
|
50
81
|
},
|
|
51
|
-
body:
|
|
82
|
+
body: requestBody,
|
|
52
83
|
signal: controller.signal,
|
|
53
84
|
});
|
|
54
85
|
clearTimeout(timeout);
|
|
55
86
|
if (!response.ok) {
|
|
56
|
-
throw new Error(`Failed to fetch signed prices from ${
|
|
87
|
+
throw new Error(`Failed to fetch signed prices from ${url}: ${response.statusText}`);
|
|
57
88
|
}
|
|
58
89
|
return (await response.json());
|
|
59
90
|
}
|
|
60
91
|
catch (error) {
|
|
61
|
-
console.error(`Error fetching signed prices from ${
|
|
92
|
+
console.error(`Error fetching signed prices from ${url}:`, {
|
|
93
|
+
error: error?.message,
|
|
94
|
+
});
|
|
62
95
|
return null;
|
|
63
96
|
}
|
|
64
97
|
};
|
|
98
|
+
const validateSignedPricesPairs = (pairs) => {
|
|
99
|
+
if (!Array.isArray(pairs) || pairs?.length === 0 || pairs.some(p => isNaN(p)))
|
|
100
|
+
return { valid: false, pairs: [] };
|
|
101
|
+
// Pairs must always be in ascending order
|
|
102
|
+
return { valid: true, pairs: [...new Set(pairs)].sort((a, b) => a - b) };
|
|
103
|
+
};
|
|
104
|
+
exports.validateSignedPricesPairs = validateSignedPricesPairs;
|
|
65
105
|
const isValidSignedPricesChain = (chainId) => {
|
|
66
106
|
return (!isNaN(chainId) &&
|
|
67
107
|
[
|
|
@@ -73,10 +113,14 @@ const isValidSignedPricesChain = (chainId) => {
|
|
|
73
113
|
].includes(chainId));
|
|
74
114
|
};
|
|
75
115
|
exports.isValidSignedPricesChain = isValidSignedPricesChain;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
116
|
+
const isValidSignedPricesOrderType = (orderType) => {
|
|
117
|
+
return (!isNaN(orderType) &&
|
|
118
|
+
[
|
|
119
|
+
trade_1.PendingOrderType.LIMIT_OPEN,
|
|
120
|
+
trade_1.PendingOrderType.STOP_OPEN,
|
|
121
|
+
trade_1.PendingOrderType.TP_CLOSE,
|
|
122
|
+
trade_1.PendingOrderType.SL_CLOSE,
|
|
123
|
+
trade_1.PendingOrderType.LIQ_CLOSE,
|
|
124
|
+
].includes(orderType));
|
|
81
125
|
};
|
|
82
|
-
exports.
|
|
126
|
+
exports.isValidSignedPricesOrderType = isValidSignedPricesOrderType;
|
|
@@ -21,3 +21,26 @@ export type MarketPriceContext = {
|
|
|
21
21
|
oiShortToken: number;
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* @dev Types for signed prices data structure
|
|
26
|
+
*/
|
|
27
|
+
export type SignedPricesResponse = {
|
|
28
|
+
signedData: SignedPrices;
|
|
29
|
+
missingPrices: number[];
|
|
30
|
+
};
|
|
31
|
+
export type SignedPrices = {
|
|
32
|
+
signerId: number;
|
|
33
|
+
expiryTs: number;
|
|
34
|
+
fromBlock: number;
|
|
35
|
+
isLookback: boolean;
|
|
36
|
+
pairIndices: number[];
|
|
37
|
+
prices: Price[];
|
|
38
|
+
signature: string;
|
|
39
|
+
};
|
|
40
|
+
export type Price = {
|
|
41
|
+
open: string;
|
|
42
|
+
high: string;
|
|
43
|
+
low: string;
|
|
44
|
+
current: string;
|
|
45
|
+
ts: number;
|
|
46
|
+
};
|
|
@@ -13,9 +13,8 @@ exports.buildBorrowingV1Context = void 0;
|
|
|
13
13
|
* @returns Full borrowing context with all pairs and groups or undefined if data not available
|
|
14
14
|
*/
|
|
15
15
|
const buildBorrowingV1Context = (globalTradingVariables, collateralIndex, currentBlock) => {
|
|
16
|
-
var _a;
|
|
17
16
|
const collateral = globalTradingVariables.collaterals[collateralIndex - 1];
|
|
18
|
-
if (!
|
|
17
|
+
if (!collateral?.pairBorrowingFees || !collateral?.groupBorrowingFees) {
|
|
19
18
|
return undefined;
|
|
20
19
|
}
|
|
21
20
|
const pairs = collateral.pairBorrowingFees;
|
|
@@ -27,7 +26,7 @@ const buildBorrowingV1Context = (globalTradingVariables, collateralIndex, curren
|
|
|
27
26
|
currentBlock,
|
|
28
27
|
pairs,
|
|
29
28
|
groups,
|
|
30
|
-
collateralPriceUsd:
|
|
29
|
+
collateralPriceUsd: collateral.prices?.collateralPriceUsd || 1,
|
|
31
30
|
pairOis: collateral.pairOis,
|
|
32
31
|
};
|
|
33
32
|
};
|
|
@@ -14,7 +14,11 @@ const convertPairGroupBorrowingFee = (pairGroup) => ({
|
|
|
14
14
|
block: pairGroup.block,
|
|
15
15
|
});
|
|
16
16
|
exports.convertPairGroupBorrowingFee = convertPairGroupBorrowingFee;
|
|
17
|
-
const convertPairBorrowingFee = (pair, pairOi, pairGroup, feeCap) => (
|
|
17
|
+
const convertPairBorrowingFee = (pair, pairOi, pairGroup, feeCap) => ({
|
|
18
|
+
...(0, exports.convertGroupBorrowingData)(pair, pairOi),
|
|
19
|
+
groups: pairGroup.map(value => (0, exports.convertPairGroupBorrowingFee)(value)),
|
|
20
|
+
feePerBlockCap: (0, exports.convertFeePerBlockCap)(feeCap),
|
|
21
|
+
});
|
|
18
22
|
exports.convertPairBorrowingFee = convertPairBorrowingFee;
|
|
19
23
|
const convertPairBorrowingFees = ([pairs, pairOi, pairGroups, feeCaps]) => pairs.map((value, ix) => (0, exports.convertPairBorrowingFee)(value, pairOi[ix], pairGroups[ix], feeCaps[ix]));
|
|
20
24
|
exports.convertPairBorrowingFees = convertPairBorrowingFees;
|
|
@@ -48,7 +48,7 @@ const getBorrowingFee = (posDai, pairIndex, long, initialAccFees, currentPairPri
|
|
|
48
48
|
return 0;
|
|
49
49
|
}
|
|
50
50
|
const pairGroups = pairs[pairIndex].groups;
|
|
51
|
-
const firstPairGroup =
|
|
51
|
+
const firstPairGroup = pairGroups?.length > 0 ? pairGroups[0] : undefined;
|
|
52
52
|
let fee = 0;
|
|
53
53
|
if (!firstPairGroup || firstPairGroup.block > initialAccFees.block) {
|
|
54
54
|
const openInterest = (0, __1.getPairTotalOisDynamicCollateral)(pairIndex, {
|
|
@@ -215,13 +215,13 @@ collateralPriceUsd) => {
|
|
|
215
215
|
};
|
|
216
216
|
const getPendingAccFeesDelta = (blockDistance, feePerBlock, netOi, maxOi, feeExponent) => {
|
|
217
217
|
return maxOi > 0 && feeExponent > 0
|
|
218
|
-
? feePerBlock * blockDistance *
|
|
218
|
+
? feePerBlock * blockDistance * (netOi / maxOi) ** feeExponent
|
|
219
219
|
: 0;
|
|
220
220
|
};
|
|
221
221
|
const getFeePerBlockCaps = (cap) => {
|
|
222
222
|
return {
|
|
223
|
-
minP:
|
|
224
|
-
maxP:
|
|
223
|
+
minP: cap?.minP || 0,
|
|
224
|
+
maxP: cap?.maxP && cap.maxP > 0 ? cap.maxP : 1,
|
|
225
225
|
};
|
|
226
226
|
};
|
|
227
227
|
const getBorrowingDataActiveFeePerBlock = (val) => {
|
|
@@ -231,7 +231,7 @@ const getBorrowingDataActiveFeePerBlock = (val) => {
|
|
|
231
231
|
// If minP > 0 then netOi has to be at least minP * maxOi
|
|
232
232
|
// If maxP > 0 then netOi cannot be more than maxP * maxOi
|
|
233
233
|
const effectiveOi = Math.min(Math.max(Math.abs(long - short), max * minP), max * maxP);
|
|
234
|
-
return val.feePerBlock *
|
|
234
|
+
return val.feePerBlock * (effectiveOi / max) ** val.feeExponent;
|
|
235
235
|
};
|
|
236
236
|
const getActiveFeePerBlock = (pair, group) => {
|
|
237
237
|
const pairFeePerBlock = getBorrowingDataActiveFeePerBlock(pair);
|
|
@@ -5,13 +5,12 @@ exports.buildBorrowingV2Context = void 0;
|
|
|
5
5
|
* @dev Builds borrowing v2 sub-context for a specific pair
|
|
6
6
|
*/
|
|
7
7
|
const buildBorrowingV2Context = (globalTradingVariables, collateralIndex, pairIndex, currentTimestamp) => {
|
|
8
|
-
var _a, _b;
|
|
9
8
|
const collateral = globalTradingVariables.collaterals[collateralIndex - 1];
|
|
10
|
-
if (!
|
|
9
|
+
if (!collateral?.pairBorrowingFeesV2) {
|
|
11
10
|
return undefined;
|
|
12
11
|
}
|
|
13
|
-
const params =
|
|
14
|
-
const data =
|
|
12
|
+
const params = collateral.pairBorrowingFeesV2.params?.[pairIndex];
|
|
13
|
+
const data = collateral.pairBorrowingFeesV2.data?.[pairIndex];
|
|
15
14
|
if (!params || !data) {
|
|
16
15
|
return undefined;
|
|
17
16
|
}
|
|
@@ -116,7 +116,7 @@ exports.aprToBorrowingRate = aprToBorrowingRate;
|
|
|
116
116
|
*/
|
|
117
117
|
const createCollateralScopedBorrowingContext = (collateralBorrowingData, currentTimestamp) => {
|
|
118
118
|
const context = {
|
|
119
|
-
currentTimestamp: currentTimestamp
|
|
119
|
+
currentTimestamp: currentTimestamp ?? Math.floor(Date.now() / 1000),
|
|
120
120
|
borrowingParams: {},
|
|
121
121
|
borrowingData: {},
|
|
122
122
|
};
|