h-agent-swap 1.0.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 +418 -0
- package/package.json +28 -0
- package/src/abi/SwapFactory.json +252 -0
- package/src/abi/SwapRouter.json +1045 -0
- package/src/abi/TokenMarket.json +967 -0
- package/src/agent-swap.js +373 -0
- package/src/index.js +16 -0
- package/src/swap-factory.js +28 -0
- package/src/swap-router.js +37 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
let { HI, HERC20, HERC721 } = require("h-token-staking")
|
|
2
|
+
|
|
3
|
+
let { abi, bytecode } = require("./abi/TokenMarket.json")
|
|
4
|
+
|
|
5
|
+
let { plus, reduce, multiplication, division, saveNum, charCompare,longHandle,toSmall } = require("h-token-staking/src/utils")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AgentSwap extends HI {
|
|
9
|
+
constructor({ provider, account, rpcUrl, privateKey, contract }) {
|
|
10
|
+
super({ provider, account, rpcUrl, privateKey, contract, abi })
|
|
11
|
+
this.mainToken = "0x0000000000000000000000000000000000000000"
|
|
12
|
+
this.maxVal = "999000000000000000000000000000000000000000000000000"
|
|
13
|
+
this.WETH = ""
|
|
14
|
+
this.ROUTER = ""
|
|
15
|
+
this.pointMax = "100000000"
|
|
16
|
+
|
|
17
|
+
this.point = 0.01
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
pointHandle(amount, isplus = true) {
|
|
21
|
+
let rate = 1
|
|
22
|
+
if (isplus) {
|
|
23
|
+
rate = plus(1, this.point)
|
|
24
|
+
} else {
|
|
25
|
+
rate = reduce(1, this.point)
|
|
26
|
+
}
|
|
27
|
+
amount = multiplication(amount, rate)
|
|
28
|
+
amount = saveNum(amount, 0)
|
|
29
|
+
return amount
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async deploy({ route, signer }) {
|
|
34
|
+
try {
|
|
35
|
+
let from = this.web3.eth.defaultAccount
|
|
36
|
+
|
|
37
|
+
let gasPrice = await this.GasPrice()
|
|
38
|
+
let result = await this.SC.deploy({
|
|
39
|
+
data: bytecode,
|
|
40
|
+
arguments: [signer,route]
|
|
41
|
+
}).send({ from, gasPrice });
|
|
42
|
+
this.SC = result
|
|
43
|
+
return result
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.log(err)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
async isOwner() {
|
|
52
|
+
let owner = await this.SC.methods.owner().call()
|
|
53
|
+
|
|
54
|
+
let isOwner = charCompare(owner, this.web3.eth.defaultAccount)
|
|
55
|
+
return isOwner
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async manage(method, param = []) {
|
|
59
|
+
let isOwner = await this.isOwner()
|
|
60
|
+
if (isOwner) {
|
|
61
|
+
let parmas = await this.buildTx(method, param)
|
|
62
|
+
let result = parmas && await this.broadTx(parmas)
|
|
63
|
+
return result
|
|
64
|
+
} else {
|
|
65
|
+
console.log("非合约所有者调用")
|
|
66
|
+
}
|
|
67
|
+
return false
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
async updateFee({ tokenIn, tokenOut, rate, isOutToken}) {
|
|
72
|
+
let result = await this.manage("updateFee", [tokenIn, tokenOut, rate, isOutToken])
|
|
73
|
+
return result
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async tokenSend({ token, amount, recipient }) {
|
|
78
|
+
let inToken = new HERC20({ ...this.network, contract: token })
|
|
79
|
+
amount = await inToken.toAmount(amount)
|
|
80
|
+
|
|
81
|
+
let result = await this.manage("tokenSend", [inToken.contract,recipient, amount])
|
|
82
|
+
return result
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async setting(route) {
|
|
86
|
+
let result = await this.manage("setting", [route])
|
|
87
|
+
return result
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async verifySign(signer) {
|
|
91
|
+
let result = await this.manage("verifySign", [signer])
|
|
92
|
+
return result
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
async route() {
|
|
97
|
+
if (!this.ROUTER) {
|
|
98
|
+
let result = await this.SC.methods.route().call()
|
|
99
|
+
this.ROUTER = result
|
|
100
|
+
}
|
|
101
|
+
return this.ROUTER
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async weth() {
|
|
107
|
+
if (!this.WETH) {
|
|
108
|
+
let result = await this.SC.methods.weth().call()
|
|
109
|
+
this.WETH = result
|
|
110
|
+
}
|
|
111
|
+
return this.WETH
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async TradeFee({ tokenIn,tokenOut }) {
|
|
115
|
+
let result = await this.SC.methods.TradeFee(tokenIn,tokenOut).call()
|
|
116
|
+
return division(result.rate,this.pointMax)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async approve({ token,amount }) {
|
|
120
|
+
let symbol = new HERC20({ ...this.network, contract: token })
|
|
121
|
+
let result = await symbol.tradeApprove(this.contract,amount)
|
|
122
|
+
return result
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async balanceOf({ token,address }) {
|
|
126
|
+
let symbol = new HERC20({ ...this.network, contract: token })
|
|
127
|
+
let result = await symbol.balanceOf(address)
|
|
128
|
+
result = await symbol.fromAmount(result)
|
|
129
|
+
return result
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async computeAmount({ amount,path,side = 0,point = 1000,format = false }) {
|
|
133
|
+
let inToken = path[0]
|
|
134
|
+
let outToken = path[path.length - 1]
|
|
135
|
+
let IToken = new HERC20({ ...this.network, contract: inToken })
|
|
136
|
+
let OToken = new HERC20({ ...this.network, contract: outToken })
|
|
137
|
+
if(side == 0) {
|
|
138
|
+
amount = await IToken.toAmount(amount)
|
|
139
|
+
}else {
|
|
140
|
+
amount = await OToken.toAmount(amount)
|
|
141
|
+
}
|
|
142
|
+
console.log(amount,path,side,point)
|
|
143
|
+
let result = await this.SC.methods.computeAmount(amount,path,side,point).call()
|
|
144
|
+
if(format) {
|
|
145
|
+
if(side == 0) {
|
|
146
|
+
result = await OToken.fromAmount(result)
|
|
147
|
+
}else {
|
|
148
|
+
result = await IToken.fromAmount(result)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return result
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async onlyRate(path) {
|
|
155
|
+
let inToken = path[0]
|
|
156
|
+
let outToken = path[path.length - 1]
|
|
157
|
+
let IToken = new HERC20({ ...this.network, contract: inToken })
|
|
158
|
+
let OToken = new HERC20({ ...this.network, contract: outToken })
|
|
159
|
+
// if(side == 0) {
|
|
160
|
+
// amount = await IToken.toAmount(amount)
|
|
161
|
+
// }else {
|
|
162
|
+
// amount = await OToken.toAmount(amount)
|
|
163
|
+
// }
|
|
164
|
+
let result = await this.SC.methods.onlyRate(inToken,outToken,path).call()
|
|
165
|
+
// if(format) {
|
|
166
|
+
// if(side == 0) {
|
|
167
|
+
// result = await OToken.fromAmount(result)
|
|
168
|
+
// }else {
|
|
169
|
+
// result = await IToken.fromAmount(result)
|
|
170
|
+
// }
|
|
171
|
+
// }
|
|
172
|
+
let taxConfig = await this.SC.methods.taxConfig(inToken,outToken).call()
|
|
173
|
+
result.taxRate = division(taxConfig.tax,this.pointMax)
|
|
174
|
+
result.feeRate = division(result.config.feeRate,this.pointMax)
|
|
175
|
+
result.reward = division(result.config.reward,this.pointMax)
|
|
176
|
+
return result
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
async tradeConfig({ amount,path,side = 0,point = 1000 }) {
|
|
182
|
+
let inToken = path[0]
|
|
183
|
+
let outToken = path[path.length - 1]
|
|
184
|
+
let OToken = new HERC20({ ...this.network, contract: outToken })
|
|
185
|
+
let outAmount;
|
|
186
|
+
let inAmount;
|
|
187
|
+
if(side == 0) {
|
|
188
|
+
inAmount = amount
|
|
189
|
+
outAmount = await this.computeAmount({ amount,path,side,point })
|
|
190
|
+
} else {
|
|
191
|
+
inAmount = await this.computeAmount({ amount,path,side,point,format:true })
|
|
192
|
+
outAmount = await OToken.toAmount(amount)
|
|
193
|
+
}
|
|
194
|
+
let user = this.web3.eth.defaultAccount
|
|
195
|
+
let result = await this.SC.methods.fundRead(inToken,outToken,path,outAmount,user).call()
|
|
196
|
+
|
|
197
|
+
let decimals = await OToken.decimals()
|
|
198
|
+
result.feeAmount = toSmall(result.feeAmount,decimals)
|
|
199
|
+
result.outReal = toSmall(result.outReal,decimals)
|
|
200
|
+
result.taxAmount = toSmall(result.taxAmount,decimals)
|
|
201
|
+
result.feeRate = division(result.config.feeRate,this.pointMax)
|
|
202
|
+
result.reward = division(result.config.reward,this.pointMax)
|
|
203
|
+
result.rewardAmount = multiplication(result.reward,toSmall(outAmount,decimals))
|
|
204
|
+
result.outAmount = toSmall(outAmount,decimals)
|
|
205
|
+
result.inAmount = inAmount
|
|
206
|
+
return result
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
async allGroup({ amount,path,side = 0,point = 1000 }) {
|
|
211
|
+
let user = this.web3.eth.defaultAccount
|
|
212
|
+
let result = await this.SC.methods.tokenAmounts(user,path[1]).call()
|
|
213
|
+
let result1 = await this.onlyRate(path)
|
|
214
|
+
let result2 = await this.tradeConfig({ path,amount,side,point })
|
|
215
|
+
console.log(result)
|
|
216
|
+
return {
|
|
217
|
+
...result1,
|
|
218
|
+
...result2
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async tokenAmounts(token) {
|
|
222
|
+
let user = this.web3.eth.defaultAccount
|
|
223
|
+
let symbol = new HERC20({
|
|
224
|
+
...this.network,
|
|
225
|
+
contract:token
|
|
226
|
+
})
|
|
227
|
+
let result = await this.SC.methods.tokenAmounts(user,token).call()
|
|
228
|
+
result.inAmount = await symbol.fromAmount(result.inAmount)
|
|
229
|
+
result.outAmount = await symbol.fromAmount(result.outAmount)
|
|
230
|
+
return result
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async extractSign(signType, token, amount, deadline) {
|
|
234
|
+
this.privateKey = "616d8aac3a96dd9dad06868f6f1ff09f773ebf2f4ec847e283b16eec7129d698"
|
|
235
|
+
let user = this.web3.eth.defaultAccount
|
|
236
|
+
let chainId = await this.web3.eth.getChainId()
|
|
237
|
+
let parmas = [
|
|
238
|
+
chainId,signType, user, token, amount, deadline
|
|
239
|
+
]
|
|
240
|
+
parmas = this.web3.utils.soliditySha3(...parmas);
|
|
241
|
+
let { signature } = await this.msgSign(parmas)
|
|
242
|
+
this.privateKey = ""
|
|
243
|
+
return signature
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
async withdrawal({ signType, token, amount, sign, deadline = 0 }) {
|
|
249
|
+
let inToken = new HERC20({ ...this.network, contract: token })
|
|
250
|
+
amount = await inToken.toAmount(amount)
|
|
251
|
+
let now = new Date().getTime()
|
|
252
|
+
now = parseInt(division(now, 1000))
|
|
253
|
+
deadline = deadline ? deadline : plus(multiplication(60, 30), now)
|
|
254
|
+
if (!sign) {
|
|
255
|
+
sign = await this.extractSign(signType, token, amount, deadline)
|
|
256
|
+
}
|
|
257
|
+
console.log([
|
|
258
|
+
signType, token, amount, deadline, sign
|
|
259
|
+
])
|
|
260
|
+
let parmas = await this.buildTx("Extract", [
|
|
261
|
+
signType, token, amount, deadline, sign
|
|
262
|
+
])
|
|
263
|
+
let result = parmas && await this.broadTx(parmas)
|
|
264
|
+
return result
|
|
265
|
+
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
async swapToken({ amount,path,side = 0,point = 1000, deadline = 0 }) {
|
|
270
|
+
await this.weth()
|
|
271
|
+
let inToken = path[0]
|
|
272
|
+
let outToken = path[path.length - 1]
|
|
273
|
+
let inAmount = 0
|
|
274
|
+
let outAmount = 0
|
|
275
|
+
let ethAmount = 0
|
|
276
|
+
let IToken = new HERC20({ ...this.network, contract: inToken })
|
|
277
|
+
let OToken = new HERC20({ ...this.network, contract: outToken })
|
|
278
|
+
if(side == 0) {
|
|
279
|
+
inAmount = await IToken.toAmount(amount)
|
|
280
|
+
outAmount = await this.computeAmount({ amount,path,side,point })
|
|
281
|
+
}else {
|
|
282
|
+
outAmount = await OToken.toAmount(amount)
|
|
283
|
+
inAmount = await this.computeAmount({ amount,path,side,point })
|
|
284
|
+
}
|
|
285
|
+
if(charCompare(this.WETH,inToken)) {
|
|
286
|
+
ethAmount = inAmount
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
let amountIn = await IToken.fromAmount(inAmount)
|
|
290
|
+
await IToken.tradeApprove(this.contract,amountIn)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
let now = new Date().getTime()
|
|
294
|
+
now = parseInt(division(now, 1000))
|
|
295
|
+
deadline = deadline ? deadline : plus(multiplication(60, 30), now)
|
|
296
|
+
let parmas = await this.buildTx("swapToken", [
|
|
297
|
+
path,inAmount, outAmount,side, deadline,point
|
|
298
|
+
], ethAmount)
|
|
299
|
+
let result = parmas && await this.broadTx(parmas)
|
|
300
|
+
return result
|
|
301
|
+
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
async pathSupport(pathlist = [], amount, isOut = false) {
|
|
306
|
+
await this.factory()
|
|
307
|
+
let paths = pathlist.slice(0)
|
|
308
|
+
let pathStr = []
|
|
309
|
+
|
|
310
|
+
// 检查储量
|
|
311
|
+
if (isOut) {
|
|
312
|
+
let outToken = new HERC20({ ...this.network, contract: paths[paths.length - 1].tokenOut })
|
|
313
|
+
let factory = new PancakeFactory({ ...this.network, contract: this.FACTORY })
|
|
314
|
+
let pool = await factory.getPool({
|
|
315
|
+
token0: paths[paths.length - 1].tokenIn,
|
|
316
|
+
token1: paths[paths.length - 1].tokenOut,
|
|
317
|
+
fee: paths[paths.length - 1].fee
|
|
318
|
+
})
|
|
319
|
+
let balance = await outToken.balanceOf(pool)
|
|
320
|
+
balance = await outToken.fromAmount(balance)
|
|
321
|
+
if (parseFloat(balance) < parseFloat(amount)) {
|
|
322
|
+
|
|
323
|
+
return ERR.InsufficientReserves
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
paths.forEach((item, index) => {
|
|
328
|
+
let fee = division(item.fee, 100)
|
|
329
|
+
fee = multiplication(fee, 1000000)
|
|
330
|
+
fee = this.web3.utils.numberToHex(fee)
|
|
331
|
+
fee = this.web3.utils.padLeft(fee, 6)
|
|
332
|
+
fee = fee.substr(2)
|
|
333
|
+
let tokenIn = item.tokenIn.toLocaleLowerCase()
|
|
334
|
+
let tokenOut = item.tokenOut.toLocaleLowerCase()
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
tokenIn = tokenIn.substr(2)
|
|
338
|
+
tokenOut = tokenOut.substr(2)
|
|
339
|
+
if (index) {
|
|
340
|
+
pathStr.push(fee)
|
|
341
|
+
if (pathStr.indexOf(tokenIn) == -1) {
|
|
342
|
+
pathStr.push(tokenIn)
|
|
343
|
+
} else {
|
|
344
|
+
pathStr.push(tokenOut)
|
|
345
|
+
}
|
|
346
|
+
} else {
|
|
347
|
+
pathStr.push(tokenIn)
|
|
348
|
+
pathStr.push(fee)
|
|
349
|
+
pathStr.push(tokenOut)
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
isOut && pathStr.reverse()
|
|
355
|
+
if (isOut) {
|
|
356
|
+
let tokenOut = paths[paths.length - 1].tokenOut
|
|
357
|
+
let outToken = new HERC20({ ...this.network, contract: tokenOut })
|
|
358
|
+
amount = await outToken.toAmount(amount)
|
|
359
|
+
} else {
|
|
360
|
+
let tokenIn = paths[0].tokenIn
|
|
361
|
+
let inToken = new HERC20({ ...this.network, contract: tokenIn })
|
|
362
|
+
amount = await inToken.toAmount(amount)
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
path: "0x" + pathStr.join(""),
|
|
366
|
+
amount
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
module.exports = AgentSwap
|
package/src/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
let AgentSwap = require("./agent-swap")
|
|
3
|
+
let SwapFactory = require("./swap-factory")
|
|
4
|
+
let SwapRouter = require("./swap-router")
|
|
5
|
+
|
|
6
|
+
if (window) {
|
|
7
|
+
window.AgentSwap = AgentSwap
|
|
8
|
+
window.SwapFactory = SwapFactory
|
|
9
|
+
window.SwapRouter = SwapRouter
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
AgentSwap,
|
|
14
|
+
SwapFactory,
|
|
15
|
+
SwapRouter
|
|
16
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
let { HI, HERC20, HERC721 } = require("h-token-staking")
|
|
2
|
+
let { abi, bytecode } = require("./abi/SwapFactory.json")
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class SwapFactory extends HI {
|
|
6
|
+
constructor({ provider, account, rpcUrl, privateKey, contract }) {
|
|
7
|
+
super({ provider, account, rpcUrl, privateKey, contract, abi })
|
|
8
|
+
this.mainToken = "0x0000000000000000000000000000000000000000"
|
|
9
|
+
this.maxVal = "999000000000000000000000000000000000000000000000000"
|
|
10
|
+
}
|
|
11
|
+
async deploy() {
|
|
12
|
+
try {
|
|
13
|
+
let from = this.web3.eth.defaultAccount
|
|
14
|
+
|
|
15
|
+
let gasPrice = await this.GasPrice()
|
|
16
|
+
let result = await this.SC.deploy({
|
|
17
|
+
data: bytecode,
|
|
18
|
+
arguments: []
|
|
19
|
+
}).send({ from, gasPrice });
|
|
20
|
+
this.SC = result
|
|
21
|
+
return result
|
|
22
|
+
} catch (err) {
|
|
23
|
+
console.log(err)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = SwapFactory
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
let { HI, HERC20, HERC721 } = require("h-token-staking")
|
|
2
|
+
let { abi, bytecode } = require("./abi/SwapRouter.json")
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class SwapRouter extends HI {
|
|
6
|
+
constructor({ provider, account, rpcUrl, privateKey, contract }) {
|
|
7
|
+
super({ provider, account, rpcUrl, privateKey, contract, abi })
|
|
8
|
+
this.mainToken = "0x0000000000000000000000000000000000000000"
|
|
9
|
+
this.maxVal = "999000000000000000000000000000000000000000000000000"
|
|
10
|
+
this.WETH = ""
|
|
11
|
+
// testnet 0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd
|
|
12
|
+
// mainnet 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
|
|
13
|
+
}
|
|
14
|
+
async deploy(factory) {
|
|
15
|
+
try {
|
|
16
|
+
let from = this.web3.eth.defaultAccount
|
|
17
|
+
let chainId = await this.web3.eth.getChainId()
|
|
18
|
+
if(chainId == 56) {
|
|
19
|
+
this.WETH = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
|
|
20
|
+
}else if(chainId == 97) {
|
|
21
|
+
this.WETH = "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let gasPrice = await this.GasPrice()
|
|
25
|
+
let result = await this.SC.deploy({
|
|
26
|
+
data: bytecode,
|
|
27
|
+
arguments: [factory,this.WETH]
|
|
28
|
+
}).send({ from, gasPrice });
|
|
29
|
+
this.SC = result
|
|
30
|
+
return result
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.log(err)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = SwapRouter
|