@@ -2,11 +2,11 @@ import chalk from "chalk";
22import { connect } from "mongoose" ;
33import { schedule } from "node-cron" ;
44import { config } from "../config" ;
5- import { OneInch } from "./lib/1inch.io " ;
6- import { Quote , Token } from "./types/1inch " ;
5+ import { OneInch } from "./lib" ;
6+ import { Quote , Direction } from "./types" ;
77const chalkTable = require ( 'chalk-table' ) ;
88import BigNumber from "bignumber.js" ;
9- import { flat } from "./utils" ;
9+ import { buildTradeMsg , flat } from "./utils" ;
1010import { MONITORED_TOKENS } from "./data/token" ;
1111
1212const Main = async ( ) => {
@@ -37,7 +37,6 @@ const Main = async () => {
3737const options = {
3838useNewUrlParser :true ,
3939useUnifiedTopology :true ,
40- useCreateIndex :true ,
4140keepAlive :true ,
4241connectTimeoutMS :60000 ,
4342socketTimeoutMS :60000 ,
@@ -47,7 +46,7 @@ const Main = async () => {
4746console . log ( "Connected to MongoDb :)" ) ;
4847} ) . catch ( async ( err ) => {
4948let error = JSON . parse ( JSON . stringify ( err ) )
50- console . log ( 'Mongo Error:' , error ?. name ) ;
49+ console . log ( 'Mongo Error:' , error ) ;
5150} ) ;
5251console . log ( `---` . repeat ( 10 ) ) ;
5352
@@ -60,6 +59,9 @@ const Main = async () => {
6059console . log ( `---` . repeat ( 10 ) ) ;
6160
6261let ethInAmount = new BigNumber ( config . ETH_IN_AMOUNT ) . shiftedBy ( 18 ) . toString ( )
62+ let on_cooldown = false
63+ let message = ''
64+
6365schedule ( `*/${ config . PRICE_CHECK_INTERVAL_IN_SECONDS } * * * * *` , async function ( ) {
6466console . log ( `***` . repeat ( 10 ) ) ;
6567MONITORED_TOKENS . forEach ( async ( token :any ) => {
@@ -110,8 +112,140 @@ const Main = async () => {
110112] ) ;
111113if ( JSON . stringify ( best_buy_protocols ) != JSON . stringify ( best_sell_protocols ) ) {
112114console . log ( table ) ;
115+
116+
117+ if ( profit_pct >= config . PROFIT_THRESHOLD . BUY && ! on_cooldown ) {
118+ let nonce :number = await oneInch . getNonce ( )
119+ console . log ( `Nonce:` , nonce ) ;
120+
121+ on_cooldown = true
122+ /**
123+ * Start of Buy => Approve? => Sell Txs
124+ */
125+ try {
126+
127+ console . log ( `Initiating a buy for token${ token . ticker } ...` ) ;
128+ // build buy Tx
129+ let txData = await oneInch . buildTx ( {
130+ srcToken :'0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' ,
131+ toToken :token . address ,
132+ srcAmount :ethInAmount ,
133+ slippage :config . SLIPPAGE
134+ } )
135+ console . log ( `Buy Tx Data:` , txData ) ;
136+
137+ // send a buy Tx
138+ nonce ++ ;
139+ oneInch . sendTx ( {
140+ data :txData . tx ,
141+ nonce
142+ } ) . then ( async ( tx :any ) => {
143+ if ( tx . hash ) {
144+
145+ // build Buy Tg Msg
146+ message = await buildTradeMsg ( { data :tx , profit_pct :profit_pct , side :Direction . BUY } )
147+ // send Msg to Tg
148+ sendMessage ( users , message ) ;
149+
150+ try {
151+ /**
152+ * Approve Token if it has not been approved before and save it to db
153+ */
154+ // approve if token has not been approved
155+ const token_is_approved = await Approve . exists ( { token :token , by :process . env . PUBLIC_KEY ! . toLowerCase ( ) } )
156+ if ( ! token_is_approved ) {
157+ // approve if not approved
158+ message = `Approving${ token . description } ...`
159+ sendMessage ( users , message )
160+ let txData = await oneInch . approve ( token . address )
161+ nonce ++ ;
162+ await oneInch . sendTx ( {
163+ data :txData . tx ,
164+ nonce
165+ } ) . then ( ( tx :any ) => {
166+ console . log ( `${ token . ticker } has been approved successfully.` )
167+ sendMessage ( users , message )
168+ } ) . catch ( ( err ) => {
169+ console . log ( `Error: ` , err )
170+ } ) ;
171+ }
172+
173+
174+ /**
175+ * Get the balance of the bought token shpuld be atleast be 1/2 of what was expected
176+ */
177+
178+ let tries = 0
179+ let tokenBalance = '0'
180+ while ( tries < 2000 ) {
181+ tokenBalance = await oneInch . balanceOf ( tx . toToken . address )
182+ if ( parseInt ( tokenBalance ) > parseInt ( new BigNumber ( token_amount ) . multipliedBy ( 0.5 ) . toString ( ) ) ) {
183+ break
184+ }
185+ tries ++
186+ }
187+ /**
188+ * End of Balance Check
189+ */
190+
191+ /**
192+ * Sell the bought tokens/assets to the exchange with the best rates
193+ */
194+ message = `Initiating a sell for token${ token . ticker } ...`
195+ // build Sell Tx
196+ let txData = await oneInch . buildTx ( {
197+ srcToken :token . address ,
198+ toToken :'0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' ,
199+ srcAmount :tokenBalance ,
200+ slippage :config . SLIPPAGE
201+ } )
202+ console . log ( `Sell Tx Data:` , txData ) ;
203+
204+ // send the sell Tx
205+ nonce ++ ;
206+ oneInch . sendTx ( {
207+ data :txData . tx ,
208+ nonce
209+ } ) . then ( async ( tx :any ) => {
210+ if ( tx . hash ) {
211+
212+ // build Sell Tg Msg
213+ message = await buildTradeMsg ( { data :tx , profit_pct :profit_pct , side :Direction . SELL } )
214+ // send Msg to Tg
215+ sendMessage ( users , message ) ;
216+
217+
218+ }
219+ } ) . catch ( ( err ) => {
220+ console . log ( `Error:` , err )
221+ } )
222+
223+ /**
224+ * End of Sell Tx
225+ */
226+
227+ }
228+ catch ( error ) {
229+ console . error ( `Error:` , error )
230+ }
231+ }
232+ }
233+ ) . catch ( ( err ) => {
234+ console . log ( `Error:` , err ) ;
235+ } ) ;
236+
237+
238+ } catch ( error ) {
239+ console . error ( `Error:` , error )
240+ }
241+ /**
242+ * End of Buy => Approve? => Sell Txs
243+ */
244+
245+ }
113246}
114247
248+
115249} catch ( error :any ) {
116250console . error ( 'Error:' , JSON . parse ( JSON . stringify ( error ) ) . code ) ;
117251}