forked from a04512/txPoolSniper
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapp.js
More file actions
122 lines (114 loc) · 3.88 KB
/
Copy pathapp.js
File metadata and controls
122 lines (114 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"use strict";
const env = require("./env.json");
Object.assign(process.env, env);
const ethers = require("ethers");
const retry = require("async-retry");
const tokens = require("./tokens.js");
const purchaseAmount = ethers.utils.parseUnits(tokens.purchaseAmount, "ether");
const pcsAbi = new ethers.utils.Interface(require("./abi.json"));
const EXPECTED_PONG_BACK = 30000;
const KEEP_ALIVE_CHECK_INTERVAL = 15000;
const provider = new ethers.providers.WebSocketProvider(
process.env.BSC_NODE_WSS
);
const wallet = ethers.Wallet.fromMnemonic(process.env.MNEMONIC);
const account = wallet.connect(provider);
const router = new ethers.Contract(tokens.router, pcsAbi, account);
const startConnection = () => {
let pingTimeout = null;
let keepAliveInterval = null;
provider._websocket.on("open", () => {
console.log("txPool sniping has begun...\n");
keepAliveInterval = setInterval(() => {
provider._websocket.ping();
// Use `WebSocket#terminate()`, which immediately destroys the connection,
// instead of `WebSocket#close()`, which waits for the close timer.
// Delay should be equal to the interval at which your server
// sends out pings plus a conservative assumption of the latency.
pingTimeout = setTimeout(() => {
provider._websocket.terminate();
}, EXPECTED_PONG_BACK);
}, KEEP_ALIVE_CHECK_INTERVAL);
provider.on("pending", async (txHash) => {
provider.getTransaction(txHash).then(async (tx) => {
if (tx && tx.to) {
if (tx.to === tokens.router) {
const re1 = new RegExp("^0xf305d719");
const re2 = new RegExp("^0x267dd102");
const re3 = new RegExp("^0xe8078d94");
if (re1.test(tx.data) || re2.test(tx.data) || re3.test(tx.data)) {
const decodedInput = pcsAbi.parseTransaction({
data: tx.data,
value: tx.value,
});
if (
ethers.utils.getAddress(tokens.pair[1]) === decodedInput.args[0]
) {
await BuyToken(tx);
}
}
}
}
});
});
});
provider._websocket.on("close", () => {
console.log("WebSocket Closed...Reconnecting...");
clearInterval(keepAliveInterval);
clearTimeout(pingTimeout);
startConnection();
});
provider._websocket.on("error", () => {
console.log("Error. Attemptiing to Reconnect...");
clearInterval(keepAliveInterval);
clearTimeout(pingTimeout);
startConnection();
});
provider._websocket.on("pong", () => {
clearInterval(pingTimeout);
});
};
const BuyToken = async (txLP) => {
const tx = await retry(
async () => {
const amounts = await router.getAmountsOut(purchaseAmount, tokens.pair, {
gasLimit: txLP.gasLimit,
gasPrice: txLP.gasPrice,
});
const amountOutMin = amounts[1].sub(amounts[1].div(tokens.slippage));
let buyConfirmation =
await router.swapExactETHForTokensSupportingFeeOnTransferTokens(
amountOutMin,
tokens.pair,
process.env.RECIPIENT,
Date.now() + 1000 * 60 * 5, //5 minutes
{
value: purchaseAmount,
gasLimit: txLP.gasLimit,
gasPrice: txLP.gasPrice,
}
);
return buyConfirmation;
},
{
retries: 5,
minTimeout: 10000,
maxTimeout: 15000,
onRetry: (err, number) => {
console.log("Buy Failed - Retrying", number);
console.log("Error", err);
if (number === 5) {
console.log("Sniping has failed...");
process.exit();
}
},
}
);
console.log("Waiting for Transaction receipt...");
const receipt = await tx.wait();
console.log("Token Purchase Complete");
console.log("Associated LP Event txHash: " + txLP.hash);
console.log("Your txHash: " + receipt.transactionHash);
process.exit();
};
startConnection();