@dhedge/v2-sdk 1.8.3 → 1.9.1
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 +7 -0
- package/dist/entities/pool.d.ts +29 -1
- package/dist/errors.d.ts +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/services/futures/trade.d.ts +1 -0
- package/dist/services/velodrome/staking.d.ts +2 -2
- package/dist/services/zeroEx/zeroExTrade.d.ts +3 -0
- package/dist/test/constants.d.ts +9 -2
- package/dist/test/utils/futures.d.ts +2 -0
- package/dist/types.d.ts +5 -2
- package/dist/v2-sdk.cjs.development.js +748 -131
- 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 +748 -132
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +3 -2
- package/src/abi/IVelodromeGaugeV2.json +191 -0
- package/src/config.ts +28 -9
- package/src/entities/pool.ts +110 -6
- package/src/errors.ts +10 -0
- package/src/index.ts +1 -0
- package/src/services/futures/trade.ts +6 -0
- package/src/services/velodrome/staking.ts +33 -20
- package/src/services/zeroEx/zeroExTrade.ts +52 -0
- package/src/test/aave.test.ts +71 -112
- package/src/test/balancer.test.ts +108 -200
- package/src/test/constants.ts +11 -4
- package/src/test/futures.test.ts +5 -2
- package/src/test/oneInch.test.ts +4 -3
- package/src/test/txOptions.ts +1 -1
- package/src/test/utils/futures.ts +14 -0
- package/src/test/velodromeV2.test.ts +114 -0
- package/src/test/wallet.ts +1 -1
- package/src/test/zeroEx.test.ts +46 -0
- package/src/types.ts +5 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhedge/v2-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "🛠 An SDK for building applications on top of dHEDGE V2",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"size": "size-limit",
|
|
22
22
|
"analyze": "size-limit --why",
|
|
23
23
|
"fork:polygon": "hardhat node --fork $(grep POLYGON_URL .env | cut -d '=' -f2)",
|
|
24
|
-
"fork:optimism": "hardhat node --fork $(grep OPTIMISM_URL .env | cut -d '=' -f2)"
|
|
24
|
+
"fork:optimism": "hardhat node --fork $(grep OPTIMISM_URL .env | cut -d '=' -f2)",
|
|
25
|
+
"fork:arbitrum": "hardhat node --fork $(grep ARBITRUM_URL .env | cut -d '=' -f2)"
|
|
25
26
|
},
|
|
26
27
|
"husky": {
|
|
27
28
|
"hooks": {
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
{
|
|
2
|
+
"abi": [
|
|
3
|
+
{
|
|
4
|
+
"inputs": [
|
|
5
|
+
{
|
|
6
|
+
"internalType": "address",
|
|
7
|
+
"name": "user",
|
|
8
|
+
"type": "address"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"name": "balanceOf",
|
|
12
|
+
"outputs": [
|
|
13
|
+
{
|
|
14
|
+
"internalType": "uint256",
|
|
15
|
+
"name": "",
|
|
16
|
+
"type": "uint256"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"stateMutability": "view",
|
|
20
|
+
"type": "function"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"inputs": [
|
|
24
|
+
{
|
|
25
|
+
"internalType": "uint256",
|
|
26
|
+
"name": "_amount",
|
|
27
|
+
"type": "uint256"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"internalType": "address",
|
|
31
|
+
"name": "_recipient",
|
|
32
|
+
"type": "address"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"name": "deposit",
|
|
36
|
+
"outputs": [],
|
|
37
|
+
"stateMutability": "nonpayable",
|
|
38
|
+
"type": "function"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"inputs": [
|
|
42
|
+
{
|
|
43
|
+
"internalType": "uint256",
|
|
44
|
+
"name": "_amount",
|
|
45
|
+
"type": "uint256"
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"name": "deposit",
|
|
49
|
+
"outputs": [],
|
|
50
|
+
"stateMutability": "nonpayable",
|
|
51
|
+
"type": "function"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"inputs": [
|
|
55
|
+
{
|
|
56
|
+
"internalType": "address",
|
|
57
|
+
"name": "_account",
|
|
58
|
+
"type": "address"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"name": "earned",
|
|
62
|
+
"outputs": [
|
|
63
|
+
{
|
|
64
|
+
"internalType": "uint256",
|
|
65
|
+
"name": "_earned",
|
|
66
|
+
"type": "uint256"
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"stateMutability": "view",
|
|
70
|
+
"type": "function"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"inputs": [
|
|
74
|
+
{
|
|
75
|
+
"internalType": "address",
|
|
76
|
+
"name": "_account",
|
|
77
|
+
"type": "address"
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"name": "getReward",
|
|
81
|
+
"outputs": [],
|
|
82
|
+
"stateMutability": "nonpayable",
|
|
83
|
+
"type": "function"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"inputs": [],
|
|
87
|
+
"name": "isPool",
|
|
88
|
+
"outputs": [
|
|
89
|
+
{
|
|
90
|
+
"internalType": "bool",
|
|
91
|
+
"name": "_isPool",
|
|
92
|
+
"type": "bool"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"stateMutability": "view",
|
|
96
|
+
"type": "function"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"inputs": [],
|
|
100
|
+
"name": "lastTimeRewardApplicable",
|
|
101
|
+
"outputs": [
|
|
102
|
+
{
|
|
103
|
+
"internalType": "uint256",
|
|
104
|
+
"name": "_time",
|
|
105
|
+
"type": "uint256"
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"stateMutability": "view",
|
|
109
|
+
"type": "function"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"inputs": [],
|
|
113
|
+
"name": "left",
|
|
114
|
+
"outputs": [
|
|
115
|
+
{
|
|
116
|
+
"internalType": "uint256",
|
|
117
|
+
"name": "_left",
|
|
118
|
+
"type": "uint256"
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"stateMutability": "view",
|
|
122
|
+
"type": "function"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"inputs": [
|
|
126
|
+
{
|
|
127
|
+
"internalType": "uint256",
|
|
128
|
+
"name": "amount",
|
|
129
|
+
"type": "uint256"
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"name": "notifyRewardAmount",
|
|
133
|
+
"outputs": [],
|
|
134
|
+
"stateMutability": "nonpayable",
|
|
135
|
+
"type": "function"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"inputs": [],
|
|
139
|
+
"name": "rewardPerToken",
|
|
140
|
+
"outputs": [
|
|
141
|
+
{
|
|
142
|
+
"internalType": "uint256",
|
|
143
|
+
"name": "_rewardPerToken",
|
|
144
|
+
"type": "uint256"
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"stateMutability": "view",
|
|
148
|
+
"type": "function"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"inputs": [],
|
|
152
|
+
"name": "rewardToken",
|
|
153
|
+
"outputs": [
|
|
154
|
+
{
|
|
155
|
+
"internalType": "address",
|
|
156
|
+
"name": "_token",
|
|
157
|
+
"type": "address"
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
"stateMutability": "view",
|
|
161
|
+
"type": "function"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"inputs": [],
|
|
165
|
+
"name": "stakingToken",
|
|
166
|
+
"outputs": [
|
|
167
|
+
{
|
|
168
|
+
"internalType": "address",
|
|
169
|
+
"name": "_pool",
|
|
170
|
+
"type": "address"
|
|
171
|
+
}
|
|
172
|
+
],
|
|
173
|
+
"stateMutability": "view",
|
|
174
|
+
"type": "function"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"inputs": [
|
|
178
|
+
{
|
|
179
|
+
"internalType": "uint256",
|
|
180
|
+
"name": "_amount",
|
|
181
|
+
"type": "uint256"
|
|
182
|
+
}
|
|
183
|
+
],
|
|
184
|
+
"name": "withdraw",
|
|
185
|
+
"outputs": [],
|
|
186
|
+
"stateMutability": "nonpayable",
|
|
187
|
+
"type": "function"
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -15,7 +15,8 @@ export const factoryAddress: AddressNetworkMap = {
|
|
|
15
15
|
[Network.POLYGON]: process.env.STAGING_CONTRACTS
|
|
16
16
|
? "0xDd87eCdB10cFF7004276AAbAbd30e7a08F69bb53"
|
|
17
17
|
: "0xfdc7b8bFe0DD3513Cc669bB8d601Cb83e2F69cB0",
|
|
18
|
-
[Network.OPTIMISM]: "0x5e61a079A178f0E5784107a4963baAe0c5a680c6"
|
|
18
|
+
[Network.OPTIMISM]: "0x5e61a079A178f0E5784107a4963baAe0c5a680c6",
|
|
19
|
+
[Network.ARBITRUM]: "0xfffb5fb14606eb3a548c113026355020ddf27535"
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export const routerAddress: AddressDappNetworkMap = {
|
|
@@ -28,7 +29,8 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
28
29
|
[Dapp.BALANCER]: "0xBA12222222228d8Ba445958a75a0704d566BF2C8",
|
|
29
30
|
[Dapp.UNISWAPV3]: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
30
31
|
[Dapp.ARRAKIS]: "0xc73fb100a995b33f9fa181d420f4c8d74506df66",
|
|
31
|
-
[Dapp.TOROS]: "0xB2F1498983bf9c9442c35F772e6C1AdE66a8DeDE"
|
|
32
|
+
[Dapp.TOROS]: "0xB2F1498983bf9c9442c35F772e6C1AdE66a8DeDE",
|
|
33
|
+
[Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"
|
|
32
34
|
},
|
|
33
35
|
[Network.OPTIMISM]: {
|
|
34
36
|
[Dapp.UNISWAPV3]: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
@@ -37,8 +39,16 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
37
39
|
[Dapp.ONEINCH]: "0x1111111254EEB25477B68fb85Ed929f73A960582",
|
|
38
40
|
[Dapp.TOROS]: "0x3988513793bCE39f0167064A9F7fC3617FaF35AB",
|
|
39
41
|
[Dapp.VELODROME]: "0x9c12939390052919aF3155f41Bf4160Fd3666A6f",
|
|
42
|
+
[Dapp.VELODROMEV2]: "0xa062ae8a9c5e11aaa026fc2670b0d65ccc8b2858",
|
|
40
43
|
[Dapp.LYRA]: "0xCCE7819d65f348c64B7Beb205BA367b3fE33763B",
|
|
41
|
-
[Dapp.ARRAKIS]: "0x9ce88a56d120300061593eF7AD074A1B710094d5"
|
|
44
|
+
[Dapp.ARRAKIS]: "0x9ce88a56d120300061593eF7AD074A1B710094d5",
|
|
45
|
+
[Dapp.ZEROEX]: "0xdef1abe32c034e558cdd535791643c58a13acc10"
|
|
46
|
+
},
|
|
47
|
+
[Network.ARBITRUM]: {
|
|
48
|
+
[Dapp.ONEINCH]: "0x1111111254EEB25477B68fb85Ed929f73A960582",
|
|
49
|
+
[Dapp.UNISWAPV3]: "0xe592427a0aece92de3edee1f18e0157c05861564",
|
|
50
|
+
[Dapp.AAVEV3]: "0x794a61358D6845594F94dc1DB02A252b5b4814aD",
|
|
51
|
+
[Dapp.BALANCER]: "0xBA12222222228d8Ba445958a75a0704d566BF2C8"
|
|
42
52
|
}
|
|
43
53
|
};
|
|
44
54
|
|
|
@@ -47,7 +57,8 @@ export const dappFactoryAddress: AddressDappNetworkMap = {
|
|
|
47
57
|
[Dapp.SUSHISWAP]: "0xc35DADB65012eC5796536bD9864eD8773aBc74C4",
|
|
48
58
|
[Dapp.QUICKSWAP]: "0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32"
|
|
49
59
|
},
|
|
50
|
-
[Network.OPTIMISM]: {}
|
|
60
|
+
[Network.OPTIMISM]: {},
|
|
61
|
+
[Network.ARBITRUM]: {}
|
|
51
62
|
};
|
|
52
63
|
|
|
53
64
|
export const stakingAddress: AddressDappNetworkMap = {
|
|
@@ -57,7 +68,8 @@ export const stakingAddress: AddressDappNetworkMap = {
|
|
|
57
68
|
[Dapp.AAVE]: "0x357D51124f59836DeD84c8a1730D72B749d8BC23",
|
|
58
69
|
[Dapp.AAVEV3]: "0x929EC64c34a17401F460460D4B9390518E5B473e"
|
|
59
70
|
},
|
|
60
|
-
[Network.OPTIMISM]: {}
|
|
71
|
+
[Network.OPTIMISM]: {},
|
|
72
|
+
[Network.ARBITRUM]: {}
|
|
61
73
|
};
|
|
62
74
|
|
|
63
75
|
export const aaveAddressProvider: AddressDappNetworkMap = {
|
|
@@ -67,27 +79,34 @@ export const aaveAddressProvider: AddressDappNetworkMap = {
|
|
|
67
79
|
},
|
|
68
80
|
[Network.OPTIMISM]: {
|
|
69
81
|
[Dapp.AAVEV3]: "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb"
|
|
82
|
+
},
|
|
83
|
+
[Network.ARBITRUM]: {
|
|
84
|
+
[Dapp.AAVEV3]: "0xa97684ead0e402dc232d5a977953df7ecbab3cdb"
|
|
70
85
|
}
|
|
71
86
|
};
|
|
72
87
|
export const nonfungiblePositionManagerAddress: AddressNetworkMap = {
|
|
73
88
|
[Network.POLYGON]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
|
|
74
|
-
[Network.OPTIMISM]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
|
|
89
|
+
[Network.OPTIMISM]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
|
|
90
|
+
[Network.ARBITRUM]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
|
|
75
91
|
};
|
|
76
92
|
|
|
77
93
|
export const networkChainIdMap: NetworkChainIdMap = {
|
|
78
94
|
[Network.POLYGON]: 137,
|
|
79
|
-
[Network.OPTIMISM]: 10
|
|
95
|
+
[Network.OPTIMISM]: 10,
|
|
96
|
+
[Network.ARBITRUM]: 42161
|
|
80
97
|
};
|
|
81
98
|
|
|
82
99
|
export const balancerSubgraph: AddressNetworkMap = {
|
|
83
100
|
[Network.POLYGON]:
|
|
84
101
|
"https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-polygon-v2",
|
|
85
|
-
[Network.OPTIMISM]: ""
|
|
102
|
+
[Network.OPTIMISM]: "",
|
|
103
|
+
[Network.ARBITRUM]: ""
|
|
86
104
|
};
|
|
87
105
|
|
|
88
106
|
export const multiCallAddress: AddressNetworkMap = {
|
|
89
107
|
[Network.POLYGON]: "0x275617327c958bD06b5D6b871E7f491D76113dd8",
|
|
90
|
-
[Network.OPTIMISM]: ""
|
|
108
|
+
[Network.OPTIMISM]: "",
|
|
109
|
+
[Network.ARBITRUM]: ""
|
|
91
110
|
};
|
|
92
111
|
|
|
93
112
|
export const lyraNetworkMap: LyraNetworkMap = {
|
package/src/entities/pool.ts
CHANGED
|
@@ -59,6 +59,9 @@ import {
|
|
|
59
59
|
getFuturesChangePositionTxData,
|
|
60
60
|
getFuturesChangeMarginTxData
|
|
61
61
|
} from "../services/futures";
|
|
62
|
+
import { getFuturesCancelOrderTxData } from "../services/futures/trade";
|
|
63
|
+
import { getZeroExTradeTxData } from "../services/zeroEx/zeroExTrade";
|
|
64
|
+
import { ApiError } from "../errors";
|
|
62
65
|
|
|
63
66
|
export class Pool {
|
|
64
67
|
public readonly poolLogic: Contract;
|
|
@@ -285,16 +288,35 @@ export class Pool {
|
|
|
285
288
|
): Promise<any> {
|
|
286
289
|
let swapTxData: string;
|
|
287
290
|
switch (dapp) {
|
|
291
|
+
case Dapp.ZEROEX:
|
|
292
|
+
swapTxData = await getZeroExTradeTxData(
|
|
293
|
+
this.network,
|
|
294
|
+
assetFrom,
|
|
295
|
+
assetTo,
|
|
296
|
+
amountIn,
|
|
297
|
+
slippage,
|
|
298
|
+
this.address
|
|
299
|
+
);
|
|
300
|
+
break;
|
|
288
301
|
case Dapp.ONEINCH:
|
|
289
302
|
const chainId = networkChainIdMap[this.network];
|
|
290
303
|
const protocols = await getOneInchProtocols(chainId);
|
|
291
|
-
|
|
304
|
+
if (!process.env.ONEINCH_API_URL)
|
|
305
|
+
throw new Error("ONEINCH_API_URL not configured in .env file");
|
|
306
|
+
const apiUrl = `${
|
|
307
|
+
process.env.ONEINCH_API_URL
|
|
308
|
+
}/${chainId}/swap?fromTokenAddress=${assetFrom}&toTokenAddress=${assetTo}&amount=${amountIn.toString()}&fromAddress=${
|
|
292
309
|
this.address
|
|
293
310
|
}&destReceiver=${
|
|
294
311
|
this.address
|
|
295
312
|
}&slippage=${slippage.toString()}&disableEstimate=true${protocols}`;
|
|
296
|
-
|
|
297
|
-
|
|
313
|
+
try {
|
|
314
|
+
const response = await axios.get(apiUrl);
|
|
315
|
+
swapTxData = response.data.tx.data;
|
|
316
|
+
} catch (e) {
|
|
317
|
+
throw new ApiError("Swap api request of 1inch failed");
|
|
318
|
+
}
|
|
319
|
+
|
|
298
320
|
break;
|
|
299
321
|
case Dapp.BALANCER:
|
|
300
322
|
swapTxData = await this.utils.getBalancerSwapTx(
|
|
@@ -478,7 +500,10 @@ export class Pool {
|
|
|
478
500
|
]);
|
|
479
501
|
break;
|
|
480
502
|
case Dapp.VELODROME:
|
|
481
|
-
stakeTxData = getVelodromeStakeTxData(amount);
|
|
503
|
+
stakeTxData = getVelodromeStakeTxData(amount, false);
|
|
504
|
+
break;
|
|
505
|
+
case Dapp.VELODROMEV2:
|
|
506
|
+
stakeTxData = getVelodromeStakeTxData(amount, true);
|
|
482
507
|
break;
|
|
483
508
|
default:
|
|
484
509
|
throw new Error("dapp not supported");
|
|
@@ -521,7 +546,7 @@ export class Pool {
|
|
|
521
546
|
}
|
|
522
547
|
|
|
523
548
|
/**
|
|
524
|
-
* Unstake liquidity pool tokens from gauge
|
|
549
|
+
* Unstake liquidity pool tokens from Velodrome or Balancer gauge
|
|
525
550
|
* @param {string} gauge Gauge contract address
|
|
526
551
|
* @param {BigNumber | string} amount Amount of liquidity pool tokens
|
|
527
552
|
* @param {any} options Transaction options
|
|
@@ -1046,7 +1071,11 @@ export class Pool {
|
|
|
1046
1071
|
break;
|
|
1047
1072
|
case Dapp.VELODROME:
|
|
1048
1073
|
contractAddress = tokenId;
|
|
1049
|
-
txData = getVelodromeClaimTxData(this, tokenId);
|
|
1074
|
+
txData = getVelodromeClaimTxData(this, tokenId, false);
|
|
1075
|
+
break;
|
|
1076
|
+
case Dapp.VELODROMEV2:
|
|
1077
|
+
contractAddress = tokenId;
|
|
1078
|
+
txData = getVelodromeClaimTxData(this, tokenId, true);
|
|
1050
1079
|
break;
|
|
1051
1080
|
default:
|
|
1052
1081
|
throw new Error("dapp not supported");
|
|
@@ -1157,6 +1186,69 @@ export class Pool {
|
|
|
1157
1186
|
return tx;
|
|
1158
1187
|
}
|
|
1159
1188
|
|
|
1189
|
+
/**
|
|
1190
|
+
* Add liquidity to Velodrome V2 pool
|
|
1191
|
+
* @param {string} assetA First asset
|
|
1192
|
+
* @param {string} assetB Second asset
|
|
1193
|
+
* @param {BigNumber | string} amountA Amount first asset
|
|
1194
|
+
* @param {BigNumber | string} amountB Amount second asset
|
|
1195
|
+
* @param { boolean } isStable Is stable pool
|
|
1196
|
+
* @param {any} options Transaction options
|
|
1197
|
+
* @returns {Promise<any>} Transaction
|
|
1198
|
+
*/
|
|
1199
|
+
async addLiquidityVelodromeV2(
|
|
1200
|
+
assetA: string,
|
|
1201
|
+
assetB: string,
|
|
1202
|
+
amountA: BigNumber | string,
|
|
1203
|
+
amountB: BigNumber | string,
|
|
1204
|
+
isStable: boolean,
|
|
1205
|
+
options: any = null
|
|
1206
|
+
): Promise<any> {
|
|
1207
|
+
const tx = await this.poolLogic.execTransaction(
|
|
1208
|
+
routerAddress[this.network][Dapp.VELODROMEV2],
|
|
1209
|
+
await getVelodromeAddLiquidityTxData(
|
|
1210
|
+
this,
|
|
1211
|
+
assetA,
|
|
1212
|
+
assetB,
|
|
1213
|
+
amountA,
|
|
1214
|
+
amountB,
|
|
1215
|
+
isStable
|
|
1216
|
+
),
|
|
1217
|
+
options
|
|
1218
|
+
);
|
|
1219
|
+
return tx;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
/**
|
|
1223
|
+
* Remove liquidity from Velodrome V2 pool
|
|
1224
|
+
* @param {string} assetA First asset
|
|
1225
|
+
* @param {string} assetB Second asset
|
|
1226
|
+
* @param {BigNumber | string} amount Amount of LP tokens
|
|
1227
|
+
* @param { boolean } isStable Is stable pool
|
|
1228
|
+
* @param {any} options Transaction options
|
|
1229
|
+
* @returns {Promise<any>} Transaction
|
|
1230
|
+
*/
|
|
1231
|
+
async removeLiquidityVelodromeV2(
|
|
1232
|
+
assetA: string,
|
|
1233
|
+
assetB: string,
|
|
1234
|
+
amount: BigNumber | string,
|
|
1235
|
+
isStable: boolean,
|
|
1236
|
+
options: any = null
|
|
1237
|
+
): Promise<any> {
|
|
1238
|
+
const tx = await this.poolLogic.execTransaction(
|
|
1239
|
+
routerAddress[this.network][Dapp.VELODROMEV2],
|
|
1240
|
+
await getVelodromeRemoveLiquidityTxData(
|
|
1241
|
+
this,
|
|
1242
|
+
assetA,
|
|
1243
|
+
assetB,
|
|
1244
|
+
amount,
|
|
1245
|
+
isStable
|
|
1246
|
+
),
|
|
1247
|
+
options
|
|
1248
|
+
);
|
|
1249
|
+
return tx;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1160
1252
|
/**
|
|
1161
1253
|
* Trade options on lyra
|
|
1162
1254
|
* @param {LyraOptionMarket} market Underlying market e.g. eth
|
|
@@ -1251,4 +1343,16 @@ export class Pool {
|
|
|
1251
1343
|
const tx = await this.poolLogic.execTransaction(market, txData, options);
|
|
1252
1344
|
return tx;
|
|
1253
1345
|
}
|
|
1346
|
+
|
|
1347
|
+
/** Cancels an open oder on Synthetix futures market
|
|
1348
|
+
*
|
|
1349
|
+
* @param {string} market Address of futures market
|
|
1350
|
+
* @param {any} options Transaction options
|
|
1351
|
+
* @returns {Promise<any>} Transaction
|
|
1352
|
+
*/
|
|
1353
|
+
async cancelFuturesOrder(market: string, options: any = null): Promise<any> {
|
|
1354
|
+
const txData = await getFuturesCancelOrderTxData(this);
|
|
1355
|
+
const tx = await this.poolLogic.execTransaction(market, txData, options);
|
|
1356
|
+
return tx;
|
|
1357
|
+
}
|
|
1254
1358
|
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// see https://stackoverflow.com/a/41102306
|
|
2
|
+
const CAN_SET_PROTOTYPE = "setPrototypeOf" in Object;
|
|
3
|
+
|
|
4
|
+
export class ApiError extends Error {
|
|
5
|
+
public constructor(message?: string) {
|
|
6
|
+
super(message ?? "Api request failed");
|
|
7
|
+
this.name = this.constructor.name;
|
|
8
|
+
if (CAN_SET_PROTOTYPE) Object.setPrototypeOf(this, new.target.prototype);
|
|
9
|
+
}
|
|
10
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -24,3 +24,9 @@ export async function getFuturesChangePositionTxData(
|
|
|
24
24
|
ethers.utils.formatBytes32String(FUTURES_TRACKING)
|
|
25
25
|
]);
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
export async function getFuturesCancelOrderTxData(pool: Pool): Promise<string> {
|
|
29
|
+
return new ethers.utils.Interface(
|
|
30
|
+
ISynthetixFuturesMarketV2.abi
|
|
31
|
+
).encodeFunctionData("cancelOffchainDelayedOrder", [pool.address]);
|
|
32
|
+
}
|
|
@@ -1,31 +1,44 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { BigNumber, ethers } from "ethers";
|
|
3
|
-
import
|
|
3
|
+
import IVelodromeGaugeV1 from "../../abi/IVelodromeGauge.json";
|
|
4
|
+
import IVelodromeGaugeV2 from "../../abi/IVelodromeGaugeV2.json";
|
|
4
5
|
import { Pool } from "../../entities";
|
|
5
|
-
import { Transaction } from "../../types";
|
|
6
6
|
import { call } from "../../utils/contract";
|
|
7
|
-
const
|
|
7
|
+
const iVelodromeGaugeV1 = new ethers.utils.Interface(IVelodromeGaugeV1.abi);
|
|
8
|
+
const iVelodromeGaugeV2 = new ethers.utils.Interface(IVelodromeGaugeV2.abi);
|
|
8
9
|
|
|
9
|
-
export function getVelodromeStakeTxData(
|
|
10
|
-
|
|
10
|
+
export function getVelodromeStakeTxData(
|
|
11
|
+
amount: BigNumber | string,
|
|
12
|
+
v2: boolean
|
|
13
|
+
): any {
|
|
14
|
+
const depositParams: [string, unknown[]] = v2
|
|
15
|
+
? ["deposit(uint256)", [amount]]
|
|
16
|
+
: ["deposit", [amount, 0]];
|
|
17
|
+
const iVelodromeGauge = v2 ? iVelodromeGaugeV2 : iVelodromeGaugeV1;
|
|
18
|
+
return iVelodromeGauge.encodeFunctionData(...depositParams);
|
|
11
19
|
}
|
|
12
20
|
|
|
13
21
|
export async function getVelodromeClaimTxData(
|
|
14
22
|
pool: Pool,
|
|
15
|
-
gauge: string
|
|
23
|
+
gauge: string,
|
|
24
|
+
v2: boolean
|
|
16
25
|
): Promise<any> {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
[
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
if (v2) {
|
|
27
|
+
return iVelodromeGaugeV2.encodeFunctionData("getReward", [pool.address]);
|
|
28
|
+
} else {
|
|
29
|
+
const rewardAssetCount = await call(pool.signer, IVelodromeGaugeV1.abi, [
|
|
30
|
+
gauge,
|
|
31
|
+
"rewardsListLength",
|
|
32
|
+
[]
|
|
33
|
+
]);
|
|
34
|
+
const rewardAssets = await Promise.all(
|
|
35
|
+
Array.from(Array(rewardAssetCount.toNumber()).keys()).map(e =>
|
|
36
|
+
call(pool.signer, IVelodromeGaugeV1.abi, [gauge, "rewards", [e]])
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
return iVelodromeGaugeV1.encodeFunctionData("getReward", [
|
|
40
|
+
pool.address,
|
|
41
|
+
rewardAssets
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
31
44
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { BigNumber } from "ethers";
|
|
3
|
+
import { Network } from "../../types";
|
|
4
|
+
import { ApiError } from "../../errors";
|
|
5
|
+
|
|
6
|
+
// slippage of 0x is different from that of 1Inch
|
|
7
|
+
// in 0x, e.g. 0.03 for 3% slippage allowed
|
|
8
|
+
// 1inch slippage 0.5% represented by 0.5
|
|
9
|
+
// 0x slippage 0.5% represented by 0.005
|
|
10
|
+
const getZeroExSlippage = (slippage: number): number => {
|
|
11
|
+
return Number(slippage) / 100;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const getZeroExTradeTxData = async (
|
|
15
|
+
network: Network,
|
|
16
|
+
assetFrom: string,
|
|
17
|
+
assetTo: string,
|
|
18
|
+
amountIn: BigNumber | string,
|
|
19
|
+
slippage = 0.5,
|
|
20
|
+
takerAddress: string
|
|
21
|
+
): Promise<string> => {
|
|
22
|
+
if (!process.env.ZEROEX_API_KEY)
|
|
23
|
+
throw new Error("ZEROEX_API_KEY not configured in .env file");
|
|
24
|
+
try {
|
|
25
|
+
const slippagePercentage = getZeroExSlippage(slippage);
|
|
26
|
+
const params = {
|
|
27
|
+
buyToken: assetTo,
|
|
28
|
+
sellToken: assetFrom,
|
|
29
|
+
sellAmount: amountIn.toString(),
|
|
30
|
+
// necessary to skip quote validation is that in which the takerAddress refers to a smart contract
|
|
31
|
+
skipValidation: true,
|
|
32
|
+
// Used to enable RFQ-T liquidity
|
|
33
|
+
intentOnFilling: true,
|
|
34
|
+
takerAddress,
|
|
35
|
+
slippagePercentage
|
|
36
|
+
// excludedSourcesParam
|
|
37
|
+
};
|
|
38
|
+
const response = await axios.get(
|
|
39
|
+
`https://${network}.api.0x.org/swap/v1/quote`,
|
|
40
|
+
{
|
|
41
|
+
params,
|
|
42
|
+
headers: {
|
|
43
|
+
"0x-api-key": process.env.ZEROEX_API_KEY
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return response.data.data;
|
|
49
|
+
} catch (e) {
|
|
50
|
+
throw new ApiError("Swap api request of 0x failed");
|
|
51
|
+
}
|
|
52
|
+
};
|