├── .gitignore
├── README.md
├── babel.config.js
├── package.json
├── public
├── css
│ ├── Gilroy-Bold.woff
│ ├── Gilroy-Heavy.woff
│ ├── Gilroy-Light.woff
│ ├── Gilroy-Medium.woff
│ ├── Gilroy-Regular.woff
│ ├── mdb.min.css
│ ├── style.css
│ └── style.css.map
├── favicon.ico
├── img
│ ├── Approve.svg
│ ├── Delete.svg
│ ├── Edit.svg
│ ├── Spender.svg
│ ├── Withdraw.svg
│ ├── bg-bnb.jpg
│ ├── bg-cricle.jpg
│ ├── bnb.svg
│ ├── close.svg
│ ├── coin.svg
│ ├── delete-warning.svg
│ ├── dots.svg
│ ├── error.svg
│ ├── eth.svg
│ ├── exclude.png
│ ├── finish.svg
│ ├── formatic.svg
│ ├── info-card.svg
│ ├── info-circle.svg
│ ├── info.svg
│ ├── install-meta.svg
│ ├── logo.svg
│ ├── observe.svg
│ ├── plus.svg
│ ├── portis.svg
│ ├── question.svg
│ ├── search.svg
│ ├── spinner.svg
│ ├── success.svg
│ ├── unobserve.svg
│ ├── unwatch.svg
│ ├── view.svg
│ ├── wallet-connect.svg
│ ├── warning.svg
│ └── watch.svg
├── index.html
└── js
│ └── mdb.min.js
├── src
├── App.vue
├── components
│ ├── AccountList.vue
│ ├── AlertModal.vue
│ ├── ConfirmModal.vue
│ ├── DepositModal.vue
│ ├── InformationList.vue
│ ├── InputModal.vue
│ ├── Loader.vue
│ ├── Modal.vue
│ ├── NotificationList.vue
│ ├── TpSlModal.vue
│ └── TransactionConfig.vue
├── config.js
├── constants
│ ├── CopyTradingSamples.js
│ ├── abi.js
│ └── events.js
├── helpers
│ ├── ABI.js
│ ├── API.js
│ ├── CopyTrade.js
│ ├── Crypto.js
│ ├── Listener.js
│ ├── Observer.js
│ ├── Parse.js
│ ├── Transaction.js
│ ├── Utils.js
│ └── Web3.js
├── main.js
├── router
│ └── index.js
├── store
│ ├── index.js
│ └── modules
│ │ ├── accounts.js
│ │ ├── contracts.js
│ │ ├── histories.js
│ │ ├── information.js
│ │ ├── positions.js
│ │ ├── targets.js
│ │ ├── transactions.js
│ │ └── watches.js
└── views
│ ├── Contract
│ ├── components
│ │ ├── Details.vue
│ │ ├── HistoryList.vue
│ │ ├── PositionList.vue
│ │ └── WarnModal.vue
│ └── index.vue
│ ├── CopyTrading
│ ├── components
│ │ ├── EditTriggerModal.vue
│ │ ├── ExcludeModal.vue
│ │ └── TargetList.vue
│ └── index.vue
│ ├── Home
│ ├── components
│ │ ├── ActiveList.vue
│ │ └── WatchList.vue
│ └── index.vue
│ ├── Navbar
│ └── index.vue
│ └── Template.vue
└── vue.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
3 | package-lock.json
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **WARNING**: links that are related to community are closed and scammers are dealing with it.
2 |
3 | To run the sniper locally, see this [Wiki](https://github.com/anysniper/Frontend/wiki/Project-Setup)
4 |
5 | # AnySniper DApp
6 |
7 | This repository contains all the code to run AnySniper DApp which had 500 active users. All logic code is in this repository and you can add your custom DEX to src/config.js
8 |
9 | There are currently Uniswap, Pancakeswap, Sushiswap, Degenswap and some DEXs on Crono chains.
10 |
11 | The backend is intended to store user configurations such as contract scanner information, favorite contract addresses, and copy trading targets.
12 |
13 | The backend is using [Parse Server](https://parseplatform.org/)
14 |
15 | You can use a free backend service like Back4App, details about this can be found in [here](https://github.com/anysniper/Frontend/wiki/Project-Setup).
16 |
17 | There is a minor issue with copy trading and will be fixed soon. It basically calculates amountOut / amountIn.
18 |
19 | One or two files have multiple lines of code with almost all the logic for sniping, but you can optimize it and any PRs are welcome.
20 |
21 | I hope this will help the space for developing new projects at Defi and I'm sure this code will be nice to use as a template or boilerplate for new projects.
22 |
23 | ## Project setup
24 | ```
25 | npm install
26 | ```
27 |
28 | Open `src/config.js` and change the Parse urls into your backend's urls.
29 |
30 | You can create a free server on https://back4app.com.
31 |
32 | Create New App and then get the `applicationId` and `javascriptKey` in `App Settings / Security & Keys`
33 |
34 | The final configration would be looking like this
35 |
36 | ```
37 | PARSE_APP_ID: 'R0qwhAQIbNmHctk030RjGGlYD9hSTuytv...',
38 | PARSE_URL: 'https://parseapi.back4app.com',
39 | PARSE_MASTER_KEY: '',
40 | PARSE_JS_KEY: '1MT3Ew8i1yQUX4SIvqbDiaggfszvtZ....',
41 | ```
42 |
43 | You also need to change `MAINNET_RPC` which is used to fetch the token balance. Create a new project at [Infura](https://infura.io/) and get RPC url.
44 |
45 | ### Compiles and hot-reloads for development
46 | ```
47 | npm run serve
48 | ```
49 |
50 | ### Compiles and minifies for production
51 | ```
52 | npm run build
53 | ```
54 |
55 | ### Lints and fixes files
56 | ```
57 | npm run lint
58 | ```
59 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "AnySniper",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "@fortawesome/fontawesome-svg-core": "^1.3.0",
12 | "@fortawesome/free-brands-svg-icons": "^5.15.4",
13 | "@fortawesome/free-regular-svg-icons": "^5.15.4",
14 | "@fortawesome/free-solid-svg-icons": "^5.15.4",
15 | "@fortawesome/vue-fontawesome": "^2.0.6",
16 | "@walletconnect/web3-provider": "^1.7.1",
17 | "axios": "^0.24.0",
18 | "core-js": "^3.6.5",
19 | "crypto-js": "^4.1.1",
20 | "epic-spinners": "^1.1.0",
21 | "ethers": "^5.5.1",
22 | "merkletreejs": "^0.2.24",
23 | "parse": "^3.4.0",
24 | "socket.io-client": "^4.4.0",
25 | "v-calendar": "^2.3.4",
26 | "v-click-outside": "^3.1.2",
27 | "v-emoji-picker": "^2.3.3",
28 | "vue": "^2.6.11",
29 | "vue-json-pretty": "^1.8.2",
30 | "vue-router": "^3.2.0",
31 | "vue-toastification": "^1.7.14",
32 | "vue-tour": "^2.0.0",
33 | "vuesax": "^4.0.1-alpha.25",
34 | "vuex": "^3.6.2",
35 | "web3": "^1.6.0",
36 | "web3modal": "^1.9.4"
37 | },
38 | "devDependencies": {
39 | "@vue/cli-plugin-babel": "~4.5.0",
40 | "@vue/cli-plugin-eslint": "~4.5.0",
41 | "@vue/cli-plugin-router": "^4.5.15",
42 | "@vue/cli-service": "~4.5.0",
43 | "babel-eslint": "^10.1.0",
44 | "eslint": "^6.7.2",
45 | "eslint-plugin-vue": "^6.2.2",
46 | "vue-template-compiler": "^2.6.11"
47 | },
48 | "eslintConfig": {
49 | "root": true,
50 | "env": {
51 | "node": true
52 | },
53 | "extends": [
54 | "plugin:vue/essential",
55 | "eslint:recommended"
56 | ],
57 | "parserOptions": {
58 | "parser": "babel-eslint"
59 | },
60 | "rules": {}
61 | },
62 | "browserslist": [
63 | "> 1%",
64 | "last 2 versions",
65 | "not dead"
66 | ]
67 | }
68 |
--------------------------------------------------------------------------------
/public/css/Gilroy-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/css/Gilroy-Bold.woff
--------------------------------------------------------------------------------
/public/css/Gilroy-Heavy.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/css/Gilroy-Heavy.woff
--------------------------------------------------------------------------------
/public/css/Gilroy-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/css/Gilroy-Light.woff
--------------------------------------------------------------------------------
/public/css/Gilroy-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/css/Gilroy-Medium.woff
--------------------------------------------------------------------------------
/public/css/Gilroy-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/css/Gilroy-Regular.woff
--------------------------------------------------------------------------------
/public/css/style.css.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "mappings": "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",
4 | "sources": ["style.scss"],
5 | "names": [],
6 | "file": "style.css"
7 | }
8 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/favicon.ico
--------------------------------------------------------------------------------
/public/img/Approve.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
11 |
13 |
15 |
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 |
--------------------------------------------------------------------------------
/public/img/Delete.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/Edit.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/Spender.svg:
--------------------------------------------------------------------------------
1 | n
--------------------------------------------------------------------------------
/public/img/Withdraw.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/public/img/bg-bnb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/img/bg-bnb.jpg
--------------------------------------------------------------------------------
/public/img/bg-cricle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/img/bg-cricle.jpg
--------------------------------------------------------------------------------
/public/img/bnb.svg:
--------------------------------------------------------------------------------
1 | binance-coin-bnb
--------------------------------------------------------------------------------
/public/img/close.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/delete-warning.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/public/img/dots.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/error.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/img/exclude.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anysniper/Frontend/31453e68bb459e0bce381b02f0cd629ff7cb47c0/public/img/exclude.png
--------------------------------------------------------------------------------
/public/img/finish.svg:
--------------------------------------------------------------------------------
1 | finish
--------------------------------------------------------------------------------
/public/img/formatic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/public/img/info-card.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/info-circle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/info.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/public/img/install-meta.svg:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/public/img/observe.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/img/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/img/question.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
10 |
11 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/public/img/search.svg:
--------------------------------------------------------------------------------
1 | b
--------------------------------------------------------------------------------
/public/img/spinner.svg:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/public/img/success.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/public/img/unobserve.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/img/unwatch.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
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 |
--------------------------------------------------------------------------------
/public/img/view.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/public/img/warning.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/public/img/watch.svg:
--------------------------------------------------------------------------------
1 | v
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 | Sniper
17 |
18 |
19 |
20 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
Settings
10 |
16 |
17 |
23 |
24 |
25 |
26 |
27 | Loading...
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Please be aware that for the zero / low tax tokens, in order to prevent sandwitch bots frontrunning your transaction, use Original Router with lower slippage unless you use the Buy instant feature.
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
48 |
49 |
50 |
51 |
52 | Please connect your wallet to use the platform V1.6.27.2022. If you are unsure about connecting a wallet, checkout this
article
53 |
54 |
55 | AnySniper Dapp requires you to sign `anysniper_dapp` and don't accept any request to sign this string on any other website.
56 |
57 |
58 |
59 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | Loading...
73 |
74 |
82 |
83 |
84 |
85 |
94 |
95 |
96 |
97 |
220 |
221 |
222 |
295 |
--------------------------------------------------------------------------------
/src/components/AlertModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
16 |
17 |
{{title}}
18 |
{{content}}
19 |
20 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
86 |
87 |
--------------------------------------------------------------------------------
/src/components/ConfirmModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
16 |
17 |
{{title}}
18 |
{{content}}
19 |
20 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
96 |
97 |
--------------------------------------------------------------------------------
/src/components/DepositModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
Your Current Balance
15 |
{{formatBalance(balance)}}
16 |
17 |
18 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
51 |
52 |
53 |
54 |
55 |
56 |
101 |
102 |
--------------------------------------------------------------------------------
/src/components/InformationList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Information
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
Escrow
18 |
19 |
20 |
W{{getNetwork().currency}} BALANCE
21 |
22 | {{formatBalance(escrowBalance)}}
23 |
24 |
25 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
42 |
45 |
46 |
47 |
48 |
{{getNetwork().currency}} Price : {{ethPrice}}
49 |
GWei : {{gwei}}
50 |
51 |
52 |
53 |
54 |
55 |
64 |
65 |
74 |
75 |
76 |
77 |
212 |
213 |
--------------------------------------------------------------------------------
/src/components/InputModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
{{title}}
15 |
16 |
17 | {{field.label}}
18 |
19 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
93 |
94 |
--------------------------------------------------------------------------------
/src/components/Loader.vue:
--------------------------------------------------------------------------------
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 |
65 |
66 |
--------------------------------------------------------------------------------
/src/components/Modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
18 |
19 |
20 |
21 |
22 |
35 |
36 |
--------------------------------------------------------------------------------
/src/components/NotificationList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Recent Actions
6 |
7 | Total PnL:
8 | {{profit}} {{getNetwork().currency}}
9 |
10 |
11 |
12 |
*Total PnL is currently not accurate as it doesn't calculate the fund refunded for the Max percent limit of the token.
13 |
14 |
15 |
16 | Token
17 | {{getNetwork().currency}}
18 |
19 | Gas
20 | Time
21 |
22 |
23 |
24 |
25 |
26 | {{formatAddress(order.get('token1'))}}
27 | {{getEthAmount(order)}}
28 |
29 | {{getGas(order)}}
30 | {{getTime(order)}}
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
125 |
126 |
--------------------------------------------------------------------------------
/src/components/TpSlModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
Take Profit / Stop Loss
15 |
16 |
17 |
18 |
21 |
22 |
{{entry}} {{getNetwork().currency}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
Take Profit
30 |
31 |
32 |
33 |
34 |
35 | {{getNetwork().currency}}
36 |
37 |
38 |
39 |
40 |
41 |
42 |
When Price reaches more than {{parseFloat(tp).toFixed(2)}} , it will trigger sell. Estimated profit will be {{(parseFloat(tp) - parseFloat(entry)).toFixed(2)}} {{getNetwork().currency}}
43 |
44 |
45 |
46 |
47 |
48 |
Stop Loss
49 |
50 |
51 |
52 |
53 |
54 | {{getNetwork().currency}}
55 |
56 |
57 |
58 |
59 |
60 |
61 |
When Price reaches below than {{parseFloat(sl).toFixed(2)}} , it will trigger sell. Estimated lose will be {{(parseFloat(entry) - parseFloat(sl)).toFixed(2)}} {{getNetwork().currency}}
62 |
63 |
64 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
155 |
156 |
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | import ABI from '@/constants/abi';
2 |
3 | const config = {
4 | API_BASE_URL: 'http://localhost:8001', // API not used
5 |
6 | // TODO: change backend's endpoints
7 | PARSE_APP_ID: 'standalone',
8 | PARSE_URL: 'http://localhost:9000/standalone',
9 | PARSE_LIVE_QUERY_URL: 'ws://localhost:1338',
10 | PARSE_MASTER_KEY: 'master',
11 | PARSE_JS_KEY: '',
12 | // User's default password
13 | PARSE_DEFAULT_PASSWORD: 'password',
14 |
15 | ADMIN: '0x0000',
16 |
17 | CHAIN_ID: 1, // 1: eth mainnet, 4: rinkeby, 1337: localhost, 5777: ganache, 56: BSC
18 | // CHAIN_NAME: 'Ethereum Mainnet',
19 | // RPC_URL: '',
20 |
21 | // Socket configrations
22 | NETWORK: 'main', // bsc-main, rinkeby, main
23 |
24 | SOCKET_DAPP_ID: 'e72e44c7-d688-4e0e-82a1-6ceb410b2992',
25 |
26 | // Threshold
27 | MIN_SNIPER_VALUE: 0,
28 | MIN_SNIPER_VALUE_FOR_COPY_TRADING: 0,
29 | MIN_DETAILS_SNIPER_AMOUNT: 0,
30 |
31 | SNIPER_ADDRESS: '0xb8fb35e3406e597e5f86d4f3c0e3063a6fab71a5',
32 |
33 | MAINNET_RPC: 'https://mainnet.infura.io/v3/',
34 | MAINNET_UNI_ROUTER_ADDRESS: '0x7a250d5630b4cf539739df2c5dacb4c659f2488d',
35 | MAINNET_WETH_ADDRESS: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
36 |
37 | // For V1 Escros contracts (not used)
38 | ETH_ESCROW_ADDRESS: '0x89d7c52b999DE0f2D862eD944203BFA0526AE973', // Main
39 | RINKEBY_ESCROW_ADDRESS: '0x3e4dEaB798b75FB19E3305cf2DDc83032940A24c', // Test
40 | BSC_ESCROW_ADDRESS: '0xf965f1995A6CC011524F8762d811F64f1045777E', // BSC
41 |
42 | // For V1 Router contracts (not used)
43 | ETH_ROUTER_ADDRESS: '0xf05dab17B820063Ca143303641adD237C3cA9d32',
44 | RINKEBY_ROUTER_ADDRESS: '0xAAa83841d5a6Ea44E90Cd534d2e470005e4633c3',
45 | BSC_ROUTER_ADDRESS: '0x9d1a0E3492F16Ad58E744071e41483495537e488',
46 |
47 | // For Aggregator
48 | ETH_AGGREGATOR_ADDRESS: '0x0Ff5F706A99BE785B35dF6788ED698290ab56ac0', // Main
49 | RINKEBY_AGGREGATOR_ADDRESS: '0xf2Ca019454C5e0dcdcBD8e3539CcfCF00850e148', // Test
50 | BSC_AGGREGATOR_ADDRESS: '0x328c0Ac24544fbF031080E470A7037d66F57013b', // BSC
51 | CRO_AGGREGATOR_ADDRESS: '', // CRO
52 |
53 | // V2 Router
54 | ETH_ROUTER_V2_ADDRESS: '0xd82E803289b22DAa6EAE106764AF92C88de7bc78',
55 | RINKEBY_ROUTER_V2_ADDRESS: '0x39a70EDaC9413F4A71ea9c682b2c62095b165A7b',
56 | BSC_ROUTER_V2_ADDRESS: '0xa7c94265eeC99B43C17BAC5Cd04d24641F73c934',
57 | CRO_ROUTER_V2_ADDRESS: '',
58 |
59 | ETH_WETH_ADDRESS: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
60 | RINKEBY_WETH_ADDRESS: '0xc778417e063141139fce010982780140aa0cd5ab',
61 | BSC_WETH_ADDRESS: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
62 | CRO_WETH_ADDRESS: '0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23',
63 |
64 | ETH_DEX_LIST: [
65 | {
66 | title: 'UniSwapV2',
67 | address: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f', // factory
68 | router: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
69 | abi: ABI.UniswapRouterABI
70 | },
71 | {
72 | title: 'UniSwapV3',
73 | address: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f',
74 | router: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
75 | isCopyTrading: true,
76 | },
77 | {
78 | title: 'SushiSwap',
79 | address: '0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac',
80 | router: '0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f',
81 | abi: ABI.UniswapRouterABI
82 | },
83 | {
84 | title: 'DegenSwap',
85 | address: '0x5c515455efb90308689579993c11a84fc41229c0',
86 | router: '0x4bf3E2287D4CeD7796bFaB364C0401DFcE4a4f7F',
87 | isDirect: true, // indicates if can't buy through our router
88 | abi: ABI.UniswapRouterABI
89 | }
90 | ],
91 | CRO_DEX_LIST: [
92 | {
93 | title: 'MMF Swap',
94 | address: '0xd590cc180601aecd6eeadd9b7f2b7611519544f4',
95 | router: '0x145677fc4d9b8f19b5d56d1820c48e0443049a30',
96 | isDirect: true // indicates if can't buy through our router
97 | }
98 | ],
99 | RINKEBY_DEX_LIST: [
100 | {
101 | title: 'Uniswap',
102 | address: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f',
103 | router: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
104 | abi: ABI.UniswapRouterABI
105 | },
106 | {
107 | title: 'UniSwapV3',
108 | address: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f',
109 | router: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
110 | isCopyTrading: true,
111 | },
112 | ],
113 | BSC_DEX_LIST: [
114 | {
115 | title: 'PancakeSwap',
116 | address: '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73',
117 | router: '0x10ED43C718714eb63d5aA57B78B54704E256024E'
118 | }
119 | ],
120 |
121 | IS_TEST: false,
122 |
123 | load() {
124 | try {
125 | const localConfig = JSON.parse(localStorage.getItem(`backend_configs`));
126 | this.PARSE_APP_ID = localConfig.APP_ID;
127 | this.PARSE_URL = localConfig.URL;
128 | this.PARSE_MASTER_KEY = localConfig.MASTER_KEY;
129 | this.PARSE_JS_KEY = localConfig.JS_KEY;
130 | // eslint-disable-next-line no-empty
131 | } catch (e) {}
132 | },
133 |
134 | save() {
135 | try {
136 | const config = {
137 | APP_ID: this.PARSE_APP_ID,
138 | URL: this.PARSE_URL,
139 | MASTER_KEY: this.PARSE_MASTER_KEY,
140 | JS_KEY: this.PARSE_JS_KEY
141 | }
142 | localStorage.setItem('backend_configs', JSON.stringify(config));
143 | // eslint-disable-next-line no-empty
144 | } catch (e) {}
145 | }
146 | }
147 |
148 | config.load();
149 |
150 | export default config;
--------------------------------------------------------------------------------
/src/constants/events.js:
--------------------------------------------------------------------------------
1 | export const E_ACCOUNT_CHANGED = 'e_account_changed';
2 | export const E_CHAIN_CHANGED = 'e_chain_changed';
3 |
4 | export const E_LOGIN = 'e_login';
5 |
6 | export const C_NEW_TX = 'c_new_tx';
7 |
8 | export const C_TEST_FAILED = 'c_test_failed';
9 | export const C_TEST_FINISHED = 'c_test_finished';
10 | export const C_TEST_SUCCESS = 'c_test_success';
11 |
12 | export const E_REJECT_SIGN = 'e_reject_sign';
13 |
14 | export const E_NEW_BLOCK = 'e_new_block';
15 |
16 | export const E_NEW_ORDER = 'e_new_order';
--------------------------------------------------------------------------------
/src/helpers/ABI.js:
--------------------------------------------------------------------------------
1 | import Web3 from './Web3';
2 |
3 | class ABI {
4 | constructor() {
5 | }
6 |
7 | getAbi(address) {
8 | for (let dex of Web3.getDexList()) {
9 | if (dex.address.toLowerCase() == address.toLowerCase()) {
10 | if (dex.abi) {
11 | return dex.abi;
12 | }
13 | }
14 | }
15 | return null;
16 | }
17 | }
18 |
19 | const helper = new ABI();
20 | export default helper;
--------------------------------------------------------------------------------
/src/helpers/API.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import config from '../config';
3 |
4 | class APIHelper {
5 |
6 | constructor() {
7 | }
8 |
9 | config() {
10 | return this.call('GET', 'config');
11 | }
12 |
13 | cancel(accounts) {
14 | return this.call('POST', 'cancel', {
15 | accounts
16 | });
17 | }
18 |
19 | // accounts: array of publick key to be used
20 | // if history is null, then use normal gas
21 | // if gasGwei is 0, then use normal gas
22 | // max supply is max wallet percent of total supply
23 | buy(accounts, history, contract, gasGwei, gasMultiplier, amount, maxSupply) {
24 | return this.call('POST', 'buy', {
25 | accounts,
26 | history,
27 | contract,
28 | gasGwei,
29 | gasMultiplier,
30 | amount,
31 | maxSupply
32 | });
33 | }
34 |
35 | // accounts: array of publick key to be used
36 | // if history is null, then use normal gas
37 | // if gasGwei is 0, then use normal gas
38 | // max supply is max wallet percent of total supply
39 | sell(accounts, history, contract, gasGwei, gasMultiplier, percent) {
40 | return this.call('POST', 'sell', {
41 | accounts,
42 | history,
43 | contract,
44 | gasGwei,
45 | gasMultiplier,
46 | percent
47 | });
48 | }
49 |
50 | call(method, endpoint, params) {
51 | let url = config.API_BASE_URL + '/' + endpoint;
52 |
53 | let args = {};
54 |
55 | if (method == 'POST') {
56 | args = {
57 | method: 'post',
58 | url,
59 | data: params,
60 | headers: { 'Content-Type': 'application/json' }
61 | }
62 | } else {
63 | url += '?' + (new URLSearchParams(params)).toString()
64 | args = {
65 | method: 'get',
66 | url,
67 | headers: { 'Content-Type': 'application/json' }
68 | }
69 | }
70 | return axios(args).then(response => {
71 | return response.data;
72 | });
73 | }
74 | }
75 |
76 | const helper = new APIHelper();
77 | export default helper;
--------------------------------------------------------------------------------
/src/helpers/CopyTrade.js:
--------------------------------------------------------------------------------
1 | import Web3 from 'web3';
2 | class CopyTrade {
3 | constructor() {
4 | this.boughtTokens = [];
5 | this.buyProcessed = [];
6 | this.soldTokens = [];
7 | this.sellProcessed = [];
8 | this.processed = [];
9 | }
10 |
11 | setProcessed(tx, status) {
12 | this.processed.push(tx.toLowerCase() + '-' + status.toLowerCase());
13 | }
14 |
15 | hasProcessed(tx, status) {
16 | return this.processed.includes(tx.toLowerCase() + '-' + status.toLowerCase());
17 | }
18 |
19 | setBought(token) {
20 | this.boughtTokens.push(token.toLowerCase());
21 | }
22 |
23 | hasBought(token) {
24 | return this.boughtTokens.includes(token.toLowerCase());
25 | }
26 |
27 | setSold(token) {
28 | this.soldTokens.push(token.toLowerCase());
29 | }
30 |
31 | hasSold(token) {
32 | return this.soldTokens.includes(token.toLowerCase());
33 | }
34 |
35 | setBuyProcessed(token) {
36 | this.buyProcessed.push(token.toLowerCase());
37 | }
38 |
39 | hasBuyProcessed(token) {
40 | return this.buyProcessed.includes(token.toLowerCase());
41 | }
42 |
43 | setSellProcessed(token) {
44 | this.sellProcessed.push(token.toLowerCase());
45 | }
46 |
47 | hasSellProcessed(token) {
48 | return this.sellProcessed.includes(token.toLowerCase());
49 | }
50 |
51 | pad(num, size) {
52 | // eslint-disable-next-line no-undef
53 | num = BigInt(num).toString(16);
54 | while (num.length < size) num = "0" + num;
55 | return num;
56 | }
57 |
58 | fill(str, size) {
59 | while (str.length < size) str = str + "0";
60 | return str;
61 | }
62 |
63 | getInput({input, selector, args, abi, index}) {
64 | const web3 = new Web3();
65 | const params = [];
66 | let value = 0;
67 |
68 | for (let i = 0; i <= 5; i++) {
69 | for (let key in index) {
70 | if (index[key] === i && key != 'isExact') {
71 | if (i == 0) {
72 | value = args[key];
73 | } else {
74 | params.push(args[key]);
75 | }
76 | break;
77 | }
78 | }
79 | }
80 | const inputParams = web3.eth.abi.encodeParameters(abi, params);
81 | let finalInput = selector + inputParams.substr(2);
82 |
83 | if (index.deadline == -1) {
84 | let newInput = input.substr(0, 10) + this.pad(args['deadline'], 64) + input.substring(74, input.indexOf(selector.substr(2)));
85 | newInput += finalInput.substr(2, input.length - newInput.length);
86 |
87 | finalInput = newInput;
88 | finalInput = this.fill(finalInput, input.length);
89 | }
90 | return {
91 | value,
92 | input: finalInput
93 | };
94 | }
95 | }
96 |
97 | const helper = new CopyTrade();
98 | export default helper;
--------------------------------------------------------------------------------
/src/helpers/Crypto.js:
--------------------------------------------------------------------------------
1 | const CryptoJS = require('crypto-js');
2 |
3 | class Crypto {
4 | encrypt(text, password) {
5 | return CryptoJS.AES.encrypt(text, password).toString();
6 | }
7 |
8 | decrypt(encrypted, password) {
9 | const bytes = CryptoJS.AES.decrypt(encrypted, password);
10 | const originalText = bytes.toString(CryptoJS.enc.Utf8);
11 | return originalText;
12 | }
13 | }
14 |
15 | export default new Crypto();
--------------------------------------------------------------------------------
/src/helpers/Listener.js:
--------------------------------------------------------------------------------
1 | import Config from '../config';
2 | import Observer from "./Observer";
3 | import Parse from './Parse';
4 | import Web3 from './Web3';
5 |
6 | import {C_NEW_TX} from "../constants/events";
7 |
8 | function uuidv4() {
9 | return 'Cn-xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xyn]/g, function(c) {
10 | if (c=='n') {
11 | return Math.random() * 9 | 0;
12 | }
13 | var r = Math.random() * 16 | 1, v = c == 'x' ? r : (r & 0x3 | 0x8);
14 | return v.toString(16);
15 | });
16 | }
17 |
18 | class Socket {
19 | constructor() {
20 | this.webSocket = null;
21 | this.socketClosed = true;
22 | this.firstMessageArrived = false;
23 | this.callback = null;
24 | }
25 |
26 | setCallback(callback) {
27 | this.callback = callback;
28 | }
29 |
30 | init(config, abi) {
31 | if (this.close()) {
32 | // if not closed, then callback handler will call this func again
33 | // return;
34 | }
35 | this.firstMessageArrived = false;
36 | this.webSocket = new WebSocket("wss://api.blocknative.com/v0");
37 | this.socketClosed = false;
38 |
39 | this.webSocket.onmessage = (event) => {
40 | if (!this.firstMessageArrived) {
41 | // Communicating for protocol init
42 | this.firstMessageArrived = true;
43 | let condition = {
44 | "appName": 'Onboard',
45 | "appVersion": '1.34.1',
46 | "blockchain": {
47 | "system": "ethereum",
48 | "network": Web3.getNetwork().network
49 | },
50 | "categoryCode": "configs",
51 | "config": {
52 | // "scope": router,
53 | // "filters": filters,
54 | "watchAddress": true,
55 | ...config
56 | },
57 | "dappId": Config.SOCKET_DAPP_ID,
58 | "eventCode": "put",
59 | "timeStamp": new Date().toISOString(),
60 | "version": '3.5.0',
61 | }
62 | if (abi) {
63 | condition['config']['abi'] = abi;
64 | }
65 | setTimeout(() => {
66 | this.webSocket.send(JSON.stringify(condition));
67 | }, 1000);
68 | return;
69 | }
70 |
71 | let data = JSON.parse(event.data);
72 |
73 | if (!data.event || !data.event.transaction) {
74 | return;
75 | }
76 |
77 | data = data.event;
78 |
79 | // if ( data.transaction.status != 'txStuck' || data.transaction.status != 'stuck') {
80 | // data.transaction.status = 'pending';
81 | // }
82 |
83 | if (
84 | data.transaction.status != 'pending'
85 | && data.transaction.status != 'confirmed'
86 | && data.transaction.status != 'failed'
87 | ) {
88 | return;
89 | }
90 |
91 | this.callback(data);
92 | }
93 |
94 | this.webSocket.onclose = () => {
95 | console.log('The connection has been closed and reconnecting');
96 | this.socketClosed = true;
97 | this.init();
98 | };
99 |
100 | this.webSocket.onerror = () => {
101 | console.log('The connection faced an error and reconnecting');
102 | this.init();
103 | }
104 |
105 | this.webSocket.onopen = () => {
106 | this.webSocket.send(JSON.stringify({
107 | "appName": 'Onboard',
108 | "appVersion": '3.5.0',
109 | "blockchain": {
110 | "system": "ethereum",
111 | "network": Web3.getNetwork().network
112 | },
113 | "categoryCode": "initialize",
114 | "connectionId": uuidv4(),
115 | "dappId": Config.SOCKET_DAPP_ID,
116 | "eventCode": "checkDappId",
117 | "timeStamp": new Date().toISOString(),
118 | "version": '3.5.0',
119 | }));
120 | };
121 | }
122 |
123 | close() {
124 | if (this.webSocket) {
125 | this.webSocket.onclose = () => {};
126 | this.webSocket.close();
127 | this.webSocket = null;
128 | return true;
129 | }
130 | return false;
131 | }
132 | }
133 |
134 | class Listener {
135 | constructor() {
136 | this.contract = null;
137 | this.owner = null;
138 | this.abi = null;
139 | this.isListening = false;
140 | this.sockets = [];
141 | }
142 |
143 | stop() {
144 | if (this.sockets.length > 0) {
145 | for (let socket of this.sockets) {
146 | socket.close();
147 | }
148 | this.sockets = [];
149 | }
150 | this.isListening = false;
151 | }
152 |
153 | async listenTargets(addresses, contracts) {
154 | this.stop();
155 | this.isListening = true;
156 | this.sockets = addresses.map((address) => {
157 | const socket = new Socket();
158 | const config = {
159 | "scope": address,
160 | "filters": [
161 | // {
162 | // "_join": "OR",
163 | // "terms": addresses.map((address) => {
164 | // return {
165 | // 'from': address
166 | // }
167 | // })
168 | // },
169 | {
170 | "_join": "OR",
171 | "terms": contracts.map((contract) => {
172 | return {
173 | 'to': contract
174 | }
175 | })
176 | }
177 | ],
178 | // "watchAddress": true
179 | }
180 | socket.setCallback(async (data) => {
181 | const History = Parse.getClass('History');
182 | const history = new History();
183 | history.set('data', data);
184 | history.set('owner', data.transaction.from);
185 | history.set('status', data.transaction.status);
186 | history.set('hash', data.transaction.hash);
187 | history.set('contract', this.contract);
188 | // await history.save();
189 | Observer.$emit(C_NEW_TX, history)
190 | });
191 | socket.init(config);
192 | return socket;
193 | })
194 | }
195 |
196 | async listen(address, owner) {
197 | this.stop();
198 | this.sockets = [
199 | new Socket()
200 | ];
201 | this.isListening = true;
202 |
203 | // abi can be null
204 | this.contract = address;
205 | this.owner = owner;
206 |
207 | const config = {
208 | "scope": this.owner,
209 | "filters": [
210 | {
211 | "_join": "OR",
212 | "terms": [
213 | {
214 | "from": this.owner
215 | },
216 | {
217 | "to": this.contract
218 | }
219 | ]
220 | }
221 | ],
222 | "watchAddress": true
223 | }
224 | this.sockets[0].setCallback(async (data) => {
225 | const History = Parse.getClass('History');
226 | const history = new History();
227 | history.set('data', data);
228 | history.set('owner', this.owner);
229 | history.set('status', data.transaction.status);
230 | history.set('hash', data.transaction.hash);
231 | history.set('contract', this.contract);
232 | // await history.save();
233 | Observer.$emit(C_NEW_TX, history)
234 | });
235 | this.sockets[0].init(config);
236 | }
237 |
238 | }
239 |
240 | export default new Listener();
--------------------------------------------------------------------------------
/src/helpers/Observer.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | const observer = new Vue();
4 |
5 | export default observer;
--------------------------------------------------------------------------------
/src/helpers/Parse.js:
--------------------------------------------------------------------------------
1 | const parse = require('parse');
2 | import config from '../config';
3 | export class ParseHelper {
4 | constructor() {
5 | this._initilized = false;
6 | }
7 |
8 | get client() {
9 | return parse;
10 | }
11 |
12 | instance() {
13 | return parse;
14 | }
15 |
16 | getClass(className) {
17 | return parse.Object.extend(className);
18 | }
19 |
20 | getUserClass() {
21 | return parse.User;
22 | }
23 |
24 | getAccountQuery() {
25 | return this.getQuery('Account');
26 | }
27 |
28 | getTargetQuery() {
29 | return this.getQuery('Target');
30 | }
31 |
32 | getContractQuery() {
33 | return this.getQuery('Contract');
34 | }
35 |
36 | getHistoryQuery() {
37 | return this.getQuery('History');
38 | }
39 |
40 | getQuery(className) {
41 | return new parse.Query(className);
42 | }
43 |
44 | destroy() {
45 | return Promise.all([
46 | ]);
47 | }
48 |
49 | init(isRefresh) {
50 | if (!this._initilized || isRefresh) {
51 | parse.initialize(config.PARSE_APP_ID, config.PARSE_JS_KEY);
52 | parse.masterKey = config.PARSE_MASTER_KEY;
53 | parse.serverURL = config.PARSE_URL;
54 | }
55 |
56 | this.destroy().then(() => {
57 | this._initilized = true;
58 | })
59 | }
60 |
61 | getLiveQueryClient() {
62 | return new parse.LiveQueryClient({
63 | applicationId: config.PARSE_APP_ID,
64 | serverURL: config.PARSE_LIVE_QUERY_URL,
65 | javascriptKey: config.PARSE_JS_KEY
66 | });
67 | }
68 |
69 | callCloud(func, params) {
70 | return parse.Cloud.run(func, params)
71 | }
72 |
73 | getHistories(contract, skip = 0, limit = 100) {
74 | const query = this.getHistoryQuery();
75 | query.equalTo('contract', contract);
76 | query.descending("createdAt");
77 | query.skip(skip);
78 | query.limit(limit);
79 | return query.find();
80 | }
81 | }
82 |
83 | const instance = new ParseHelper();
84 | // instance.init();
85 | export default instance;
86 |
--------------------------------------------------------------------------------
/src/helpers/Transaction.js:
--------------------------------------------------------------------------------
1 | import Web3 from 'web3';
2 | import Web3Helper from './Web3';
3 | import axios from 'axios';
4 | import ABIHelper from './ABI';
5 | import ABI from '../constants/abi';
6 |
7 | class Transaction {
8 | constructor() {
9 | this.abis = {};
10 | this.isLoading = {};
11 | this.details = {};
12 | }
13 |
14 | async getAbiFromSelector(selector) {
15 | if (this.isLoading[selector]) {
16 | return null;
17 | }
18 | this.isLoading[selector] = true;
19 | return axios.get(
20 | `https://www.4byte.directory/api/v1/signatures/?hex_signature=${selector}`,
21 | {
22 | headers: {
23 | 'Content-Type': 'application/json'
24 | }
25 | }
26 | )
27 | .then(async response => {
28 | const results = response.data.results;
29 | if (results.length > 0) {
30 | const result = results[0];
31 | const text = result.text_signature;
32 | const name = text.split('(')[0];
33 | const args = text.split('(')[1].split(')')[0].split(',');
34 | const abi = {
35 | "inputs": [],
36 | "name": name,
37 | "type": "function"
38 | }
39 | args.map((arg) => {
40 | if (arg != '') {
41 | abi.inputs.push({
42 | "name": arg,
43 | "type": arg
44 | });
45 | }
46 | });
47 | this.abis[selector] = abi;
48 | return abi;
49 | }
50 | return null;
51 | });
52 | }
53 |
54 | getFunctionSelector(abiItem) {
55 | const args = abiItem.inputs.map(input => {
56 | return input.type
57 | }).join(',');
58 | const func = `${abiItem.name}(${args})`;
59 | const web3 = new Web3();
60 | return web3.eth.abi.encodeFunctionSignature(func);
61 | }
62 |
63 | parseFunctionArgs(abiItem, input) {
64 | const web3 = new Web3();
65 | const argInput = input.substring(10);
66 | const argTypes = abiItem.inputs.map(item => item.type);
67 | const argNames = abiItem.inputs.map(item => item.name);
68 | const parameters = web3.eth.abi.decodeParameters(
69 | argTypes,
70 | argInput
71 | );
72 | const result = {};
73 | for (let i = 0; i < argTypes.length; i++) {
74 | result[argNames[i]] = parameters[i];
75 | }
76 | return result;
77 | }
78 |
79 | isWarn(history, accounts, details, warns) {
80 | if (details && details.method && details.method.indexOf('removeLiquidity') != -1) {
81 | return true;
82 | }
83 |
84 | if (details && details.selector && warns && warns.includes(details.selector)) {
85 | return true;
86 | }
87 |
88 | const transaction = history.get('data').transaction;
89 | const input = transaction.input.toLowerCase();
90 | for (let account of accounts) {
91 | if (
92 | input.indexOf(account.get('address').substring(2).toLowerCase()) != -1
93 | && transaction.from.toLowerCase() != account.get('address').toLowerCase()
94 | ) {
95 | return true;
96 | }
97 | }
98 | return false;
99 | }
100 |
101 | getDetails(contract, history, isRaw) {
102 | const data = history.get('data');
103 | const transaction = data.transaction;
104 | const hash = transaction.hash;
105 |
106 | const id = `${hash}`;
107 |
108 | let abi;
109 | if (contract) {
110 | abi = Web3Helper.getAbi(contract.get('address'));
111 | } else {
112 | abi = ABIHelper.getAbi(transaction.to);
113 | }
114 |
115 | let details = {
116 | hash,
117 | status: transaction.status,
118 | value: (parseInt(transaction.value) / (10 ** 18)).toFixed(3)
119 | };
120 |
121 | const txSelector = transaction.input.substring(0, 10);
122 |
123 | if (data.contractCall) {
124 | this.details[id] = {
125 | ...details,
126 | method: data.contractCall.methodName,
127 | selector: txSelector,
128 | params: data.contractCall.params
129 | };
130 | } else {
131 | let method, params;
132 |
133 | if (!isRaw) {
134 | let isFound = false;
135 | if (abi && Array.isArray(abi)) {
136 | for (let item of abi) {
137 | if (item.type == 'function') {
138 | const selector = this.getFunctionSelector(item);
139 | if (txSelector == selector) {
140 | method = item.name;
141 | params = this.parseFunctionArgs(item, transaction.input);
142 | isFound = true;
143 | break;
144 | }
145 | }
146 | }
147 | }
148 | if (!isFound) {
149 |
150 | if (this.abis[txSelector]) {
151 | method = this.abis[txSelector].name;
152 | params = this.parseFunctionArgs(this.abis[txSelector], transaction.input);
153 | } else {
154 | this.getAbiFromSelector(txSelector);
155 | }
156 | }
157 | }
158 | this.details[id] = {
159 | ...details,
160 | input: transaction.input,
161 | method,
162 | selector: txSelector,
163 | params
164 | }
165 | }
166 | return this.details[id];
167 | }
168 |
169 | parseTransaction(transaction) {
170 | let input = transaction.input;
171 | if (input.substring(0, 10) == '0x5ae401dc') {
172 | // this is multicall proxy
173 | input = '0x' + input.substr(330) + '00000000';
174 | }
175 | console.log(input)
176 | const web3 = new Web3();
177 | for (let abi of ABI.TradingABI) {
178 | // console.log(input.substring(0, 10));
179 | if (input.substring(0, 10) == abi.selector) {
180 | const params = web3.eth.abi.decodeParameters(abi.inputs, '0x' + input.substr(10));
181 | return {
182 | params,
183 | abi
184 | };
185 | }
186 | }
187 | return null;
188 | }
189 | }
190 | export default new Transaction();
--------------------------------------------------------------------------------
/src/helpers/Utils.js:
--------------------------------------------------------------------------------
1 | class Utils {
2 | formatAddress(string, size) {
3 | if (!string) {
4 | return string;
5 | }
6 | size = size || 4;
7 | if (string.length < size * 2 + 3) {
8 | return string;
9 | }
10 | return string.substring(0, size) + '...' + string.substr(-size);
11 | }
12 | sleep(seconds) {
13 | return new Promise((resolve) => {
14 | setTimeout(() => {
15 | resolve()
16 | }, seconds * 1000);
17 | });
18 | }
19 | formatBigInt(int) {
20 | // eslint-disable-next-line no-undef
21 | return '0x' + BigInt(int).toString(16);
22 | }
23 | loadScript(script) {
24 | const jQuery = window.jQuery;
25 | return new Promise((resolve) => {
26 | jQuery.getScript(script).done(() => {
27 | resolve();
28 | });
29 | })
30 | }
31 | formatBalance(balance, decimals) {
32 | if (!decimals) {
33 | decimals = 18;
34 | }
35 | // eslint-disable-next-line no-undef
36 | return parseInt(BigInt(balance * 10000) / BigInt(10 ** decimals)) / 10000;
37 | }
38 | copyToClipboard(text) {
39 | /* Copy the text inside the text field */
40 | navigator.clipboard.writeText(text);
41 | }
42 | convertToCSV(objArray) {
43 | var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
44 | var str = '';
45 |
46 | for (var i = 0; i < array.length; i++) {
47 | var line = '';
48 | for (var index in array[i]) {
49 | if (line != '') line += ','
50 |
51 | line += array[i][index];
52 | }
53 |
54 | str += line + '\r\n';
55 | }
56 |
57 | return str;
58 | }
59 | exportCSVFile(headers, items, fileTitle) {
60 | if (headers) {
61 | items.unshift(headers);
62 | }
63 |
64 | // Convert Object to JSON
65 | var jsonObject = JSON.stringify(items);
66 |
67 | var csv = this.convertToCSV(jsonObject);
68 |
69 | var exportedFilenmae = fileTitle + '.csv' || 'export.csv';
70 |
71 | var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
72 | if (navigator.msSaveBlob) { // IE 10+
73 | navigator.msSaveBlob(blob, exportedFilenmae);
74 | } else {
75 | var link = document.createElement("a");
76 | if (link.download !== undefined) { // feature detection
77 | // Browsers that support HTML5 download attribute
78 | var url = URL.createObjectURL(blob);
79 | link.setAttribute("href", url);
80 | link.setAttribute("download", exportedFilenmae);
81 | link.style.visibility = 'hidden';
82 | document.body.appendChild(link);
83 | link.click();
84 | document.body.removeChild(link);
85 | }
86 | }
87 | }
88 | exportJSONFile(data, file) {
89 | var exportedFilenmae = file + '.json' || 'export.json';
90 | var blob = new Blob([data], { type: 'text/json;charset=utf-8;' });
91 | if (navigator.msSaveBlob) { // IE 10+
92 | navigator.msSaveBlob(blob, exportedFilenmae);
93 | } else {
94 | var link = document.createElement("a");
95 | if (link.download !== undefined) { // feature detection
96 | // Browsers that support HTML5 download attribute
97 | var url = URL.createObjectURL(blob);
98 | link.setAttribute("href", url);
99 | link.setAttribute("download", exportedFilenmae);
100 | link.style.visibility = 'hidden';
101 | document.body.appendChild(link);
102 | link.click();
103 | document.body.removeChild(link);
104 | }
105 | }
106 | }
107 | }
108 | export default new Utils();
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import Parse from './helpers/Parse';
5 |
6 | import { library } from '@fortawesome/fontawesome-svg-core'
7 | import { faUserSecret, faTimes, faInfo, faForward, faPause, faPlay, faUser, faSmileBeam, faComments, faCheck, faExclamationTriangle, faCheckCircle, faTimesCircle, faArrowLeft, faArrowRight, faArrowUp, faArrowDown, faChevronLeft, faChevronRight, faChevronDown } from '@fortawesome/free-solid-svg-icons'
8 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
9 |
10 | import vClickOutside from 'v-click-outside'
11 |
12 | import VueTour from 'vue-tour'
13 |
14 | require('vue-tour/dist/vue-tour.css')
15 |
16 | Vue.use(VueTour)
17 |
18 | import Vuesax from 'vuesax'
19 |
20 | import 'vuesax/dist/vuesax.css' //Vuesax styles
21 | Vue.use(Vuesax, {
22 | // options here
23 | })
24 |
25 |
26 | import Toast from "vue-toastification";
27 | // Import the CSS or use your own!
28 | import "vue-toastification/dist/index.css";
29 | Vue.use(Toast);
30 |
31 |
32 |
33 | Vue.use(vClickOutside)
34 | library.add(faUserSecret, faTimes, faInfo, faForward, faPause, faPlay, faUser, faSmileBeam, faComments, faCheck, faExclamationTriangle, faCheckCircle, faTimesCircle, faArrowLeft, faArrowRight, faArrowUp, faArrowDown, faChevronLeft, faChevronRight, faChevronDown);
35 |
36 | Vue.component('font-awesome-icon', FontAwesomeIcon)
37 |
38 | // import Loader from '@/components/Loader';
39 |
40 | // Vue.component('loader', Loader);
41 |
42 | Parse.init();
43 | import store from './store/index';
44 | import 'vue-json-pretty/lib/styles.css';
45 | Vue.config.productionTip = false
46 |
47 | new Vue({
48 | router,
49 | store,
50 | render: h => h(App)
51 | }).$mount('#app')
52 |
53 | document.addEventListener('visibilitychange', () => {
54 | if (document.visibilityState === 'hidden') {
55 | window.localStorage.removeItem('WALLETCONNECT_DEEPLINK_CHOICE');
56 | }
57 | });
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import Home from '@/views/Home/index.vue'
4 | import CopyTrading from '@/views/CopyTrading/index.vue'
5 | import Contract from '@/views/Contract/index.vue';
6 | // import store from '../store';
7 |
8 | Vue.use(VueRouter)
9 |
10 | const routes = [
11 | {
12 | path: '/',
13 | name: 'Home',
14 | component: Home
15 | },
16 | {
17 | path: '/contract/:address?',
18 | name: 'Contract',
19 | component: Contract,
20 | },
21 |
22 | // Copy Trading
23 | {
24 | path: '/copytrading',
25 | name: 'CopyTrading',
26 | component: CopyTrading
27 | },
28 | ]
29 |
30 | const router = new VueRouter({
31 | // mode: 'history',
32 | // base: process.env.BASE_URL,
33 | routes
34 | })
35 |
36 | router.beforeEach((to, from, next) => {
37 | // console.log('ROUTER MIDDLEWARE', store.state.account);
38 | // if (to.name !== 'Home' && !isAuthenticated) next({ name: 'Login' })
39 | // else next()
40 | next();
41 | })
42 |
43 | export default router
44 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | import accounts from './modules/accounts';
5 | import contracts from './modules/contracts';
6 | import positions from './modules/positions';
7 | import histories from './modules/histories';
8 | import watches from './modules/watches';
9 | import information from './modules/information';
10 | import transactions from './modules/transactions';
11 | import targets from './modules/targets';
12 |
13 | import { E_LOGIN } from "@/constants/events";
14 | import Observer from '@/helpers/Observer';
15 |
16 | Vue.use(Vuex)
17 |
18 | const Store = new Vuex.Store({
19 | modules: {
20 | accounts,
21 | contracts,
22 | positions,
23 | histories,
24 | watches,
25 | information,
26 | transactions,
27 | targets
28 | },
29 | state: {
30 | account: null,
31 | balance: 0
32 | },
33 | getters: {
34 | account: (state) => state.account,
35 | balance: (state) => state.balance
36 | },
37 | actions: {
38 | },
39 | mutations: {
40 | SET (state, [key, value]) {
41 | state[key] = value;
42 | }
43 | }
44 | })
45 |
46 | Observer.$on(E_LOGIN, () => {
47 | Store.dispatch('accounts/fetch');
48 |
49 | Store.dispatch('watches/fetch', 'watch');
50 | Store.dispatch('watches/fetch', 'live');
51 | Store.dispatch('watches/fetch', 'past');
52 | })
53 |
54 | export default Store;
--------------------------------------------------------------------------------
/src/store/modules/contracts.js:
--------------------------------------------------------------------------------
1 | import Parse from "@/helpers/Parse";
2 | import Web3 from '@/helpers/Web3';
3 | // import Config from '@/config';
4 |
5 | const state = {
6 | list: [],
7 | active: null
8 | };
9 | const getters = {
10 | list: (state) => state.list,
11 | active: (state) => state.active
12 | };
13 | const actions = {
14 | async fetch({commit}) {
15 | console.log('Getting contracts');
16 | const query = Parse.getContractQuery();
17 | query.equalTo('user', Web3.address);
18 | query.equalTo('network', Web3.getNetwork().network);
19 | query.limit(30);
20 | query.descending("createdAt");
21 | const contracts = await query.find();
22 | commit('SET', ['list', contracts]);
23 | },
24 | async setActive({commit}, contract) {
25 | commit('SET', ['active', contract]);
26 | },
27 | // Get Contract from db or Create if not exists
28 | async get({dispatch}, address) {
29 | const contractQuery = Parse.getContractQuery();
30 | // contractQuery.equalTo('network', Web3.getNetwork().network);
31 | // contractQuery.equalTo('address', address);
32 | contractQuery.matches('address', address, 'i');
33 | contractQuery.ascending("createdAt");
34 | contractQuery.limit(1);
35 | const contracts = await contractQuery.find();
36 |
37 | if (contracts.length > 0) {
38 | if (contracts[0].get('totalSupply')) {
39 | return contracts[0];
40 | }
41 | await contracts[0].destroy();
42 | }
43 | return await dispatch('create', address);
44 | },
45 | // eslint-disable-next-line no-empty-pattern
46 | async create({}, address) {
47 | const details = await Web3.getTokenDetails(address);
48 | const Contract = Parse.getClass('Contract');
49 | const contract = new Contract();
50 | contract.set('owner', details.owner);
51 | contract.set('network', Web3.getNetwork().network);
52 | contract.set('address', address);
53 | contract.set('abi', []);
54 | contract.set('totalSupply', details.totalSupply);
55 | contract.set('decimals', details.decimals);
56 | contract.set('name', details.name);
57 | contract.set('symbol', details.symbol);
58 | await contract.save();
59 | return contract;
60 | },
61 | };
62 | const mutations = {
63 | SET (state, [key, value]) {
64 | state[key] = value;
65 | }
66 | };
67 |
68 | export default {
69 | namespaced: true,
70 | state,
71 | getters,
72 | actions,
73 | mutations
74 | }
75 |
--------------------------------------------------------------------------------
/src/store/modules/histories.js:
--------------------------------------------------------------------------------
1 | import Parse from "@/helpers/Parse";
2 | // import Config from '@/config';
3 | import Web3 from '@/helpers/Web3';
4 |
5 | const state = {
6 | };
7 | const getters = {
8 | };
9 | const actions = {
10 | // eslint-disable-next-line no-empty-pattern
11 | async fetch({}, address) {
12 | const query = Parse.getQuery('History');
13 | query.equalTo('contract', address);
14 | query.equalTo('network', Web3.getNetwork().network);
15 | query.limit(30);
16 | query.descending("createdAt");
17 | const histories = await query.find();
18 | return histories;
19 | }
20 | };
21 | const mutations = {
22 | SET (state, [key, value]) {
23 | state[key] = value;
24 | }
25 | };
26 |
27 | export default {
28 | namespaced: true,
29 | state,
30 | getters,
31 | actions,
32 | mutations
33 | }
34 |
--------------------------------------------------------------------------------
/src/store/modules/information.js:
--------------------------------------------------------------------------------
1 | import Parse from "@/helpers/Parse";
2 | import Web3 from '@/helpers/Web3';
3 |
4 | const state = {
5 | status: [],
6 | orders: {
7 | pageSize: 5,
8 | page: 1,
9 | data: []
10 | },
11 | };
12 | const getters = {
13 | status: (state) => state.status,
14 | orders: (state) => state.orders,
15 | };
16 | const actions = {
17 | async fetchStatus({commit}) {
18 | const statusQuery = Parse.getQuery('Status');
19 | const source = Web3.getLevel().canUseAccount() ? 'account' : 'wallet';
20 | statusQuery.equalTo('network', Web3.getNetwork().network);
21 | statusQuery.equalTo('source', source);
22 | statusQuery.matches('owner', Web3.address, 'i');
23 | const status = await statusQuery.find();
24 | commit('SET', ['status', status]);
25 | },
26 | async fetchOrders({state, commit}) {
27 | const orderQuery = Parse.getQuery('Order');
28 | const source = Web3.getLevel().canUseAccount() ? 'account' : 'wallet';
29 | orderQuery.equalTo('network', Web3.getNetwork().network);
30 | orderQuery.equalTo('source', source);
31 | orderQuery.matches('owner', Web3.address, 'i');
32 | orderQuery.skip(state.orders.pageSize * (state.orders.page - 1))
33 | orderQuery.limit(state.orders.pageSize);
34 | orderQuery.descending("createdAt");
35 |
36 | const orders = await orderQuery.find();
37 | commit('SET', ['orders', {
38 | pageSize: state.orders.pageSize,
39 | page: state.orders.page,
40 | data: orders
41 | }]);
42 | },
43 | };
44 | const mutations = {
45 | SET (state, [key, value]) {
46 | state[key] = value;
47 | }
48 | };
49 |
50 | export default {
51 | namespaced: true,
52 | state,
53 | getters,
54 | actions,
55 | mutations
56 | }
57 |
--------------------------------------------------------------------------------
/src/store/modules/positions.js:
--------------------------------------------------------------------------------
1 | import Parse from "@/helpers/Parse";
2 | import Web3 from '@/helpers/Web3';
3 | // import Config from '@/config';
4 |
5 | const state = {
6 | };
7 | const getters = {
8 | };
9 | const actions = {
10 | // eslint-disable-next-line no-empty-pattern
11 | async fetch({}, contract) {
12 | const query = Parse.getContractQuery();
13 | query.equalTo('user', Web3.address);
14 | query.equalTo('network', Web3.getNetwork().network);
15 | query.equalTo('contract', contract);
16 | query.limit(30);
17 | query.descending("createdAt");
18 | return await query.find();
19 | }
20 | };
21 | const mutations = {
22 | SET (state, [key, value]) {
23 | state[key] = value;
24 | }
25 | };
26 |
27 | export default {
28 | namespaced: true,
29 | state,
30 | getters,
31 | actions,
32 | mutations
33 | }
34 |
--------------------------------------------------------------------------------
/src/store/modules/targets.js:
--------------------------------------------------------------------------------
1 | import Parse from "@/helpers/Parse";
2 | // import Config from '@/config';
3 | import Web3 from '@/helpers/Web3';
4 | // import Observer from '@/helpers/Observer';
5 | // import {E_NEW_ORDER} from "@/constants/events";
6 |
7 | const state = {
8 | list: [],
9 | templates: []
10 | };
11 |
12 | const getters = {
13 | list: (state) => {
14 | return state.list
15 | },
16 | templates: state => state.templates
17 | };
18 | const actions = {
19 | async fetchTemplate({commit}) {
20 | const query = Parse.getQuery('TargetTemplate');
21 | query.ascending("createdAt");
22 | const templates = await query.find();
23 |
24 | commit('SET', ['templates', templates]);
25 | },
26 | async fetch({commit}) {
27 | const query = Parse.getTargetQuery();
28 | query.matches('user', Web3.address, 'i');
29 | query.equalTo('network', Web3.getNetwork().network);
30 | query.limit(30);
31 | query.ascending("createdAt");
32 | const list = await query.find();
33 |
34 | commit('SET', ['list', list]);
35 | },
36 |
37 | async create({commit}, {name, address}) {
38 | const Target = Parse.getClass('Target');
39 | const target = new Target();
40 | target.set('user', Web3.address);
41 | target.set('name', name);
42 | target.set('network', Web3.getNetwork().network);
43 | target.set('address', address);
44 | await target.save();
45 | commit('PUSH', ['list', target]);
46 | },
47 |
48 | // eslint-disable-next-line no-empty-pattern
49 | async edit({}, {target, fields}) {
50 | Object.keys(fields).map(key => {
51 | target.set(key, fields[key]);
52 | })
53 | await target.save();
54 | },
55 |
56 | async delete({commit, state}, target) {
57 | await target.destroy();
58 | commit('SET', ['list', state.list.filter(tar => {
59 | return tar.id != target.id;
60 | })]);
61 | },
62 | };
63 | const mutations = {
64 | SET (state, [key, value]) {
65 | state[key] = value;
66 | },
67 | PUSH (state, [key, value]) {
68 | state[key].push(value);
69 | }
70 | };
71 |
72 | export default {
73 | namespaced: true,
74 | state,
75 | getters,
76 | actions,
77 | mutations
78 | }
79 |
--------------------------------------------------------------------------------
/src/store/modules/transactions.js:
--------------------------------------------------------------------------------
1 | import Utils from "@/helpers/Utils";
2 | import Web3 from '@/helpers/Web3';
3 |
4 | const state = {
5 | config: {
6 | gasGWei: 0,
7 | blocks: 1,
8 | buyGasMultiplier: 1,
9 | buyFastGasMultiplier: 1.5,
10 | buyAmount: 0.1,
11 | maxSupply: 0,
12 | sellPercent: 100,
13 | sellGasMultiplier: 1,
14 | sellFastGasMultiplier: 1.5,
15 | cancelGasMultiplier: 1.5,
16 |
17 | // Buy Params
18 | buyOn: '',
19 | isBuyInstant: true,
20 | isSellOnWarn: true,
21 | factory: 0,
22 | copyRouters: [],
23 |
24 | isOriginalRouter: false,
25 | slippage: 0,
26 | warns: [],
27 |
28 | // Copy Trading Params
29 | isBuySameAmount: false,
30 | isSellSameAmount: true,
31 | isBuyOnce: false,
32 | sellThreshold: 0,
33 |
34 | // Gas Limit
35 | gasLimitETH: 0
36 | }
37 | };
38 | const getters = {
39 | config: (state) => state.config
40 | };
41 | const actions = {
42 | // eslint-disable-next-line no-empty-pattern
43 | async getConfig({state}, {action, type, history}) {
44 | if (!type) {
45 | type = 'normal';
46 | }
47 | // gas: gasLimit, value, gasPrice / (maxFeePerGas, maxPriorityFeePerGas)
48 | let gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit = 1000000;
49 |
50 | if (!history) {
51 | gasPrice = await Web3.getGasPrice();
52 | maxFeePerGas = 0;
53 | maxPriorityFeePerGas = 0;
54 | } else {
55 | const data = history.get('data');
56 | gasPrice = data.transaction.gasPrice;
57 | maxFeePerGas = data.transaction.maxFeePerGas;
58 | maxPriorityFeePerGas = data.transaction.maxPriorityFeePerGas;
59 | if (maxFeePerGas && maxPriorityFeePerGas) {
60 | gasPrice = 0;
61 | } else {
62 | maxFeePerGas = 0;
63 | maxPriorityFeePerGas = 0;
64 | }
65 | }
66 |
67 | if (!maxFeePerGas && !maxPriorityFeePerGas && !gasPrice) {
68 | gasPrice = await Web3.getGasPrice();
69 | }
70 |
71 | let gasGWei = parseFloat(state.config.gasGWei), gasMultiplier;
72 | if (type == 'frontrun') {
73 | gasMultiplier = parseFloat(state.config[action + 'FastGasMultiplier']);
74 | } else if (type == 'backrun' && history) {
75 | gasGWei = 0;
76 | gasMultiplier = 1;
77 | } else {
78 | gasMultiplier = parseFloat(state.config[action + 'GasMultiplier']);
79 | }
80 |
81 | if (gasGWei) {
82 | // eslint-disable-next-line no-undef
83 | gasPrice = BigInt(gasGWei) * BigInt(10 ** 9);
84 | maxFeePerGas = 0;
85 | maxPriorityFeePerGas = 0;
86 | } else if (gasMultiplier != 1) {
87 | if (gasPrice) {
88 | // eslint-disable-next-line no-undef
89 | gasPrice = BigInt(gasPrice) * BigInt(parseInt(gasMultiplier * 100)) / BigInt(100)
90 | } else {
91 | // eslint-disable-next-line no-undef
92 | maxFeePerGas = BigInt(maxFeePerGas) * BigInt(parseInt(gasMultiplier * 100)) / BigInt(100);
93 | // eslint-disable-next-line no-undef
94 | maxPriorityFeePerGas = BigInt(maxPriorityFeePerGas) * BigInt(parseInt(gasMultiplier * 100)) / BigInt(100);
95 | }
96 | }
97 |
98 | const config = {
99 | gas: gasLimit
100 | };
101 |
102 | if (gasPrice) {
103 | config.gasPrice = Utils.formatBigInt(gasPrice);
104 | } else {
105 | config.maxFeePerGas = Utils.formatBigInt(maxFeePerGas);
106 | config.maxPriorityFeePerGas = Utils.formatBigInt(maxPriorityFeePerGas);
107 | }
108 | return config;
109 | },
110 | };
111 | const mutations = {
112 | SET (state, [key, value]) {
113 | state[key] = value;
114 | }
115 | };
116 |
117 | export default {
118 | namespaced: true,
119 | state,
120 | getters,
121 | actions,
122 | mutations
123 | }
124 |
--------------------------------------------------------------------------------
/src/store/modules/watches.js:
--------------------------------------------------------------------------------
1 | import Parse from "@/helpers/Parse";
2 | import Web3 from '@/helpers/Web3';
3 | // import Config from '@/config';
4 |
5 | const state = {
6 | liveList: [],
7 | pastList: [],
8 | watchList: []
9 | };
10 |
11 | const getters = {
12 | liveList: (state) => state.liveList,
13 | pastList: (state) => state.pastList,
14 | watchList: (state) => state.watchList
15 | };
16 | const actions = {
17 | async fetch({commit}, type) {
18 | let key = '';
19 | const query = Parse.getQuery('Watch');
20 | query.equalTo('user', Web3.address);
21 | query.equalTo('network', Web3.getNetwork().network);
22 |
23 | if (type == 'live') {
24 | query.equalTo('isActive', true);
25 | query.equalTo('isFinished', false);
26 | key = 'liveList';
27 | } else if (type == 'past') {
28 | query.equalTo('isActive', true);
29 | query.equalTo('isFinished', true);
30 | key = 'pastList';
31 | } else {
32 | query.equalTo('isActive', false);
33 | key = 'watchList';
34 | }
35 |
36 | query.limit(30);
37 | query.descending("createdAt");
38 | const watches = await query.find();
39 | commit('SET', [key, watches]);
40 | },
41 |
42 | // eslint-disable-next-line no-empty-pattern
43 | async get({}, address) {
44 | const query = Parse.getQuery('Watch');
45 | query.equalTo('network', Web3.getNetwork().network);
46 | query.equalTo('address', address);
47 | query.limit(1);
48 | const watches = await query.find();
49 |
50 | if (watches.length > 0) {
51 | return watches[0];
52 | }
53 | return null;
54 | },
55 |
56 | // eslint-disable-next-line no-empty-pattern
57 | async delete({commit, state}, {address, type}) {
58 | const query = Parse.getQuery('Watch');
59 | query.equalTo('address', address);
60 | query.equalTo('network', Web3.getNetwork().network);
61 | query.equalTo('user', Web3.address);
62 | query.limit(1);
63 | const watches = await query.find();
64 |
65 | if (watches.length > 0) {
66 | await watches[0].destroy();
67 | const key = type + 'List';
68 | commit('SET', [key, state[key].filter(item => {
69 | return item.get('address') != address;
70 | })])
71 | }
72 | return true;
73 | },
74 |
75 | async createUpdate({commit, state}, {address, owner, symbol, name, isActive, isFinished}) {
76 | const query = Parse.getQuery('Watch');
77 | query.equalTo('network', Web3.getNetwork().network);
78 | query.equalTo('address', address);
79 | query.limit(1);
80 | const watches = await query.find();
81 |
82 | let watch = null;
83 | let wasActive = null;
84 | let wasFinished = null;
85 |
86 | if (watches.length > 0) {
87 | watch = watches[0];
88 | wasActive = !!watch.get('isActive');
89 | wasFinished = !!watch.get('isFinished');
90 | } else {
91 | const Watch = Parse.getClass('Watch');
92 | watch = new Watch();
93 | watch.set('network', Web3.getNetwork().network);
94 | }
95 |
96 | if (address) {
97 | watch.set('address', address);
98 | }
99 | if (name) {
100 | watch.set('name', name);
101 | }
102 | if (symbol) {
103 | watch.set('symbol', symbol);
104 | }
105 | if (owner) {
106 | watch.set('owner', owner);
107 | }
108 | watch.set('user', Web3.address);
109 | if (isActive != undefined) {
110 | watch.set('isActive', isActive);
111 | }
112 | if (isFinished != undefined) {
113 | watch.set('isFinished', isFinished);
114 | }
115 | await watch.save();
116 |
117 | if (wasActive === false) {
118 | commit('SET', ['watchList', state.watchList.filter(item => {
119 | return item.id != watch.id;
120 | })])
121 | } else if (wasFinished === false) {
122 | commit('SET', ['liveList', state.liveList.filter(item => {
123 | return item.id != watch.id;
124 | })])
125 | } else {
126 | commit('SET', ['pastList', state.pastList.filter(item => {
127 | return item.id != watch.id;
128 | })])
129 | }
130 |
131 | if (!watch.get('isActive')) {
132 | commit('PUSH', ['watchList', watch]);
133 | } else if (!watch.get('isFinished')) {
134 | commit('PUSH', ['liveList', watch]);
135 | } else {
136 | commit('PUSH', ['pastList', watch]);
137 | }
138 | return watch;
139 | }
140 | };
141 | const mutations = {
142 | SET (state, [key, value]) {
143 | state[key] = value;
144 | },
145 | PUSH (state, [key, value]) {
146 | state[key].push(value);
147 | }
148 | };
149 |
150 | export default {
151 | namespaced: true,
152 | state,
153 | getters,
154 | actions,
155 | mutations
156 | }
157 |
--------------------------------------------------------------------------------
/src/views/Contract/components/HistoryList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
22 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
43 |
44 |
45 |
46 |
162 |
--------------------------------------------------------------------------------
/src/views/Contract/components/PositionList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Positions
6 |
7 |
8 |
9 |
10 |
11 | Name:
12 | {{account.get('name')}}
13 | Balance:
14 | {{getBalance(account)}} / {{getEthValue(account)}} {{getNetwork().currency}}
15 | TP/SL:
16 |
17 | {{getTp(account)}} / {{getSl(account)}}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Balance:
28 | {{getBalance(wallet)}}
29 | {{getNetwork().currency}} Value:
30 | {{getEthValue(wallet)}} {{getNetwork().currency}}
31 | TP/SL:
32 |
33 | {{getTp(wallet)}} / {{getSl(wallet)}}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
52 |
53 |
54 |
55 |
227 |
--------------------------------------------------------------------------------
/src/views/Contract/components/WarnModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 | Loading...
15 |
16 |
17 |
18 | Warning List
19 |
20 |
51 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
141 |
142 |
--------------------------------------------------------------------------------
/src/views/Contract/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Loading contract details
17 |
18 |
19 |
20 |
21 |
22 |
107 |
--------------------------------------------------------------------------------
/src/views/CopyTrading/components/EditTriggerModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
16 |
Trigger functions
17 |
Select at least one of these functions to copy target's trading behavior.
18 |
19 |
37 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
101 |
102 |
--------------------------------------------------------------------------------
/src/views/CopyTrading/components/ExcludeModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 | Loading...
15 |
16 |
17 |
18 | Excluded Tokens List
22 |
23 |
24 |
25 |
26 |
27 | Address
28 | Name
29 |
30 |
31 |
32 |
33 |
34 |
35 | {{formatAddress(token.address)}}
36 | {{token.name}}
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
51 |
52 |
53 |
54 |
63 |
64 |
65 |
66 |
205 |
206 |
--------------------------------------------------------------------------------
/src/views/CopyTrading/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
--------------------------------------------------------------------------------
/src/views/Home/components/ActiveList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Active Contracts
6 |
7 |
8 |
9 |
10 | Live
21 |
22 |
23 | Past
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
47 |
48 |
49 |
50 |
51 | Name
52 | Address
53 | Owner
54 | Symbol
55 |
56 |
57 |
58 |
59 |
60 |
61 | {{watch.get('name')}}
62 | {{formatAddress(watch.get('address'))}}
63 | {{formatAddress(watch.get('owner'))}}
64 | {{watch.get('symbol')}}
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | There is no active contract. Please add one by searching contract address
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
141 |
142 |
--------------------------------------------------------------------------------
/src/views/Home/components/WatchList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Watched Contracts
7 |
8 |
9 |
10 |
11 |
12 |
13 | Name
14 | Address
15 | Owner
16 | Symbol
17 |
18 |
19 |
20 |
21 |
22 | {{watch.get('name')}}
23 | {{formatAddress(watch.get('address'))}}
24 | {{formatAddress(watch.get('owner'))}}
25 | {{watch.get('symbol')}}
26 |
27 |
32 |
33 |
34 |
35 |
36 |
37 | There is no watched contract. Please add one by searching contract address
38 |
39 |
40 |
41 |
42 |
50 |
51 |
60 |
61 |
62 |
63 |
150 |
151 |
--------------------------------------------------------------------------------
/src/views/Home/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
15 |
16 |
17 |
18 |
19 |
74 |
75 |
--------------------------------------------------------------------------------
/src/views/Navbar/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
43 |
44 |
45 |
51 |
52 |
53 |
{{getNetwork().title}}
54 |
{{formatAddress(account.get('address'))}}
55 |
56 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
187 |
188 |
--------------------------------------------------------------------------------
/src/views/Template.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | publicPath: './'
3 | }
--------------------------------------------------------------------------------