├── .gitignore ├── .gitmodules ├── AgamaApp-windows.md ├── LICENSE ├── README.md ├── assets ├── BitRock Installer Files │ ├── IgaunaApp-Linux.xml │ ├── IgaunaApp-OSX.xml │ └── IgaunaApp-Win.xml ├── deps │ └── confs │ │ ├── .tmpmarker │ │ ├── ANC_peers.txt │ │ ├── BLK_peers.txt │ │ ├── BTCD_peers.txt │ │ ├── BTC_peers.txt │ │ ├── BTM_peers.txt │ │ ├── CARB_peers.txt │ │ ├── DGB_peers.txt │ │ ├── DOGE_peers.txt │ │ ├── EAC_peers.txt │ │ ├── FRK_peers.txt │ │ ├── GAME_peers.txt │ │ ├── KMD_peers.txt │ │ ├── LTC_peers.txt │ │ ├── MZC_peers.txt │ │ ├── REVS_peers.txt │ │ ├── SXC_peers.txt │ │ ├── SYS_peers.txt │ │ ├── TAZ_peers.txt │ │ ├── UNO_peers.txt │ │ ├── VIA_peers.txt │ │ ├── ZEC_peers.txt │ │ ├── ZET_peers.txt │ │ └── iguana.conf ├── icons │ ├── agama_app_icon.icns │ ├── agama_app_icon.ico │ └── agama_icons │ │ ├── 128x128.png │ │ ├── 16x16.png │ │ ├── 24x24.png │ │ ├── 256x256.png │ │ ├── 32x32.png │ │ ├── 48x48.png │ │ ├── 64x64.png │ │ ├── 96x96.png │ │ ├── agama_app_icon.icns │ │ └── agama_app_icon.ico ├── installer_imgs │ ├── Agama_installer_splash_image.png │ ├── Agama_installer_wizard_image.png │ ├── Iguana_installer_splash_image.png │ ├── Iguana_installer_wizard_image.png │ ├── supernet-agama-logo.png │ └── supernet-iguana-logo.png └── js │ ├── iguana.js │ └── startup.js ├── binary_artifacts.sh ├── binary_artifacts_mac.sh ├── buildscripts ├── AgamaApp-linux.xml ├── AgamaApp-osx.xml ├── AgamaApp-windows.xml ├── easydex-build.sh ├── electron-build-linux.sh ├── electron-build-osx.sh └── electron-build-windows.sh ├── check_submodule.sh ├── gui └── startup │ ├── agama-instance-error.html │ ├── app-closing.html │ ├── app-settings.html │ └── index.html ├── main.js ├── make-deb.js ├── make-patch.sh ├── make-rpm.js ├── package.json ├── private ├── mainmenu.js └── setconf.js ├── routes ├── appConfig.js ├── electrumjs │ ├── electrumServers.js │ ├── electrumjs.core.js │ ├── electrumjs.networks.js │ ├── electrumjs.txdecoder-2bytes.js │ ├── electrumjs.txdecoder-pos.js │ └── electrumjs.txdecoder.js ├── md5.js ├── nativeCoind.js ├── ports.js ├── shepherd.js └── shepherd │ ├── addCoinShortcuts.js │ ├── appInfo.js │ ├── auth.js │ ├── binsUtils.js │ ├── coindWalletKeys.js │ ├── coins.js │ ├── coinsList.js │ ├── confMaxconnections.js │ ├── config.js │ ├── daemonControl.js │ ├── dashboardUpdate.js │ ├── debugLog.js │ ├── dex │ ├── coind.js │ ├── coins.json │ ├── electrumServersList.js │ ├── mmControl.js │ └── mmRequest.js │ ├── downloadBins.js │ ├── downloadPatch.js │ ├── downloadUtil.js │ ├── downloadZcparams.js │ ├── elections.js │ ├── electrum │ ├── auth.js │ ├── balance.js │ ├── block.js │ ├── coins.js │ ├── createtx-multi.js │ ├── createtx-split.js │ ├── createtx.js │ ├── estimate.js │ ├── interest.js │ ├── keys.js │ ├── listunspent.js │ ├── merkle.js │ ├── network.js │ └── transactions.js │ ├── explorer │ ├── overview.js │ └── remoteExplorers.js │ ├── init.js │ ├── kickstart.js │ ├── log.js │ ├── paths.js │ ├── pin.js │ ├── quitDaemon.js │ └── rpc.js ├── version ├── version_build └── windeps ├── CopyWinDepsFiles.bat ├── ReadMe.md ├── x64 ├── ucrtbased.dll └── vcruntime140d.dll └── x86 ├── ucrtbased.dll └── vcruntime140d.dll /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # electron cache directory 37 | .electron 38 | 39 | # Optional REPL history 40 | .node_repl_history 41 | 42 | # Ignore node.js modules folder 43 | node_modules 44 | 45 | # Ignore any igauna made directories or files in repo folder 46 | tmp 47 | help 48 | debug.log 49 | genesis 50 | DB 51 | coins 52 | 53 | # Electron-builder related folders 54 | build 55 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "gui/EasyDEX-GUI"] 2 | path = gui/EasyDEX-GUI 3 | url = https://github.com/SuperNETorg/EasyDEX-GUI.git 4 | -------------------------------------------------------------------------------- /AgamaApp-windows.md: -------------------------------------------------------------------------------- 1 | # Agama application build summary is here: 2 | 3 | Platform: windows 4 | 5 | Version: 0.2.0.1a-beta 6 | 7 | Date: Mon Jun 12 11:57:21 CEST 2017 8 | 9 | 10 | Download link: 11 | * [https://f001.backblazeb2.com/file/supernet/files/AgamaApp-0.2.0.1a-beta-windows-installer.zip](https://f001.backblazeb2.com/file/supernet/files/AgamaApp-0.2.0.1a-beta-windows-installer.zip) 12 | * [checksum](https://f001.backblazeb2.com/file/supernet/files/AgamaApp-0.2.0.1a-beta-windows.checksum) 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 - 2018 SuperNET 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository is no longer maintained. Please use http://github.com/komodoplatform/agama instead. 2 | -------------------------------------------------------------------------------- /assets/deps/confs/.tmpmarker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/deps/confs/.tmpmarker -------------------------------------------------------------------------------- /assets/deps/confs/ANC_peers.txt: -------------------------------------------------------------------------------- 1 | 84.73.4.183 2 | 98.115.147.74 3 | 192.241.187.222 4 | 159.203.208.102 5 | 85.25.44.119 6 | 178.32.251.114 7 | 109.155.227.178 8 | 146.0.32.101 9 | 108.61.10.90 10 | 198.27.82.134 11 | 80.74.157.31 12 | 192.241.183.16 13 | 164.132.25.194 14 | 128.199.47.200 15 | 173.255.197.64 16 | 46.101.136.168 17 | 207.192.70.250 18 | 54.201.183.106 19 | 211.149.175.37 20 | 128.199.192.241 21 | 216.146.143.177 22 | 82.164.213.27 23 | 107.170.167.218 24 | 195.154.223.134 25 | -------------------------------------------------------------------------------- /assets/deps/confs/BLK_peers.txt: -------------------------------------------------------------------------------- 1 | 188.112.70.36 2 | 1.34.180.245 3 | 104.131.248.191 4 | 104.174.97.3 5 | 104.204.109.11 6 | 106.68.86.178 7 | 108.174.171.46 8 | 108.219.100.78 9 | 112.198.64.34 10 | -------------------------------------------------------------------------------- /assets/deps/confs/BTCD_peers.txt: -------------------------------------------------------------------------------- 1 | 89.248.160.237 2 | 89.248.160.238 3 | 89.248.160.239 4 | 89.248.160.240 5 | 89.248.160.241 6 | 89.248.160.242 7 | 89.248.160.243 8 | 89.248.160.244 9 | 89.248.160.245 10 | 5.9.102.210 11 | 78.47.196.146 12 | 85.25.217.233:14631 13 | 88.198.53.194:55692 14 | 88.206.186.58:37299 15 | 162.255.117.105:63084 16 | 115.28.42.60:60878 17 | 82.176.15.155:35026 18 | 88.198.15.19:48150 19 | 176.9.13.13:14631 20 | 217.8.62.188:52714 21 | 162.13.4.69:55410 22 | 211.58.177.43:35581 23 | 63.247.147.166:50266 24 | 24.168.17.50:50793 25 | 46.231.137.186:56963 26 | 178.62.185.131:35572 27 | 62.75.145.171:14631 28 | 89.212.19.49:48018 29 | 192.99.233.217:42232 30 | 68.190.213.46:14631 31 | 162.210.92.46:14631 32 | 98.118.105.12:60805 33 | 75.130.163.51:56719 34 | 51.255.38.28:14631 35 | 88.110.117.18:52158 36 | 24.101.114.249:55457 37 | 99.44.222.86:62377 38 | 108.61.166.209:58365 39 | 98.208.113.72:62065 40 | 72.133.226.130:14631 41 | 5.189.144.97:58243 42 | 14.203.46.202:57987 43 | 98.202.147.55:60460 44 | 24.45.172.109:14631 45 | 89.114.38.65:52768 46 | 68.59.64.126:50633 47 | 68.43.220.127:4303 48 | 81.205.30.207:63077 49 | 113.87.28.142:62764 50 | 73.211.90.130:41271 51 | 110.174.129.213:49252 52 | 68.45.147.145:57803 53 | 95.232.175.161:62633 54 | 73.229.133.160:38440 55 | 124.191.14.253:54342 56 | 167.114.249.196:52705 57 | 92.24.168.248:52892 58 | 93.158.216.201:14631 59 | 158.69.27.82:46643 60 | 104.204.109.11:63390 61 | 68.157.88.187:56711 62 | 71.53.152.87:5234 63 | 82.229.201.131:63466 64 | 59.147.42.146:57461 65 | 81.0.91.211:53187 66 | 82.241.71.230:51945 67 | 108.247.198.39:64094 68 | 77.22.227.8:65093 69 | 122.166.169.11:49325 70 | 173.76.182.122:14631 71 | 173.24.82.253:14631 72 | 100.13.54.119:14631 73 | 2.26.181.208:14631 74 | 94.242.213.3:14631 75 | 87.149.45.42:36077 76 | 98.207.117.83:50955 77 | 71.1.8.48:14631 78 | 71.1.8.48:50439 79 | 101.166.241.31:14631 80 | 178.143.154.142:27497 81 | 103.255.7.59:58660 82 | 156.57.132.119:62428 83 | 60.225.171.82:36834 84 | 46.223.149.120:43358 85 | 37.157.215.75:4162 86 | -------------------------------------------------------------------------------- /assets/deps/confs/BTM_peers.txt: -------------------------------------------------------------------------------- 1 | 70.168.53.153:9265 2 | 146.0.32.101:9265 3 | 24.143.47.161:9265 4 | 139.162.128.92:9265 5 | 85.24.169.215:9265 6 | 98.115.147.74:9265 7 | 192.124.224.254:9265 8 | 45.33.65.161:9265 9 | 184.166.27.254:9265 10 | 139.59.160.118:9265 11 | 98.127.109.96:9265 12 | 101.173.200.202:9265 13 | 157.161.128.55:9265 14 | 104.172.24.79:9265 15 | 158.69.216.182:9265 16 | 72.209.139.213:9265 17 | 198.205.118.181:9265 18 | 101.173.197.85:9265 19 | 174.36.9.130:9265 20 | 84.24.208.22:9265 21 | -------------------------------------------------------------------------------- /assets/deps/confs/CARB_peers.txt: -------------------------------------------------------------------------------- 1 | 54.85.71.51 2 | 87.98.182.171 3 | 98.115.147.74 4 | 85.25.146.74 5 | 86.21.79.62 6 | 46.101.43.245 7 | 144.76.64.123 8 | 193.192.37.135 9 | 88.101.128.228 10 | 85.25.201.216 11 | 85.236.188.213 12 | -------------------------------------------------------------------------------- /assets/deps/confs/DGB_peers.txt: -------------------------------------------------------------------------------- 1 | 212.129.1.77 2 | 157.161.128.58 3 | 178.33.228.14 4 | 108.61.10.90 5 | 104.236.32.184 6 | 66.228.56.115 7 | 167.160.36.126 8 | -------------------------------------------------------------------------------- /assets/deps/confs/DOGE_peers.txt: -------------------------------------------------------------------------------- 1 | 144.76.71.141 2 | 63.231.239.212 3 | 76.178.149.124 4 | 50.168.159.133 5 | 85.172.79.190 6 | 109.239.49.207 7 | 23.92.25.116 8 | 104.236.136.96 9 | 83.163.222.19 10 | 47.88.34.118 11 | 85.24.244.205 12 | 104.222.120.12 13 | 109.233.58.55 14 | 1.32.70.66 15 | 125.205.136.247 16 | 52.23.175.47 17 | 188.0.80.142 18 | 189.27.147.140 19 | 211.149.148.151 20 | 179.185.112.222 21 | 81.5.71.115 22 | 62.76.15.208 23 | 204.91.28.100 24 | 84.18.118.27 25 | 198.27.81.24 26 | 52.76.154.206 27 | 52.69.7.50 28 | 52.192.155.175 29 | 82.24.81.133 30 | 5.100.250.140 31 | 114.55.5.204 32 | 31.179.43.191 33 | 194.135.90.38 34 | 198.50.242.34 35 | 176.9.31.178 36 | 85.25.41.70 37 | 123.57.60.66 38 | 5.196.82.175 39 | 148.251.88.245 40 | 163.172.19.96 41 | 192.30.138.66 42 | 72.207.111.81 43 | 98.115.147.74 44 | 174.50.64.101 45 | 159.203.107.139 46 | 50.191.229.7 47 | 220.135.22.146 48 | 120.55.80.212 49 | 157.161.128.62 50 | 96.48.162.59 51 | 73.253.240.20 52 | 149.210.242.48 53 | 71.181.42.73 54 | 178.32.9.103 55 | 107.170.82.106 56 | 210.28.136.11 57 | 82.78.191.165 58 | 96.126.123.143 59 | 23.239.31.246 60 | 176.9.50.227 61 | 101.200.156.61 62 | 31.41.40.25 63 | 94.254.62.188 64 | 107.170.86.160 65 | 203.74.121.63 66 | 121.40.17.150 67 | 79.109.198.106 68 | 192.95.56.199 69 | 172.249.137.148 70 | 24.249.152.169 71 | 95.174.187.112 72 | 146.0.32.101 73 | 67.171.207.32 74 | 76.185.84.244 75 | 108.241.66.106 76 | 31.184.195.115 77 | 176.9.113.75 78 | 178.63.18.3 79 | 73.225.31.99 80 | 139.196.9.71 81 | 173.28.134.245 82 | 192.95.29.153 83 | 182.92.183.58 84 | 173.236.240.49 85 | 142.217.48.137 86 | 192.99.11.57 87 | 198.23.230.253 88 | 85.243.255.154 89 | 87.189.43.165 90 | 54.201.183.106 91 | 84.230.4.177 92 | 220.240.96.156 93 | 111.201.159.247 94 | 78.84.100.95 95 | 71.207.13.6 96 | 84.253.125.186 97 | 180.229.32.149 98 | 121.42.206.214 99 | 213.65.111.18 100 | 65.13.189.227 101 | 98.127.32.237 102 | 65.28.164.248 103 | 71.236.237.133 104 | 24.22.225.211 105 | 86.21.9.55 106 | 144.76.239.66 107 | 85.25.200.102 108 | 92.255.199.98 109 | 67.170.74.103 110 | 98.162.199.30 111 | 145.131.3.54 112 | 81.7.3.24 113 | 77.201.157.202 114 | 104.131.40.196 115 | 70.79.168.92 116 | 71.80.233.61 117 | 78.102.123.56 118 | 120.146.143.87 119 | 174.115.20.94 120 | 24.255.204.177 121 | 69.145.193.96 122 | 80.68.90.161 123 | 24.121.141.96 124 | 176.9.65.41 125 | 173.63.255.25 126 | 69.42.223.118 127 | 91.83.69.247 128 | -------------------------------------------------------------------------------- /assets/deps/confs/FRK_peers.txt: -------------------------------------------------------------------------------- 1 | 193.227.134.111:7912 2 | 85.24.169.215:7912 3 | 195.154.223.134:7912 4 | 175.33.51.90:7912 5 | 91.153.109.149:7912 6 | 84.242.139.4:7912 7 | 73.211.90.130:7912 8 | 123.56.194.66:7912 9 | 157.161.128.55:7912 10 | 91.134.120.210:7912 11 | 80.219.59.25:7912 12 | 173.65.129.85:7912 13 | 198.27.97.180:7912 14 | 178.140.25.85:7912 15 | 104.172.24.79:7912 16 | 198.27.81.114:7912 17 | 104.236.163.203:7912 18 | 98.115.147.74:7912 19 | 155.254.32.17:7912 20 | 198.27.97.172:7912 21 | 108.61.10.90:7912 22 | 104.236.26.26:7912 23 | 144.76.91.109:7912 24 | 158.69.238.230:7912 25 | 86.174.4.251:7912 26 | 151.80.9.33:7912 27 | 198.50.217.13:7912 28 | 193.192.37.135:7912 29 | 80.219.59.42:7912 30 | 68.117.4.111:7912 31 | 109.145.33.45:7912 32 | 74.196.59.103:7912 33 | 84.107.181.197:7912 34 | 80.219.59.98:7912 35 | 104.236.59.76:7912 36 | 81.89.56.170:7912 37 | 157.161.128.58:7912 38 | 158.69.27.82:7912 39 | 209.126.119.209:7912 40 | 104.238.171.32:7912 41 | -------------------------------------------------------------------------------- /assets/deps/confs/GAME_peers.txt: -------------------------------------------------------------------------------- 1 | 46.105.118.15 2 | 89.36.212.56 3 | 85.214.23.49 4 | 194.135.81.138 5 | 111.99.55.252 6 | 104.172.24.79 7 | 104.236.84.230 8 | 104.255.67.131 9 | -------------------------------------------------------------------------------- /assets/deps/confs/KMD_peers.txt: -------------------------------------------------------------------------------- 1 | 148.251.57.148 2 | 149.56.28.84 3 | 176.9.26.39 4 | 94.102.63.199 5 | 5.9.102.210 6 | 88.198.65.74 7 | 94.102.63.200 8 | 78.47.196.146 9 | 104.255.64.3 10 | 221.121.144.140 11 | 103.18.58.150 12 | 103.18.58.146 13 | 213.202.253.10 14 | 185.106.121.32 15 | 27.100.36.201 16 | -------------------------------------------------------------------------------- /assets/deps/confs/LTC_peers.txt: -------------------------------------------------------------------------------- 1 | 37.97.159.116 2 | 5.9.67.48 3 | 86.107.207.194 4 | 46.28.206.204 5 | 91.232.188.3 6 | 209.180.247.49 7 | 61.150.109.231 8 | 24.217.216.92 9 | 219.117.248.55 10 | 131.161.120.110 11 | 122.224.51.104 12 | 78.25.32.206 13 | 46.63.26.63 14 | 200.79.231.62 15 | -------------------------------------------------------------------------------- /assets/deps/confs/MZC_peers.txt: -------------------------------------------------------------------------------- 1 | 188.226.195.226 2 | 72.49.184.206 3 | 84.22.108.241 4 | 75.128.211.140 5 | 176.31.53.252 6 | 212.5.143.185 7 | 205.197.252.41 8 | 195.154.223.134 9 | 142.4.218.174 10 | 72.46.152.250 11 | 45.63.65.112 12 | 104.236.167.70 13 | 142.4.218.175 14 | 108.61.164.199 15 | 107.170.173.232 16 | 98.117.92.108 17 | 192.95.29.153 18 | 97.88.116.115 19 | 24.206.113.66 20 | 173.239.208.6 21 | 24.107.101.162 22 | 88.198.49.154 23 | 193.107.94.202 24 | 86.26.119.177 25 | 198.27.97.172 26 | 73.240.243.108 27 | 98.127.109.96 28 | 27.109.250.186 29 | 79.64.13.216 30 | 81.102.95.39 31 | 92.14.74.221 32 | 68.42.79.115 33 | 85.169.119.123 34 | 24.107.102.70 35 | 151.80.206.101 36 | 107.170.167.218 37 | 151.80.9.33 38 | 82.46.79.119 39 | 63.247.147.166 40 | 95.145.252.94 41 | 113.52.87.159 42 | 192.99.35.133 43 | 12.35.68.211 44 | 46.105.158.205 45 | 72.84.241.101 46 | 37.59.18.108 47 | 104.172.24.79 48 | 174.107.118.81 49 | 76.106.178.145 50 | 75.128.193.117 51 | 158.69.27.82 52 | 45.32.233.30 53 | 84.22.106.192 54 | 74.132.6.75 55 | 45.55.153.77 56 | 89.156.223.223 57 | 94.23.32.109 58 | 180.94.191.62 59 | 45.55.220.222 60 | 73.192.202.185 61 | 186.90.15.65 62 | 108.224.49.4 63 | 84.237.85.210 64 | 76.19.242.156 65 | 73.157.167.155 66 | 68.117.4.111 67 | 98.18.22.32 68 | 69.59.214.109 69 | 198.84.218.9 70 | 98.115.147.74 71 | 71.7.124.80 72 | 65.15.37.140 73 | 217.44.16.102 74 | 73.240.162.49 75 | 23.80.94.149 76 | 151.80.206.110 77 | 50.254.73.158 78 | 92.14.75.139 79 | 188.124.91.76 80 | 66.189.11.251 81 | 184.17.228.71 82 | -------------------------------------------------------------------------------- /assets/deps/confs/REVS_peers.txt: -------------------------------------------------------------------------------- 1 | 148.251.57.148 2 | 149.56.28.84 3 | 176.9.26.39 4 | 94.102.63.199 5 | 5.9.102.210 6 | 88.198.65.74 7 | 94.102.63.200 8 | 78.47.196.146 9 | 104.255.64.3 10 | 221.121.144.140 11 | 103.18.58.150 12 | 103.18.58.146 13 | 213.202.253.10 14 | 185.106.121.32 15 | 27.100.36.201 16 | -------------------------------------------------------------------------------- /assets/deps/confs/SXC_peers.txt: -------------------------------------------------------------------------------- 1 | 104.238.221.17:16814 2 | 148.163.102.28:16814 3 | 167.160.36.152:16814 4 | 192.227.158.136:16814 5 | 213.46.197.237:16814 6 | 87.204.149.94:16814 7 | 45.43.26.103:16814 8 | 172.110.18.177:16814 9 | 172.110.18.178:16814 10 | 185.116.238.204:16814 11 | 84.242.207.225:16814 12 | -------------------------------------------------------------------------------- /assets/deps/confs/SYS_peers.txt: -------------------------------------------------------------------------------- 1 | 176.9.13.13 2 | 162.210.92.46 3 | 146.0.32.101 4 | 144.76.94.38 5 | 50.157.173.168 6 | 188.165.3.6 7 | 88.198.15.19 8 | 192.95.29.72 9 | 108.61.10.90 10 | 71.97.31.194 11 | 40.86.87.8 12 | 45.79.215.60 13 | 97.124.163.6 14 | 192.241.200.33 15 | 184.164.147.82 16 | 162.243.59.178 17 | 107.178.109.224 18 | 198.15.127.242 19 | 98.115.147.74 20 | 194.135.90.38 21 | 86.131.170.245 22 | 107.170.185.5 23 | 216.14.119.170 24 | 108.170.26.210 25 | 183.131.213.30 26 | -------------------------------------------------------------------------------- /assets/deps/confs/TAZ_peers.txt: -------------------------------------------------------------------------------- 1 | 176.9.26.39 2 | 5.9.102.210 3 | 78.47.196.146 4 | -------------------------------------------------------------------------------- /assets/deps/confs/UNO_peers.txt: -------------------------------------------------------------------------------- 1 | 195.154.223.134 2 | 85.25.217.233 3 | 104.172.24.79 4 | 188.165.42.51 5 | 45.32.244.201 6 | 52.23.179.46 7 | 192.95.29.72 8 | 185.50.213.123 9 | -------------------------------------------------------------------------------- /assets/deps/confs/VIA_peers.txt: -------------------------------------------------------------------------------- 1 | 84.73.4.183 2 | 98.115.147.74 3 | 192.241.187.222 4 | 159.203.208.102 5 | 85.25.44.119 6 | 178.32.251.114 7 | 109.155.227.178 8 | 146.0.32.101 9 | 108.61.10.90 10 | 198.27.82.134 11 | 80.74.157.31 12 | 192.241.183.16 13 | 164.132.25.194 14 | 128.199.47.200 15 | 173.255.197.64 16 | 46.101.136.168 17 | 207.192.70.250 18 | 54.201.183.106 19 | 211.149.175.37 20 | 128.199.192.241 21 | 216.146.143.177 22 | 82.164.213.27 23 | 107.170.167.218 24 | 195.154.223.134 25 | -------------------------------------------------------------------------------- /assets/deps/confs/ZEC_peers.txt: -------------------------------------------------------------------------------- 1 | 198.100.147.192 2 | 159.203.60.92 3 | 188.166.31.56 4 | 46.105.126.215 5 | -------------------------------------------------------------------------------- /assets/deps/confs/ZET_peers.txt: -------------------------------------------------------------------------------- 1 | 208.94.242.218 2 | 85.25.217.233 3 | 76.95.178.229 4 | 155.94.243.135 5 | 108.61.10.90 6 | 155.254.49.54 7 | 198.27.81.25 8 | 94.249.166.140 9 | -------------------------------------------------------------------------------- /assets/deps/confs/iguana.conf: -------------------------------------------------------------------------------- 1 | { "exchanges":[{"name":"poloniex"},{"name":"btc38"}] } -------------------------------------------------------------------------------- /assets/icons/agama_app_icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_app_icon.icns -------------------------------------------------------------------------------- /assets/icons/agama_app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_app_icon.ico -------------------------------------------------------------------------------- /assets/icons/agama_icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/128x128.png -------------------------------------------------------------------------------- /assets/icons/agama_icons/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/16x16.png -------------------------------------------------------------------------------- /assets/icons/agama_icons/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/24x24.png -------------------------------------------------------------------------------- /assets/icons/agama_icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/256x256.png -------------------------------------------------------------------------------- /assets/icons/agama_icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/32x32.png -------------------------------------------------------------------------------- /assets/icons/agama_icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/48x48.png -------------------------------------------------------------------------------- /assets/icons/agama_icons/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/64x64.png -------------------------------------------------------------------------------- /assets/icons/agama_icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/96x96.png -------------------------------------------------------------------------------- /assets/icons/agama_icons/agama_app_icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/agama_app_icon.icns -------------------------------------------------------------------------------- /assets/icons/agama_icons/agama_app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/icons/agama_icons/agama_app_icon.ico -------------------------------------------------------------------------------- /assets/installer_imgs/Agama_installer_splash_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/installer_imgs/Agama_installer_splash_image.png -------------------------------------------------------------------------------- /assets/installer_imgs/Agama_installer_wizard_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/installer_imgs/Agama_installer_wizard_image.png -------------------------------------------------------------------------------- /assets/installer_imgs/Iguana_installer_splash_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/installer_imgs/Iguana_installer_splash_image.png -------------------------------------------------------------------------------- /assets/installer_imgs/Iguana_installer_wizard_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/installer_imgs/Iguana_installer_wizard_image.png -------------------------------------------------------------------------------- /assets/installer_imgs/supernet-agama-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/installer_imgs/supernet-agama-logo.png -------------------------------------------------------------------------------- /assets/installer_imgs/supernet-iguana-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/assets/installer_imgs/supernet-iguana-logo.png -------------------------------------------------------------------------------- /assets/js/iguana.js: -------------------------------------------------------------------------------- 1 | //SuperNET iguana app launcher 2 | 3 | //var exec = require('child_process').exec 4 | //exec does not return obj with stream but instead the whole buffer output from proc 5 | //spawn returns objects with stderr and out streams 6 | //for question contact ca333@keemail.me 7 | 8 | const spawn = require('child_process').spawn; 9 | var iguana = path.join(__dirname, '/assets/iguana/iguana'); 10 | //var os = require('os'); 11 | -------------------------------------------------------------------------------- /assets/js/startup.js: -------------------------------------------------------------------------------- 1 | //startup separator for superNET iguana 2 | -------------------------------------------------------------------------------- /binary_artifacts.sh: -------------------------------------------------------------------------------- 1 | echo Refreshing binaries from artifacts.supernet.org 2 | echo ========================================= 3 | echo Step: Removing old binaries 4 | pwd 5 | [ ! -d assets ] && \ 6 | mkdir -p assets 7 | cd assets 8 | [ -d artifacts.supernet.org ] && \ 9 | echo Removing old artifacts. && \ 10 | rm -rvf artifacts.supernet.org 11 | echo 12 | echo Step: Cloning latest binaries for build 13 | wget --recursive --no-parent https://artifacts.supernet.org/latest/ 14 | cd .. 15 | echo ========================================= 16 | echo 17 | pwd 18 | echo ========================================= 19 | echo Step: Permission +x for OSX binaries from artifacts to assets/bin/osx/ 20 | echo 21 | rm assets/artifacts.supernet.org/latest/osx/iguana 22 | chmod +x assets/artifacts.supernet.org/latest/osx/komodo* 23 | 24 | mkdir assets/bin 25 | mv assets/artifacts.supernet.org/latest/osx assets/bin/osx 26 | 27 | echo Moving legacy libs to assets/bin 28 | wget https://supernetorg.bintray.com/misc/libs_legacy_osx.zip 29 | checksum=`shasum -a 256 libs_legacy_osx.zip | awk '{ print $1 }'` 30 | if [ "$checksum" = "e9474aa243694a2d4c87fccc443e4b16a9a5172a24da76af9e5ecddd006649bb" ]; then 31 | echo "Checksum is correct." 32 | unzip libs_legacy_osx.zip 33 | cp -rvf libs_legacy_osx/* assets/bin/osx/. 34 | else 35 | echo "Checksum is incorrect!" 36 | exit 0 37 | fi 38 | echo ========================================= 39 | echo Step: Moving Windows binaries from artifacts to assets/bin/win64/ 40 | #echo 41 | rm assets/artifacts.supernet.org/latest/windows/iguana 42 | mv assets/artifacts.supernet.org/latest/windows assets/bin/win64 43 | echo 44 | echo ========================================= 45 | echo Step: Permissions +x for linux64 binaries from artifacts to assets/bin/linux64 46 | echo 47 | rm assets/artifacts.supernet.org/latest/linux/iguana 48 | chmod +x assets/artifacts.supernet.org/latest/linux/komodo* 49 | echo Moving Linux bins to assets/bin 50 | mv assets/artifacts.supernet.org/latest/linux assets/bin/linux64/ 51 | echo 52 | echo ========================================= 53 | echo Step: Finished Updating binaries from artifacts 54 | echo -------------------------------------------------------------------------------- /binary_artifacts_mac.sh: -------------------------------------------------------------------------------- 1 | echo Refreshing binaries from artifacts.supernet.org 2 | echo ========================================= 3 | echo Step: Removing old binaries 4 | mkdir -p build 5 | cd build 6 | rm -rvf artifacts.supernet.org 7 | echo 8 | echo Step: Cloning latest binaries for build 9 | mkdir -p artifacts.supernet.org/latest/osx 10 | curl "https://artifacts.supernet.org/latest/osx/iguana" -o "artifacts.supernet.org/latest/osx/iguana" 11 | curl "https://artifacts.supernet.org/latest/osx/komodo-cli" -o "artifacts.supernet.org/latest/osx/komodo-cli" 12 | curl "https://artifacts.supernet.org/latest/osx/komodod" -o "artifacts.supernet.org/latest/osx/komodod" 13 | curl "https://artifacts.supernet.org/latest/osx/libgcc_s.1.dylib" -o "artifacts.supernet.org/latest/osx/libgcc_s.1.dylib" 14 | curl "https://artifacts.supernet.org/latest/osx/libgomp.1.dylib" -o "artifacts.supernet.org/latest/osx/libgomp.1.dylib" 15 | curl "https://artifacts.supernet.org/latest/osx/libnanomsg.5.0.0.dylib" -o "artifacts.supernet.org/latest/osx/libnanomsg.5.0.0.dylib" 16 | curl "https://artifacts.supernet.org/latest/osx/libstdc%2B%2B.6.dylib" -o "artifacts.supernet.org/latest/osx/libstdc++.6.dylib" 17 | 18 | chmod -R +x artifacts.supernet.org/latest/ 19 | cd .. 20 | echo ========================================= 21 | echo 22 | echo ========================================= 23 | echo Step: Moving osx binaries from artifacts to assets/bin/osx/ 24 | echo 25 | mv -fv build/artifacts.supernet.org/latest/osx/iguana assets/bin/osx/ 26 | mv -fv build/artifacts.supernet.org/latest/osx/komodo-cli assets/bin/osx/ 27 | mv -fv build/artifacts.supernet.org/latest/osx/komodod assets/bin/osx/ 28 | mv -fv build/artifacts.supernet.org/latest/osx/libgcc_s.1.dylib assets/bin/osx/ 29 | mv -fv build/artifacts.supernet.org/latest/osx/libgomp.1.dylib assets/bin/osx/ 30 | mv -fv build/artifacts.supernet.org/latest/osx/libnanomsg.5.0.0.dylib assets/bin/osx/ 31 | mv -fv build/artifacts.supernet.org/latest/osx/libstdc++.6.dylib assets/bin/osx/ 32 | echo 33 | echo ========================================= 34 | echo Step: Moving Win64 binaries from artifacts to assets/bin/win64/ 35 | echo 36 | mv -fv build/artifacts.supernet.org/latest/windows/genkmdconf.bat assets/bin/win64/ 37 | mv -fv build/artifacts.supernet.org/latest/windows/iguana.exe assets/bin/win64/ 38 | mv -fv build/artifacts.supernet.org/latest/windows/index.html assets/bin/win64/ 39 | mv -fv build/artifacts.supernet.org/latest/windows/komodo-cli.exe assets/bin/win64/ 40 | mv -fv build/artifacts.supernet.org/latest/windows/komodo-tx.exe assets/bin/win64/ 41 | mv -fv build/artifacts.supernet.org/latest/windows/komodod.exe assets/bin/win64/ 42 | mv -fv build/artifacts.supernet.org/latest/windows/libcrypto-1_1.dll assets/bin/win64/ 43 | mv -fv build/artifacts.supernet.org/latest/windows/libcurl-4.dll assets/bin/win64/ 44 | mv -fv build/artifacts.supernet.org/latest/windows/libcurl.dll assets/bin/win64/ 45 | mv -fv build/artifacts.supernet.org/latest/windows/libgcc_s_sjlj-1.dll assets/bin/win64/ 46 | mv -fv build/artifacts.supernet.org/latest/windows/libnanomsg.dll assets/bin/win64/ 47 | mv -fv build/artifacts.supernet.org/latest/windows/libssl-1_1.dll assets/bin/win64/ 48 | mv -fv build/artifacts.supernet.org/latest/windows/libwinpthread-1.dll assets/bin/win64/ 49 | mv -fv build/artifacts.supernet.org/latest/windows/nanomsg.dll assets/bin/win64/ 50 | mv -fv build/artifacts.supernet.org/latest/windows/pthreadvc2.dll assets/bin/win64/ 51 | echo 52 | echo ========================================= 53 | echo Step: Moving linux64 binaries from artifacts to assets/bin/linux64 54 | echo 55 | mv -fv build/artifacts.supernet.org/latest/linux/iguana assets/bin/linux64/ 56 | mv -fv build/artifacts.supernet.org/latest/linux/komodo-cli assets/bin/linux64/ 57 | mv -fv build/artifacts.supernet.org/latest/linux/komodod assets/bin/linux64/ 58 | echo 59 | echo ========================================= 60 | echo Step: Cleaning artifacts data 61 | echo 62 | rm -rf build/ 63 | echo 64 | echo ========================================= 65 | echo Step: Finished Updating binaries from artifacts 66 | echo -------------------------------------------------------------------------------- /buildscripts/easydex-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script to build gui for Agama App 3 | 4 | [ -d ${WORKSPACE}/gui/EasyDEX-GUI ] && cd ${WORKSPACE}/gui/EasyDEX-GUI 5 | [ -d ../gui/EasyDEX-GUI ] && cd ../gui/EasyDEX-GUI 6 | [ -d gui/EasyDEX-GUI ] && cd gui/EasyDEX-GUI 7 | 8 | echo "Building EasyDEX-GUI" 9 | echo "Actual directory is: ${PWD}" 10 | 11 | echo "Checkout to redux branch." 12 | git checkout electrum 13 | git pull origin electrum 14 | 15 | [ -d react ] && cd react || echo "!!! I can't find react" 16 | echo "Actual directory is: ${PWD}" 17 | echo "Installing nodejs modules." 18 | npm install 19 | npm install webpack 20 | 21 | echo "Building EasyDEX-GUI app." 22 | npm run build 23 | echo "EasyDEX-GUI is built!" 24 | -------------------------------------------------------------------------------- /buildscripts/electron-build-linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### Build script for Iguana application for Linux x64 platform. 3 | ### Created by mmaxian, 3/2017 4 | 5 | [ -z $AGAMA_VERSION ] && echo "AGAMA_VERSION variable is not set." && exit 0 6 | [ ! -d build ] && mkdir build 7 | 8 | echo 9 | echo "Build script for Iguana application for Linux x64 platform." 10 | echo "Preparing electron package $AGAMA_VERSION" 11 | 12 | electron-packager . --platform=linux --arch=x64 \ 13 | --icon=assets/icons/agama_icons/128x128.png \ 14 | --out=build/ \ 15 | --buildVersion=$AGAMA_VERSION \ 16 | --ignore=assets/bin/win64 \ 17 | --ignore=assets/bin/osx \ 18 | --ignore=react/node_modules \ 19 | --ignore=react/src \ 20 | --ignore=react/www \ 21 | --overwrite 22 | -------------------------------------------------------------------------------- /buildscripts/electron-build-osx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### Build script for Iguana application for MacOS platform. 3 | ### Created by mmaxian, 3/2017 4 | 5 | [ -z $AGAMA_VERSION ] && echo "AGAMA_VERSION variable is not set." && exit 0 6 | [ ! -d build ] && mkdir build 7 | 8 | echo 9 | echo "Build script for Iguana application for MacOS platform." 10 | echo "Preparing electron package $AGAMA_VERSION" 11 | 12 | electron-packager . --platform=darwin --arch=x64 \ 13 | --icon=assets/icons/agama_app_icon.icns \ 14 | --out=build/ --buildVersion=$AGAMA_VERSION \ 15 | --ignore=assets/bin/win64 \ 16 | --ignore=assets/bin/linux64 \ 17 | --ignore=react/node_modules \ 18 | --ignore=react/src \ 19 | --ignore=react/www \ 20 | --overwrite 21 | -------------------------------------------------------------------------------- /buildscripts/electron-build-windows.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### Build script for Iguana application for Windows x64 platform. 3 | ### Created by mmaxian, 3/2017 4 | 5 | [ -z $AGAMA_VERSION ] && echo "AGAMA_VERSION variable is not set." && exit 0 6 | [ ! -d build ] && mkdir build 7 | 8 | echo 9 | echo "Build script for Iguana application for Windows x64 platform." 10 | echo "Preparing electron package $AGAMA_VERSION" 11 | 12 | electron-packager . --platform=win32 \ 13 | --arch=ia32 \ 14 | --icon=assets/icons/agama_app_icon.ico \ 15 | --out=build/ \ 16 | --buildVersion=$AGAMA_VERSION \ 17 | --ignore=assets/bin/osx \ 18 | --ignore=assets/bin/linux64 \ 19 | --ignore=react/node_modules \ 20 | --ignore=react/src \ 21 | --ignore=react/www \ 22 | --overwrite \ 23 | --version-string.CompanyName="SuperNET" \ 24 | --version-string.FileDescription="Agama" \ 25 | --version-string.OriginalFilename="Agama" \ 26 | --version-string.ProductName="Agama" \ 27 | --version-string.InternalName="Agama" \ 28 | --app-copyright="Copyright (C) 2017 SuperNET. All rights reserved." 29 | -------------------------------------------------------------------------------- /check_submodule.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### Script will check EasyDEX-GUI submodule in gui folder. 3 | ### If you used git clone without --recursive option this is way to go. 4 | 5 | PWD=`pwd` 6 | SIZE=`du -sk gui/EasyDEX-GUI` 7 | 8 | echo "Checking EasyDEX-GUI folder." 9 | cd gui/EasyDEX-GUI && \ 10 | git submodule update --recursive && \ 11 | cd ../.. && \ 12 | echo "Folder looks fine." || \ 13 | echo "Some problem with cloning submodule EasyDEX-GUI." 14 | echo 15 | -------------------------------------------------------------------------------- /gui/startup/agama-instance-error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 23 |
Another Agama instance is already running!
24 |
Please close all other instances and restart the app.
25 |
26 | 29 |
30 |
31 | 32 | -------------------------------------------------------------------------------- /gui/startup/app-closing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
19 | 25 |
26 | App is closing. Please wait...

27 | This may take a while depending on your system resources and current state of daemon applications. 28 |
29 |
30 |
31 | 32 | -------------------------------------------------------------------------------- /gui/startup/app-settings.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
20 |
23 | 24 |
25 | 31 |
App configuration (selected options only)
32 |
35 | 36 |
39 |
Any changes to app config require app restart!
40 |
41 | 44 | 47 | 50 | 53 |
54 | 55 |
58 |
59 | 62 |
Settings notification
63 |
64 |
65 |
66 | 67 |
68 | 69 |
70 | 71 | -------------------------------------------------------------------------------- /gui/startup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
20 | 21 |
22 |
23 | 29 |
30 | Choose Agama mode 31 |
35 | 36 |
37 |
38 |
39 | 48 |
Full blockchain mode
49 | 55 |
59 | 60 |
61 | 72 | 73 |
Starts in seconds
74 | 80 |
84 | 85 |
86 | 97 | 98 |
99 | 105 | 106 |
107 |
108 |
109 | 110 | 111 | -------------------------------------------------------------------------------- /make-deb.js: -------------------------------------------------------------------------------- 1 | // prequsites: https://www.npmjs.com/package/electron-installer-debian 2 | 3 | var installer = require('electron-installer-debian'); 4 | 5 | var options = { 6 | src: 'build/Agama-linux-x64/', 7 | dest: 'build/', 8 | arch: 'amd64', 9 | icon: 'assets/icons/agama_icons/64x64.png', 10 | name: 'agama-app', 11 | bin: 'Agama', 12 | categories: ['Office', 'Internet'], 13 | homepage: 'http://supernet.org', 14 | maintainer: 'SuperNET ', 15 | } 16 | 17 | console.log('Creating package (this may take a while)'); 18 | 19 | installer(options, function (err) { 20 | if (err) { 21 | console.error(err, err.stack); 22 | process.exit(1); 23 | } 24 | 25 | console.log('Successfully created package at ' + options.dest); 26 | }); -------------------------------------------------------------------------------- /make-patch.sh: -------------------------------------------------------------------------------- 1 | cd gui/EasyDEX-GUI/react 2 | echo "building gui..." 3 | rm -rf ./build 4 | mkdir build 5 | mkdir build/assets 6 | cp -R src/assets build/ 7 | NODE_ENV="production" webpack 8 | cd ../../../ 9 | echo "copy patch files" 10 | rm -rf ./patch.zip 11 | rm -rf ./patch 12 | mkdir patch 13 | mkdir patch/gui 14 | mkdir patch/gui/EasyDEX-GUI 15 | mkdir patch/gui/EasyDEX-GUI/react 16 | mkdir patch/gui/EasyDEX-GUI/react 17 | cp -R gui/EasyDEX-GUI/react/build patch/gui/EasyDEX-GUI/react/build 18 | cp -R gui/EasyDEX-GUI/assets patch/gui/EasyDEX-GUI 19 | cp -R gui/startup patch/gui/startup 20 | cp ./main.js patch 21 | cp ./version patch 22 | cp -R routes patch/routes 23 | cp -R private patch/private 24 | echo "package patch.zip" 25 | cd patch 26 | zip -r patch.zip gui routes private main.js version 27 | cd ../ 28 | cp patch/patch.zip ./ 29 | rm -rf patch 30 | echo "patch.zip is ready" -------------------------------------------------------------------------------- /make-rpm.js: -------------------------------------------------------------------------------- 1 | // prequsites: https://www.npmjs.com/package/electron-installer-redhat 2 | 3 | var installer = require('electron-installer-redhat'); 4 | 5 | var options = { 6 | src: 'build/Agama-linux-x64/', 7 | dest: 'build/', 8 | arch: 'x86_64', 9 | icon: 'assets/icons/agama_icons/64x64.png', 10 | name: 'agama-app', 11 | bin: 'Agama', 12 | categories: ['Office', 'Internet'], 13 | homepage: 'http://supernet.org', 14 | maintainer: 'SuperNET ', 15 | }; 16 | 17 | console.log('Creating package (this may take a while)'); 18 | 19 | installer(options, function (err) { 20 | if (err) { 21 | console.error(err, err.stack); 22 | process.exit(1); 23 | } 24 | 25 | console.log('Successfully created package at ' + options.dest); 26 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agama-app", 3 | "productName": "Agama", 4 | "version": "0.2.26", 5 | "description": "Agama Wallet Desktop App", 6 | "main": "main.js", 7 | "scripts": { 8 | "start": "electron .", 9 | "make-patch": "./make-patch.sh", 10 | "make-rpm": "node make-rpm.js", 11 | "make-deb": "node make-deb.js" 12 | }, 13 | "repository": "https://github.com/KomodoPlatform/Agama/", 14 | "homepage": "http://supernet.org", 15 | "keywords": [ 16 | "agama", 17 | "SuperNET", 18 | "komodo", 19 | "multicoin", 20 | "wallet", 21 | "spv" 22 | ], 23 | "author": "SuperNET Team", 24 | "license": "MIT", 25 | "devDependencies": { 26 | "electron": "1.7.10", 27 | "electron-installer-debian": "^0.6.0", 28 | "electron-installer-redhat": "^0.5.0" 29 | }, 30 | "dependencies": { 31 | "adm-zip": "^0.4.7", 32 | "arch": "^2.1.0", 33 | "async": "^2.6.0", 34 | "bigi": "^1.4.2", 35 | "bip39": "^2.4.0", 36 | "bitcoinforksjs-lib": "git://github.com/bitcoinjs/bitcoinjs-lib#opt-in-bitcoincash-sighash", 37 | "bitcoinjs-lib": "git://github.com/SuperNETorg/bitcoinjs-lib", 38 | "bitcoinjs-lib-zcash": "git://github.com/pbca26/bitcoinjs-lib#zcash", 39 | "bitcoinjs-lib-pos": "git://github.com/KomodoPlatform/bitcoinjs-lib-pos", 40 | "bluebird": "^3.4.7", 41 | "body-parser": "^1.15.2", 42 | "buffer-reverse": "^1.0.1", 43 | "coinselect": "github:bitcoinjs/coinselect", 44 | "electron": "1.7.11", 45 | "express": "^4.14.0", 46 | "fix-path": "^2.1.0", 47 | "fs-extra": "^4.0.2", 48 | "graceful-fs": "^4.1.11", 49 | "js-sha256": "^0.7.1", 50 | "marketmaker": "git://github.com/pbca26/marketmaker", 51 | "nodejs-aes256": "^1.0.1", 52 | "portscanner": "^2.1.1", 53 | "ps-node": "^0.1.5", 54 | "remote-file-size": "^3.0.3", 55 | "request": "^2.80.0", 56 | "sha256": "^0.2.0", 57 | "socket.io": "^1.7.3", 58 | "wif": "^2.0.6" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /private/mainmenu.js: -------------------------------------------------------------------------------- 1 | const {Menu} = require('electron'); 2 | const electron = require('electron'); 3 | const app = electron.app; 4 | const {shell} = require('electron'); 5 | 6 | const template = [ 7 | { 8 | label: 'Edit', 9 | submenu: [ 10 | { 11 | role: 'undo' 12 | }, 13 | { 14 | role: 'redo' 15 | }, 16 | { 17 | type: 'separator' 18 | }, 19 | { 20 | role: 'cut' 21 | }, 22 | { 23 | role: 'copy' 24 | }, 25 | { 26 | role: 'paste' 27 | }, 28 | { 29 | role: 'pasteandmatchstyle' 30 | }, 31 | { 32 | role: 'delete' 33 | }, 34 | { 35 | role: 'selectall' 36 | } 37 | ] 38 | }, 39 | { 40 | label: 'View', 41 | submenu: [ 42 | { 43 | label: 'Reload', 44 | accelerator: 'CmdOrCtrl+R', 45 | click (item, focusedWindow) { 46 | if (focusedWindow) 47 | focusedWindow.reload(); 48 | } 49 | }, 50 | { 51 | label: 'Toggle Developer Tools', 52 | accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I', 53 | click (item, focusedWindow) { 54 | if (focusedWindow) 55 | focusedWindow.webContents.toggleDevTools(); 56 | } 57 | }, 58 | { 59 | type: 'separator' 60 | }, 61 | { 62 | role: 'resetzoom' 63 | }, 64 | { 65 | role: 'zoomin' 66 | }, 67 | { 68 | role: 'zoomout' 69 | }, 70 | { 71 | type: 'separator' 72 | }, 73 | { 74 | role: 'togglefullscreen' 75 | } 76 | ] 77 | }, 78 | { 79 | role: 'window', 80 | submenu: [ 81 | { 82 | role: 'minimize' 83 | }, 84 | { 85 | role: 'close' 86 | } 87 | ] 88 | }, 89 | { 90 | role: 'help', 91 | label: 'Debug', 92 | submenu: [ 93 | { 94 | label: 'Reset settings', 95 | click (item, focusedWindow) { 96 | focusedWindow.resetSettings(); 97 | } 98 | }, 99 | ] 100 | } 101 | ] 102 | 103 | if (process.platform === 'darwin') { 104 | const name = app.getName(); 105 | 106 | template.unshift({ 107 | label: name, 108 | submenu: [ 109 | { 110 | role: 'about' 111 | }, 112 | { 113 | type: 'separator' 114 | }, 115 | { 116 | role: 'services', 117 | submenu: [] 118 | }, 119 | { 120 | type: 'separator' 121 | }, 122 | { 123 | role: 'hide' 124 | }, 125 | { 126 | role: 'hideothers' 127 | }, 128 | { 129 | role: 'unhide' 130 | }, 131 | { 132 | type: 'separator' 133 | }, 134 | { 135 | label: 'Quit', 136 | accelerator: 'CmdOrCtrl+Q', 137 | role: 'close' 138 | } 139 | ] 140 | }); 141 | // Edit menu. 142 | template[1].submenu.push( 143 | { 144 | type: 'separator' 145 | }, 146 | { 147 | label: 'Speech', 148 | submenu: [ 149 | { 150 | role: 'startspeaking' 151 | }, 152 | { 153 | role: 'stopspeaking' 154 | } 155 | ] 156 | } 157 | ); 158 | // Window menu. 159 | template[3].submenu = [ 160 | { 161 | label: 'Close', 162 | accelerator: 'CmdOrCtrl+W', 163 | role: 'close' 164 | }, 165 | { 166 | label: 'Minimize', 167 | accelerator: 'CmdOrCtrl+M', 168 | role: 'minimize' 169 | }, 170 | { 171 | label: 'Zoom', 172 | role: 'zoom' 173 | }, 174 | { 175 | type: 'separator' 176 | }, 177 | { 178 | label: 'Bring All to Front', 179 | role: 'front' 180 | } 181 | ] 182 | }; 183 | 184 | const menu = Menu.buildFromTemplate(template); 185 | Menu.setApplicationMenu(menu); -------------------------------------------------------------------------------- /private/setconf.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Satinderjit Singh 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | * 22 | */ 23 | 24 | const child_process = require('child_process'), 25 | fs = require('fs'), 26 | path = require('path'), 27 | os = require('os'); 28 | 29 | var coind_conf = module.exports = { 30 | exec: child_process.exec, 31 | status: status 32 | }; 33 | 34 | /** 35 | * Parses the status for a single network interface. 36 | * 37 | * @private 38 | * @static 39 | * @category coind_conf 40 | * @returns {object} The parsed network interface status. 41 | * 42 | */ 43 | function parse_status_block(block) { 44 | let match; 45 | let parsed = { 46 | settings: 'exists' 47 | }; 48 | 49 | if ((match = block.match(/rpcuser=\s*(.*)/))) { 50 | parsed.rpcuser = match[1]; 51 | } 52 | 53 | if ((match = block.match(/rpcpass=\s*(.*)/))) { 54 | parsed.rpcpass = match[1]; 55 | } 56 | 57 | if ((match = block.match(/rpcpassword=\s*(.*)/))) { 58 | parsed.rpcpassword = match[1]; 59 | } 60 | 61 | if ((match = block.match(/rpcport=\s*(.*)/))) { 62 | parsed.rpcport = match[1]; 63 | } 64 | 65 | if ((match = block.match(/rpcbind=\s*(.*)/))) { 66 | parsed.rpcbind = match[1]; 67 | } 68 | 69 | if ((match = block.match(/server=\s*(.*)/))) { 70 | parsed.server = match[1]; 71 | } 72 | 73 | if ((match = block.match(/txindex=\s*(.*)/))) { 74 | parsed.txindex = match[1]; 75 | } 76 | 77 | if ((match = block.match(/addnode=\s*(.*)/))) { 78 | parsed.addnode = match[1]; 79 | } 80 | 81 | return parsed; 82 | } 83 | 84 | /** 85 | * Parses the status for all network interfaces. 86 | * 87 | * @private 88 | * @static 89 | * @category coind_conf 90 | * @param {function} callback The callback function. 91 | * 92 | */ 93 | function parse_status(callback) { 94 | return function(error, stdout, stderr) { 95 | if (error) { 96 | callback(error); 97 | } else { 98 | callback(error, 99 | stdout.trim().split('\n\n').map(parse_status_block)); 100 | } 101 | }; 102 | } 103 | 104 | function status(confPath, callback) { 105 | if (os.platform() === 'darwin' || 106 | os.platform() === 'linux') { 107 | this.exec(`cat "${confPath}"`, parse_status(callback)); 108 | } 109 | 110 | if (os.platform() === 'win32') { 111 | this.exec(`type "${confPath}"`, parse_status(callback)); 112 | } 113 | } -------------------------------------------------------------------------------- /routes/appConfig.js: -------------------------------------------------------------------------------- 1 | const appConfig = { 2 | config: { // default config 3 | host: '127.0.0.1', 4 | agamaPort: 17777, 5 | maxDescriptors: { 6 | darwin: 90000, 7 | linux: 1000000, 8 | }, 9 | dev: false, 10 | debug: false, 11 | roundValues: false, 12 | experimentalFeatures: false, 13 | dataDir: '', 14 | dex: { 15 | walletUnlockTimeout: 3600, 16 | }, 17 | cliStopTimeout: 1000, 18 | failedRPCAttemptsThreshold: 10, 19 | stopNativeDaemonsOnQuit: true, 20 | lang: 'EN', 21 | rpc2cli: false, 22 | fiatRates: false, 23 | }, 24 | schema: { 25 | host: { 26 | display: true, 27 | type: 'string', 28 | displayName: 'Hostname', 29 | info: 'Application hostname', 30 | }, 31 | agamaPort: { 32 | display: true, 33 | type: 'number', 34 | displayName: 'Agama Port', 35 | info: 'Agama HTTP port. Required to run GUI.', 36 | }, 37 | maxDescriptors: { 38 | display: false, 39 | displayName: 'Max Descriptors per Process', 40 | darwin: { 41 | display: true, 42 | displayName: 'MacOS (Darwin)', 43 | type: 'number', 44 | }, 45 | linux: { 46 | display: true, 47 | displayName: 'Linux', 48 | type: 'number', 49 | }, 50 | }, 51 | dev: { 52 | display: true, 53 | initDisplay: true, 54 | displayName: 'Developer mode', 55 | info: 'Enable developer mode', 56 | type: 'boolean', 57 | }, 58 | debug: { 59 | display: true, 60 | initDisplay: true, 61 | displayName: 'Debug', 62 | info: 'Enable debug output', 63 | type: 'boolean', 64 | }, 65 | roundValues: { 66 | display: true, 67 | displayName: 'Enable amount rounding', 68 | info: 'Round \"dust\" amounts to save screen space', 69 | type: 'boolean', 70 | }, 71 | experimentalFeatures: { 72 | display: true, 73 | initDisplay: true, 74 | displayName: 'Enable experimental features', 75 | type: 'boolean', 76 | }, 77 | dataDir: { 78 | display: true, 79 | initDisplay: true, 80 | displayName: 'Komodo data directory', 81 | info: 'The data directory is the location where Komodo data files are stored, including the wallet data file', 82 | type: 'folder', 83 | }, 84 | dex: { 85 | display: false, 86 | displayName: 'dex', 87 | walletUnlockTimeout: { 88 | display: true, 89 | displayName: 'walletUnlockTimeout', 90 | type: 'number', 91 | }, 92 | }, 93 | cliStopTimeout: { 94 | display: true, 95 | displayName: 'CLI stop timeout', 96 | info: 'Timeout between consequent CLI stop commands', 97 | type: 'number', 98 | }, 99 | stopNativeDaemonsOnQuit: { 100 | display: true, 101 | displayName: 'Stop native daemons on app quit', 102 | info: 'If set to false agama will run in detached coin daemon mode', 103 | type: 'boolean', 104 | }, 105 | failedRPCAttemptsThreshold: { 106 | display: true, 107 | displayName: 'Failed RPC connect attempts threshold', 108 | info: 'Number of allowed consequent RPC connect failures before the app marks native coin daemon as not running properly', 109 | type: 'number', 110 | }, 111 | lang: { 112 | display: true, 113 | displayName: 'Language', 114 | type: 'select', 115 | data: [ 116 | { name: 'EN', label: 'English' }, 117 | { name: 'DE', label: 'German' } 118 | ], 119 | }, 120 | rpc2cli: { 121 | display: true, 122 | displayName: 'Disable RPC', 123 | info: 'Use CLI instead of RPC JSON server in native mode', 124 | type: 'boolean', 125 | }, 126 | fiatRates: { 127 | display: true, 128 | displayName: 'Fetch fiat rates', 129 | info: 'Get coin fiat rates from atomicexplorer.com', 130 | type: 'boolean', 131 | }, 132 | }, 133 | }; 134 | 135 | module.exports = appConfig; -------------------------------------------------------------------------------- /routes/electrumjs/electrumjs.txdecoder-2bytes.js: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2017 Yuki Akiyama, SuperNET 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | var bitcoin = require('bitcoinjs-lib-zcash'); 26 | 27 | var decodeFormat = function(tx) { 28 | var result = { 29 | txid: tx.getId(), 30 | version: tx.version, 31 | locktime: tx.locktime, 32 | }; 33 | 34 | return result; 35 | } 36 | 37 | var decodeInput = function(tx) { 38 | var result = []; 39 | 40 | tx.ins.forEach(function(input, n) { 41 | var vin = { 42 | txid: input.hash.reverse().toString('hex'), 43 | n: input.index, 44 | script: bitcoin.script.toASM(input.script), 45 | sequence: input.sequence, 46 | }; 47 | 48 | result.push(vin); 49 | }); 50 | 51 | return result; 52 | } 53 | 54 | var decodeOutput = function(tx, network) { 55 | var format = function(out, n, network) { 56 | var vout = { 57 | satoshi: out.value, 58 | value: (1e-8 * out.value).toFixed(8), 59 | n: n, 60 | scriptPubKey: { 61 | asm: bitcoin.script.toASM(out.script), 62 | hex: out.script.toString('hex'), 63 | type: bitcoin.script.classifyOutput(out.script), 64 | addresses: [], 65 | }, 66 | }; 67 | 68 | switch(vout.scriptPubKey.type) { 69 | case 'pubkeyhash': 70 | vout.scriptPubKey.addresses.push(bitcoin.address.fromOutputScript(out.script, network)); 71 | break; 72 | case 'pubkey': 73 | const pubKeyBuffer = new Buffer(vout.scriptPubKey.asm.split(' ')[0], 'hex'); 74 | vout.scriptPubKey.addresses.push(bitcoin.ECPair.fromPublicKeyBuffer(pubKeyBuffer, network).getAddress()); 75 | break; 76 | case 'scripthash': 77 | vout.scriptPubKey.addresses.push(bitcoin.address.fromOutputScript(out.script, network)); 78 | break; 79 | } 80 | 81 | return vout; 82 | } 83 | 84 | var result = []; 85 | 86 | tx.outs.forEach(function(out, n) { 87 | result.push(format(out, n, network)); 88 | }); 89 | 90 | return result; 91 | } 92 | 93 | var TxDecoder = module.exports = function(rawtx, network) { 94 | try { 95 | const _tx = bitcoin.Transaction.fromHex(rawtx); 96 | 97 | return { 98 | tx: _tx, 99 | network: network, 100 | format: decodeFormat(_tx), 101 | inputs: decodeInput(_tx), 102 | outputs: decodeOutput(_tx, network), 103 | }; 104 | } catch (e) { 105 | return false; 106 | } 107 | } 108 | 109 | TxDecoder.prototype.decode = function() { 110 | var result = {}; 111 | var self = this; 112 | 113 | Object.keys(self.format).forEach(function(key) { 114 | result[key] = self.format[key]; 115 | }); 116 | 117 | result.outputs = self.outputs; 118 | 119 | return result; 120 | } -------------------------------------------------------------------------------- /routes/electrumjs/electrumjs.txdecoder-pos.js: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2017 Yuki Akiyama, SuperNET 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | var bitcoin = require('bitcoinjs-lib-pos'); 26 | var script = require('bitcoinjs-lib-pos/src/script'); 27 | var address = require('bitcoinjs-lib-pos/src/address'); 28 | var bitcoinJS = require('bitcoinjs-lib'); 29 | 30 | var decodeFormat = function(tx) { 31 | var result = { 32 | txid: tx.getId(), 33 | version: tx.version, 34 | locktime: tx.locktime, 35 | }; 36 | 37 | return result; 38 | } 39 | 40 | var decodeInput = function(tx) { 41 | var result = []; 42 | 43 | tx.ins.forEach(function(input, n) { 44 | var vin = { 45 | txid: input.hash.reverse().toString('hex'), 46 | n: input.index, 47 | script: script.fromHex(input.hash), 48 | sequence: input.sequence, 49 | }; 50 | 51 | result.push(vin); 52 | }); 53 | 54 | return result; 55 | } 56 | 57 | var decodeOutput = function(tx, network) { 58 | var format = function(out, n, network) { 59 | var vout = { 60 | satoshi: out.value, 61 | value: (1e-8 * out.value).toFixed(8), 62 | n: n, 63 | scriptPubKey: { 64 | asm: bitcoinJS.script.toASM(out.script.chunks), 65 | hex: out.script.toHex(), 66 | type: bitcoin.scripts.classifyOutput(out.script), 67 | addresses: [], 68 | }, 69 | }; 70 | 71 | switch(vout.scriptPubKey.type) { 72 | case 'pubkeyhash': 73 | vout.scriptPubKey.addresses.push(address.fromOutputScript(out.script, network)); 74 | break; 75 | case 'pubkey': 76 | const pubKeyBuffer = new Buffer(vout.scriptPubKey.asm.split(' ')[0], 'hex'); 77 | vout.scriptPubKey.addresses.push(bitcoin.ECPair.fromPublicKeyBuffer(pubKeyBuffer, network).getAddress()); 78 | break; 79 | case 'scripthash': 80 | vout.scriptPubKey.addresses.push(address.fromOutputScript(out.script, network)); 81 | break; 82 | } 83 | 84 | return vout; 85 | } 86 | 87 | var result = []; 88 | 89 | tx.outs.forEach(function(out, n) { 90 | result.push(format(out, n, network)); 91 | }); 92 | 93 | return result; 94 | } 95 | 96 | var TxDecoder = module.exports = function(rawtx, network) { 97 | try { 98 | const _tx = bitcoin.Transaction.fromHex(rawtx, network); 99 | 100 | return { 101 | tx: _tx, 102 | network: network, 103 | format: decodeFormat(_tx), 104 | inputs: decodeInput(_tx), 105 | outputs: decodeOutput(_tx, network), 106 | }; 107 | } catch (e) { 108 | return false; 109 | } 110 | } 111 | 112 | TxDecoder.prototype.decode = function() { 113 | var result = {}; 114 | var self = this; 115 | 116 | Object.keys(self.format).forEach(function(key) { 117 | result[key] = self.format[key]; 118 | }); 119 | 120 | result.outputs = self.outputs; 121 | 122 | return result; 123 | } -------------------------------------------------------------------------------- /routes/electrumjs/electrumjs.txdecoder.js: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License 3 | 4 | Copyright (c) 2017 Yuki Akiyama, SuperNET 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | var bitcoin = require('bitcoinjs-lib'); 26 | 27 | var decodeFormat = function(tx) { 28 | var result = { 29 | txid: tx.getId(), 30 | version: tx.version, 31 | locktime: tx.locktime, 32 | }; 33 | 34 | return result; 35 | } 36 | 37 | var decodeInput = function(tx) { 38 | var result = []; 39 | 40 | tx.ins.forEach(function(input, n) { 41 | var vin = { 42 | txid: input.hash.reverse().toString('hex'), 43 | n: input.index, 44 | script: bitcoin.script.toASM(input.script), 45 | sequence: input.sequence, 46 | }; 47 | 48 | result.push(vin); 49 | }); 50 | 51 | return result; 52 | } 53 | 54 | var decodeOutput = function(tx, network) { 55 | var format = function(out, n, network) { 56 | var vout = { 57 | satoshi: out.value, 58 | value: (1e-8 * out.value).toFixed(8), 59 | n: n, 60 | scriptPubKey: { 61 | asm: bitcoin.script.toASM(out.script), 62 | hex: out.script.toString('hex'), 63 | type: bitcoin.script.classifyOutput(out.script), 64 | addresses: [], 65 | }, 66 | }; 67 | 68 | switch(vout.scriptPubKey.type) { 69 | case 'pubkeyhash': 70 | vout.scriptPubKey.addresses.push(bitcoin.address.fromOutputScript(out.script, network)); 71 | break; 72 | case 'pubkey': 73 | const pubKeyBuffer = new Buffer(vout.scriptPubKey.asm.split(' ')[0], 'hex'); 74 | vout.scriptPubKey.addresses.push(bitcoin.ECPair.fromPublicKeyBuffer(pubKeyBuffer, network).getAddress()); 75 | break; 76 | case 'scripthash': 77 | vout.scriptPubKey.addresses.push(bitcoin.address.fromOutputScript(out.script, network)); 78 | break; 79 | } 80 | 81 | return vout; 82 | } 83 | 84 | var result = []; 85 | 86 | tx.outs.forEach(function(out, n) { 87 | result.push(format(out, n, network)); 88 | }); 89 | 90 | return result; 91 | } 92 | 93 | var TxDecoder = module.exports = function(rawtx, network) { 94 | try { 95 | const _tx = bitcoin.Transaction.fromHex(rawtx); 96 | 97 | return { 98 | tx: _tx, 99 | network: network, 100 | format: decodeFormat(_tx), 101 | inputs: decodeInput(_tx), 102 | outputs: decodeOutput(_tx, network), 103 | }; 104 | } catch (e) { 105 | return false; 106 | } 107 | } 108 | 109 | TxDecoder.prototype.decode = function() { 110 | var result = {}; 111 | var self = this; 112 | 113 | Object.keys(self.format).forEach(function(key) { 114 | result[key] = self.format[key]; 115 | }); 116 | 117 | result.outputs = self.outputs; 118 | 119 | return result; 120 | } -------------------------------------------------------------------------------- /routes/md5.js: -------------------------------------------------------------------------------- 1 | function md5cycle(x, k) { 2 | var a = x[0], b = x[1], c = x[2], d = x[3]; 3 | 4 | a = ff(a, b, c, d, k[0], 7, -680876936); 5 | d = ff(d, a, b, c, k[1], 12, -389564586); 6 | c = ff(c, d, a, b, k[2], 17, 606105819); 7 | b = ff(b, c, d, a, k[3], 22, -1044525330); 8 | a = ff(a, b, c, d, k[4], 7, -176418897); 9 | d = ff(d, a, b, c, k[5], 12, 1200080426); 10 | c = ff(c, d, a, b, k[6], 17, -1473231341); 11 | b = ff(b, c, d, a, k[7], 22, -45705983); 12 | a = ff(a, b, c, d, k[8], 7, 1770035416); 13 | d = ff(d, a, b, c, k[9], 12, -1958414417); 14 | c = ff(c, d, a, b, k[10], 17, -42063); 15 | b = ff(b, c, d, a, k[11], 22, -1990404162); 16 | a = ff(a, b, c, d, k[12], 7, 1804603682); 17 | d = ff(d, a, b, c, k[13], 12, -40341101); 18 | c = ff(c, d, a, b, k[14], 17, -1502002290); 19 | b = ff(b, c, d, a, k[15], 22, 1236535329); 20 | 21 | a = gg(a, b, c, d, k[1], 5, -165796510); 22 | d = gg(d, a, b, c, k[6], 9, -1069501632); 23 | c = gg(c, d, a, b, k[11], 14, 643717713); 24 | b = gg(b, c, d, a, k[0], 20, -373897302); 25 | a = gg(a, b, c, d, k[5], 5, -701558691); 26 | d = gg(d, a, b, c, k[10], 9, 38016083); 27 | c = gg(c, d, a, b, k[15], 14, -660478335); 28 | b = gg(b, c, d, a, k[4], 20, -405537848); 29 | a = gg(a, b, c, d, k[9], 5, 568446438); 30 | d = gg(d, a, b, c, k[14], 9, -1019803690); 31 | c = gg(c, d, a, b, k[3], 14, -187363961); 32 | b = gg(b, c, d, a, k[8], 20, 1163531501); 33 | a = gg(a, b, c, d, k[13], 5, -1444681467); 34 | d = gg(d, a, b, c, k[2], 9, -51403784); 35 | c = gg(c, d, a, b, k[7], 14, 1735328473); 36 | b = gg(b, c, d, a, k[12], 20, -1926607734); 37 | 38 | a = hh(a, b, c, d, k[5], 4, -378558); 39 | d = hh(d, a, b, c, k[8], 11, -2022574463); 40 | c = hh(c, d, a, b, k[11], 16, 1839030562); 41 | b = hh(b, c, d, a, k[14], 23, -35309556); 42 | a = hh(a, b, c, d, k[1], 4, -1530992060); 43 | d = hh(d, a, b, c, k[4], 11, 1272893353); 44 | c = hh(c, d, a, b, k[7], 16, -155497632); 45 | b = hh(b, c, d, a, k[10], 23, -1094730640); 46 | a = hh(a, b, c, d, k[13], 4, 681279174); 47 | d = hh(d, a, b, c, k[0], 11, -358537222); 48 | c = hh(c, d, a, b, k[3], 16, -722521979); 49 | b = hh(b, c, d, a, k[6], 23, 76029189); 50 | a = hh(a, b, c, d, k[9], 4, -640364487); 51 | d = hh(d, a, b, c, k[12], 11, -421815835); 52 | c = hh(c, d, a, b, k[15], 16, 530742520); 53 | b = hh(b, c, d, a, k[2], 23, -995338651); 54 | 55 | a = ii(a, b, c, d, k[0], 6, -198630844); 56 | d = ii(d, a, b, c, k[7], 10, 1126891415); 57 | c = ii(c, d, a, b, k[14], 15, -1416354905); 58 | b = ii(b, c, d, a, k[5], 21, -57434055); 59 | a = ii(a, b, c, d, k[12], 6, 1700485571); 60 | d = ii(d, a, b, c, k[3], 10, -1894986606); 61 | c = ii(c, d, a, b, k[10], 15, -1051523); 62 | b = ii(b, c, d, a, k[1], 21, -2054922799); 63 | a = ii(a, b, c, d, k[8], 6, 1873313359); 64 | d = ii(d, a, b, c, k[15], 10, -30611744); 65 | c = ii(c, d, a, b, k[6], 15, -1560198380); 66 | b = ii(b, c, d, a, k[13], 21, 1309151649); 67 | a = ii(a, b, c, d, k[4], 6, -145523070); 68 | d = ii(d, a, b, c, k[11], 10, -1120210379); 69 | c = ii(c, d, a, b, k[2], 15, 718787259); 70 | b = ii(b, c, d, a, k[9], 21, -343485551); 71 | 72 | x[0] = add32(a, x[0]); 73 | x[1] = add32(b, x[1]); 74 | x[2] = add32(c, x[2]); 75 | x[3] = add32(d, x[3]); 76 | } 77 | 78 | function cmn(q, a, b, x, s, t) { 79 | a = add32(add32(a, q), add32(x, t)); 80 | return add32((a << s) | (a >>> (32 - s)), b); 81 | } 82 | 83 | function ff(a, b, c, d, x, s, t) { 84 | return cmn((b & c) | ((~b) & d), a, b, x, s, t); 85 | } 86 | 87 | function gg(a, b, c, d, x, s, t) { 88 | return cmn((b & d) | (c & (~d)), a, b, x, s, t); 89 | } 90 | 91 | function hh(a, b, c, d, x, s, t) { 92 | return cmn(b ^ c ^ d, a, b, x, s, t); 93 | } 94 | 95 | function ii(a, b, c, d, x, s, t) { 96 | return cmn(c ^ (b | (~d)), a, b, x, s, t); 97 | } 98 | 99 | function md51(s) { 100 | txt = ''; 101 | var n = s.length, 102 | state = [1732584193, -271733879, -1732584194, 271733878], i; 103 | for (i=64; i<=s.length; i+=64) { 104 | md5cycle(state, md5blk(s.substring(i-64, i))); 105 | } 106 | s = s.substring(i-64); 107 | var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; 108 | for (i=0; i>2] |= s.charCodeAt(i) << ((i%4) << 3); 110 | tail[i>>2] |= 0x80 << ((i%4) << 3); 111 | if (i > 55) { 112 | md5cycle(state, tail); 113 | for (i=0; i<16; i++) tail[i] = 0; 114 | } 115 | tail[14] = n*8; 116 | md5cycle(state, tail); 117 | return state; 118 | } 119 | 120 | /* there needs to be support for Unicode here, 121 | * unless we pretend that we can redefine the MD-5 122 | * algorithm for multi-byte characters (perhaps 123 | * by adding every four 16-bit characters and 124 | * shortening the sum to 32 bits). Otherwise 125 | * I suggest performing MD-5 as if every character 126 | * was two bytes--e.g., 0040 0025 = @%--but then 127 | * how will an ordinary MD-5 sum be matched? 128 | * There is no way to standardize text to something 129 | * like UTF-8 before transformation; speed cost is 130 | * utterly prohibitive. The JavaScript standard 131 | * itself needs to look at this: it should start 132 | * providing access to strings as preformed UTF-8 133 | * 8-bit unsigned value arrays. 134 | */ 135 | function md5blk(s) { /* I figured global was faster. */ 136 | var md5blks = [], i; /* Andy King said do it this way. */ 137 | for (i=0; i<64; i+=4) { 138 | md5blks[i>>2] = s.charCodeAt(i) 139 | + (s.charCodeAt(i+1) << 8) 140 | + (s.charCodeAt(i+2) << 16) 141 | + (s.charCodeAt(i+3) << 24); 142 | } 143 | return md5blks; 144 | } 145 | 146 | var hex_chr = '0123456789abcdef'.split(''); 147 | 148 | function rhex(n) { 149 | var s='', j=0; 150 | for(; j<4; j++) 151 | s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] 152 | + hex_chr[(n >> (j * 8)) & 0x0F]; 153 | return s; 154 | } 155 | 156 | function hex(x) { 157 | for (var i=0; i> 16) + (y >> 16) + (lsw >> 16); 180 | return (msw << 16) | (lsw & 0xFFFF); 181 | } 182 | } 183 | 184 | module.exports = md5; -------------------------------------------------------------------------------- /routes/nativeCoind.js: -------------------------------------------------------------------------------- 1 | const nativeCoind = { 2 | 'btc': { 3 | name: 'Bitcoin', 4 | bin: 'bitcoin', 5 | fullMode: true, 6 | port: 8332, 7 | }, 8 | 'btcd': { 9 | name: 'BitcoinDark', 10 | bin: 'bitcoindarkd', 11 | fullMode: true, 12 | port: 14632, 13 | }, 14 | 'ltc': { 15 | name: 'Litecoin', 16 | bin: 'litecoin', 17 | fullMode: true, 18 | port: 9332, 19 | }, 20 | 'sys': { 21 | name: 'Syscoin', 22 | bin: 'syscoin', 23 | fullMode: true, 24 | port: 8368, 25 | }, 26 | 'uno': { 27 | name: 'Unobtanium', 28 | bin: 'unobtanium', 29 | fullMode: true, 30 | port: 65535, 31 | }, 32 | 'nmc': { 33 | name: 'Namecoin', 34 | bin: 'namecoin', 35 | fullMode: true, 36 | port: 8336, 37 | }, 38 | 'game': { 39 | name: 'GameCredits', 40 | bin: 'gamecredits', 41 | fullMode: true, 42 | port: 40001, 43 | }, 44 | 'mzc': { 45 | name: 'MazaCoin', 46 | bin: 'maza', 47 | fullMode: true, 48 | port: 12832, 49 | }, 50 | 'frk': { 51 | name: 'Franko', 52 | bin: 'franko', 53 | fullMode: true, 54 | port: 7913, 55 | }, 56 | 'doge': { 57 | name: 'Dogecoin', 58 | bin: 'dogecoin', 59 | fullMode: true, 60 | port: 22555, 61 | }, 62 | 'dgb': { 63 | name: 'Digibyte', 64 | bin: 'digibyte', 65 | port: 14022, 66 | }, 67 | 'zet': { 68 | name: 'Zetacoin', 69 | bin: 'zetacoin', 70 | fullMode: true, 71 | port: 17335, 72 | }, 73 | 'btm': { 74 | name: 'Bitmark', 75 | bin: 'bitmark', 76 | fullMode: true, 77 | port: 9266, 78 | }, 79 | 'carb': { 80 | name: 'Carboncoin', 81 | bin: 'carboncoin', 82 | fullMode: true, 83 | port: 9351, 84 | }, 85 | 'anc': { 86 | name: 'Anoncoin', 87 | bin: 'anoncoin', 88 | fullMode: true, 89 | port: 28332, 90 | }, 91 | 'lbc': { 92 | name: 'LBRY Credits', 93 | bin: 'lbrycrd', 94 | port: 9245, 95 | } 96 | }; 97 | 98 | module.exports = nativeCoind; -------------------------------------------------------------------------------- /routes/ports.js: -------------------------------------------------------------------------------- 1 | const assetChainPorts = { 2 | 'komodod': '7771', 3 | 'markermaker': '7783', 4 | 'PIZZA': '11608', 5 | 'BEER': '8923', 6 | 'CHIPS': '57776', 7 | 'SUPERNET': '11341', 8 | 'REVS': '10196', 9 | 'MNZ': '14337', 10 | 'WLC': '12167', 11 | 'PANGEA': '14068', 12 | 'DEX': '11890', 13 | 'JUMBLR': '15106', 14 | 'BET': '14250', 15 | 'CRYPTO': '8516', 16 | 'HODL': '14431', 17 | 'MSHARK': '8846', 18 | 'BOTS': '11964', 19 | 'MGW': '12386', 20 | 'COQUI': '14276', 21 | 'MVP': '11676', 22 | 'KV': '8299', 23 | 'CEAL': '11116', 24 | 'MESH': '9455', 25 | 'AXO': '12927', 26 | 'ETOMIC': '10271', 27 | 'VOTE': '8012', 28 | 'BTCH': '8800', 29 | 'USD': '13967', 30 | 'CHF': '15312', 31 | 'CAD': '8720', 32 | 'BRL': '9914', 33 | 'BGN': '9110', 34 | 'AUD': '8045', 35 | 'PLN': '13493', 36 | 'PHP': '11181', 37 | 'NZD': '10915', 38 | 'NOK': '11588', 39 | 'MYR': '10688', 40 | 'MXN': '13970', 41 | 'KRW': '14020', 42 | 'JPY': '13145', 43 | 'INR': '10536', 44 | 'ILS': '14638', 45 | 'IDR': '14459', 46 | 'HKD': '15409', 47 | 'HUF': '13699', 48 | 'HRK': '12617', 49 | 'GBP': '11505', 50 | 'EUR': '8065', 51 | 'DKK': '13830', 52 | 'CNY': '10384', 53 | 'ZAR': '15160', 54 | 'TRY': '13924', 55 | 'THB': '11847', 56 | 'SGD': '14475', 57 | 'SEK': '11447', 58 | 'RON': '8675', 59 | 'RUB': '8199', 60 | 'CZK': '9482' 61 | }; 62 | 63 | module.exports = assetChainPorts; -------------------------------------------------------------------------------- /routes/shepherd.js: -------------------------------------------------------------------------------- 1 | const electron = require('electron'); 2 | const express = require('express'); 3 | const app = electron.app; 4 | let shepherd = express.Router(); 5 | 6 | shepherd.path = require('path'); 7 | shepherd.os = require('os'); 8 | shepherd.fsnode = require('fs'); 9 | shepherd.fs = require('fs-extra'); 10 | shepherd._fs = require('graceful-fs'); 11 | shepherd.md5 = require('./md5.js'); 12 | shepherd.request = require('request'); 13 | shepherd.portscanner = require('portscanner'); 14 | shepherd.aes256 = require('nodejs-aes256'); 15 | shepherd.AdmZip = require('adm-zip'); 16 | shepherd.remoteFileSize = require('remote-file-size'); 17 | shepherd.Promise = require('bluebird'); 18 | shepherd.exec = require('child_process').exec; 19 | shepherd.execFile = require('child_process').execFile; 20 | shepherd.sha256 = require('sha256'); 21 | shepherd.bitcoinJS = require('bitcoinjs-lib'); 22 | shepherd.coinSelect = require('coinselect'); 23 | shepherd.fixPath = require('fix-path'); 24 | shepherd.crypto = require('crypto'); 25 | 26 | shepherd.setconf = require('../private/setconf.js'); 27 | shepherd.nativeCoind = require('./nativeCoind.js'); 28 | shepherd.nativeCoindList = {}; 29 | shepherd.assetChainPorts = require('./ports.js'); 30 | shepherd.assetChainPortsDefault = require('./ports.js'); 31 | shepherd._appConfig = require('./appConfig.js'); 32 | 33 | shepherd.coindInstanceRegistry = {}; 34 | shepherd.coindStdout = {}; 35 | shepherd.guiLog = {}; 36 | shepherd.rpcConf = {}; 37 | shepherd.appRuntimeLog = []; 38 | shepherd.appRuntimeSPVLog = []; 39 | shepherd.lockDownAddCoin = false; 40 | shepherd.mmupass = null; 41 | shepherd.mmRatesInterval = null; 42 | shepherd.mmPublic = { 43 | coins: [], 44 | mmupass: null, 45 | swaps: [], 46 | bids: [], 47 | asks: [], 48 | isAuth: false, 49 | rates: {}, 50 | prices: [], 51 | coinsHelper: {}, 52 | stats: [], 53 | electrumServersList: {}, 54 | }; 55 | 56 | // spv vars and libs 57 | shepherd.electrumCoins = { 58 | auth: false, 59 | }; 60 | shepherd.electrumKeys = {}; 61 | 62 | shepherd.electrumCache = {}; 63 | 64 | shepherd.electrumJSCore = require('./electrumjs/electrumjs.core.js'); 65 | shepherd.electrumJSNetworks = require('./electrumjs/electrumjs.networks.js'); 66 | shepherd.electrumServers = require('./electrumjs/electrumServers.js'); 67 | 68 | shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA = 'connection error or incomplete data'; 69 | 70 | shepherd.appConfig = shepherd._appConfig.config; 71 | 72 | // core 73 | shepherd = require('./shepherd/paths.js')(shepherd); 74 | 75 | shepherd.pathsAgama(); 76 | 77 | // core 78 | shepherd = require('./shepherd/log.js')(shepherd); 79 | shepherd = require('./shepherd/config.js')(shepherd); 80 | 81 | shepherd.appConfig = shepherd.loadLocalConfig(); 82 | 83 | shepherd.pathsDaemons(); 84 | 85 | shepherd.appConfigSchema = shepherd._appConfig.schema; 86 | shepherd.defaultAppConfig = Object.assign({}, shepherd.appConfig); 87 | shepherd.kmdMainPassiveMode = false; 88 | 89 | // spv 90 | shepherd = require('./shepherd/electrum/network.js')(shepherd); 91 | shepherd = require('./shepherd/electrum/coins.js')(shepherd); 92 | shepherd = require('./shepherd/electrum/keys.js')(shepherd); 93 | shepherd = require('./shepherd/electrum/auth.js')(shepherd); 94 | shepherd = require('./shepherd/electrum/merkle.js')(shepherd); 95 | shepherd = require('./shepherd/electrum/balance.js')(shepherd); 96 | shepherd = require('./shepherd/electrum/transactions.js')(shepherd); 97 | shepherd = require('./shepherd/electrum/block.js')(shepherd); 98 | shepherd = require('./shepherd/electrum/createtx.js')(shepherd); 99 | shepherd = require('./shepherd/electrum/createtx-split.js')(shepherd); 100 | shepherd = require('./shepherd/electrum/createtx-multi.js')(shepherd); 101 | shepherd = require('./shepherd/electrum/interest.js')(shepherd); 102 | shepherd = require('./shepherd/electrum/listunspent.js')(shepherd); 103 | shepherd = require('./shepherd/electrum/estimate.js')(shepherd); 104 | 105 | // dex 106 | shepherd = require('./shepherd/dex/coind.js')(shepherd); 107 | shepherd = require('./shepherd/dex/mmControl.js')(shepherd); 108 | shepherd = require('./shepherd/dex/mmRequest.js')(shepherd); 109 | shepherd = require('./shepherd/dex/electrumServersList.js')(shepherd); 110 | 111 | // core 112 | shepherd = require('./shepherd/addCoinShortcuts.js')(shepherd); 113 | shepherd = require('./shepherd/dashboardUpdate.js')(shepherd); 114 | shepherd = require('./shepherd/binsUtils.js')(shepherd); 115 | shepherd = require('./shepherd/downloadUtil.js')(shepherd); 116 | shepherd = require('./shepherd/init.js')(shepherd); 117 | shepherd = require('./shepherd/pin.js')(shepherd); 118 | shepherd = require('./shepherd/downloadBins.js')(shepherd); 119 | shepherd = require('./shepherd/downloadPatch.js')(shepherd); 120 | shepherd = require('./shepherd/downloadZcparams.js')(shepherd); 121 | shepherd = require('./shepherd/coinsList.js')(shepherd); 122 | shepherd = require('./shepherd/quitDaemon.js')(shepherd); 123 | shepherd = require('./shepherd/rpc.js')(shepherd); 124 | shepherd = require('./shepherd/kickstart.js')(shepherd); 125 | shepherd = require('./shepherd/debugLog.js')(shepherd); 126 | shepherd = require('./shepherd/confMaxconnections.js')(shepherd); 127 | shepherd = require('./shepherd/appInfo.js')(shepherd); 128 | shepherd = require('./shepherd/daemonControl.js')(shepherd); 129 | shepherd = require('./shepherd/auth.js')(shepherd); 130 | shepherd = require('./shepherd/coins.js')(shepherd); 131 | shepherd = require('./shepherd/coindWalletKeys.js')(shepherd); 132 | 133 | // elections 134 | shepherd = require('./shepherd/elections.js')(shepherd); 135 | 136 | // explorer 137 | // shepherd = require('./shepherd/explorer/overview.js')(shepherd); 138 | 139 | shepherd.printDirs(); 140 | 141 | // default route 142 | shepherd.get('/', (req, res, next) => { 143 | res.send('Agama app server'); 144 | }); 145 | 146 | // expose sockets obj 147 | shepherd.setIO = (io) => { 148 | shepherd.io = io; 149 | }; 150 | 151 | shepherd.setVar = (_name, _body) => { 152 | shepherd[_name] = _body; 153 | }; 154 | 155 | module.exports = shepherd; -------------------------------------------------------------------------------- /routes/shepherd/addCoinShortcuts.js: -------------------------------------------------------------------------------- 1 | const electrumServers = require('../electrumjs/electrumServers'); 2 | 3 | module.exports = (shepherd) => { 4 | shepherd.startSPV = (coin) => { 5 | if (coin === 'KMD+REVS+JUMBLR') { 6 | shepherd.addElectrumCoin('KMD'); 7 | shepherd.addElectrumCoin('REVS'); 8 | shepherd.addElectrumCoin('JUMBLR'); 9 | } else { 10 | if (process.argv.indexOf('spvcoins=all/add-all') > -1) { 11 | for (let key in electrumServers) { 12 | shepherd.addElectrumCoin(electrumServers[key].abbr); 13 | } 14 | } else { 15 | shepherd.addElectrumCoin(coin); 16 | } 17 | } 18 | } 19 | 20 | shepherd.startKMDNative = (selection, isManual) => { 21 | if (isManual) { 22 | shepherd.kmdMainPassiveMode = true; 23 | } 24 | 25 | if (selection === 'KMD') { 26 | const herdData = { 27 | 'ac_name': 'komodod', 28 | 'ac_options': [ 29 | '-daemon=0', 30 | '-addnode=78.47.196.146', 31 | ], 32 | }; 33 | 34 | const options = { 35 | url: `http://127.0.0.1:${shepherd.appConfig.agamaPort}/shepherd/herd`, 36 | method: 'POST', 37 | headers: { 38 | 'Content-Type': 'application/json', 39 | }, 40 | body: JSON.stringify({ 41 | herd: 'komodod', 42 | options: herdData, 43 | token: shepherd.appSessionHash, 44 | }), 45 | }; 46 | 47 | shepherd.request(options, (error, response, body) => { 48 | if (response && 49 | response.statusCode && 50 | response.statusCode === 200) { 51 | //resolve(body); 52 | } else { 53 | //resolve(body); 54 | } 55 | }); 56 | } else if (selection === 'REVS') { 57 | const herdData = { 58 | 'ac_name': 'REVS', 59 | 'ac_options': [ 60 | '-daemon=0', 61 | '-server', 62 | `-ac_name=REVS`, 63 | '-addnode=78.47.196.146', 64 | '-ac_supply=1300000' 65 | ] 66 | }; 67 | 68 | const options = { 69 | url: `http://127.0.0.1:${shepherd.appConfig.agamaPort}/shepherd/herd`, 70 | method: 'POST', 71 | headers: { 72 | 'Content-Type': 'application/json', 73 | }, 74 | body: JSON.stringify({ 75 | herd: 'komodod', 76 | options: herdData, 77 | token: shepherd.appSessionHash, 78 | }), 79 | }; 80 | 81 | shepherd.request(options, (error, response, body) => { 82 | if (response && 83 | response.statusCode && 84 | response.statusCode === 200) { 85 | //resolve(body); 86 | } else { 87 | //resolve(body); 88 | } 89 | }); 90 | } else if (selection === 'JUMRLR') { 91 | const herdData = { 92 | 'ac_name': 'JUMRLR', 93 | 'ac_options': [ 94 | '-daemon=0', 95 | '-server', 96 | `-ac_name=JUMRLR`, 97 | '-addnode=78.47.196.146', 98 | '-ac_supply=999999' 99 | ] 100 | }; 101 | 102 | const options = { 103 | url: `http://127.0.0.1:${shepherd.appConfig.agamaPort}/shepherd/herd`, 104 | method: 'POST', 105 | headers: { 106 | 'Content-Type': 'application/json', 107 | }, 108 | body: JSON.stringify({ 109 | herd: 'komodod', 110 | options: herdData, 111 | token: shepherd.appSessionHash, 112 | }), 113 | }; 114 | 115 | shepherd.request(options, (error, response, body) => { 116 | if (response && 117 | response.statusCode && 118 | response.statusCode === 200) { 119 | //resolve(body); 120 | } else { 121 | //resolve(body); 122 | } 123 | }); 124 | } else if (selection === 'MNZ') { 125 | const herdData = { 126 | 'ac_name': 'MNZ', 127 | 'ac_options': [ 128 | '-daemon=0', 129 | '-server', 130 | `-ac_name=MNZ`, 131 | '-addnode=78.47.196.146', 132 | '-ac_supply=257142858' 133 | ] 134 | }; 135 | 136 | const options = { 137 | url: `http://127.0.0.1:${shepherd.appConfig.agamaPort}/shepherd/herd`, 138 | method: 'POST', 139 | headers: { 140 | 'Content-Type': 'application/json', 141 | }, 142 | body: JSON.stringify({ 143 | herd: 'komodod', 144 | options: herdData, 145 | token: shepherd.appSessionHash, 146 | }), 147 | }; 148 | 149 | shepherd.request(options, (error, response, body) => { 150 | if (response && 151 | response.statusCode && 152 | response.statusCode === 200) { 153 | //resolve(body); 154 | } else { 155 | //resolve(body); 156 | } 157 | }); 158 | } else if (selection === 'BTCH') { 159 | const herdData = { 160 | 'ac_name': 'BTCH', 161 | 'ac_options': [ 162 | '-daemon=0', 163 | '-server', 164 | `-ac_name=BTCH`, 165 | '-addnode=78.47.196.146', 166 | '-ac_supply=20998641' 167 | ] 168 | }; 169 | 170 | const options = { 171 | url: `http://127.0.0.1:${shepherd.appConfig.agamaPort}/shepherd/herd`, 172 | method: 'POST', 173 | headers: { 174 | 'Content-Type': 'application/json', 175 | }, 176 | body: JSON.stringify({ 177 | herd: 'komodod', 178 | options: herdData, 179 | token: shepherd.appSessionHash, 180 | }), 181 | }; 182 | 183 | shepherd.request(options, (error, response, body) => { 184 | if (response && 185 | response.statusCode && 186 | response.statusCode === 200) { 187 | //resolve(body); 188 | } else { 189 | //resolve(body); 190 | } 191 | }); 192 | } else { 193 | const herdData = [{ 194 | 'ac_name': 'komodod', 195 | 'ac_options': [ 196 | '-daemon=0', 197 | '-addnode=78.47.196.146', 198 | ] 199 | }, { 200 | 'ac_name': 'REVS', 201 | 'ac_options': [ 202 | '-daemon=0', 203 | '-server', 204 | `-ac_name=REVS`, 205 | '-addnode=78.47.196.146', 206 | '-ac_supply=1300000' 207 | ] 208 | }, { 209 | 'ac_name': 'JUMBLR', 210 | 'ac_options': [ 211 | '-daemon=0', 212 | '-server', 213 | `-ac_name=JUMBLR`, 214 | '-addnode=78.47.196.146', 215 | '-ac_supply=999999' 216 | ] 217 | }]; 218 | 219 | for (let i = 0; i < herdData.length; i++) { 220 | setTimeout(() => { 221 | const options = { 222 | url: `http://127.0.0.1:${shepherd.appConfig.agamaPort}/shepherd/herd`, 223 | method: 'POST', 224 | headers: { 225 | 'Content-Type': 'application/json', 226 | }, 227 | body: JSON.stringify({ 228 | herd: 'komodod', 229 | options: herdData[i], 230 | token: shepherd.appSessionHash, 231 | }), 232 | }; 233 | 234 | shepherd.request(options, (error, response, body) => { 235 | if (response && 236 | response.statusCode && 237 | response.statusCode === 200) { 238 | //resolve(body); 239 | } else { 240 | //resolve(body); 241 | } 242 | }); 243 | }, 100); 244 | } 245 | } 246 | }; 247 | 248 | return shepherd; 249 | }; -------------------------------------------------------------------------------- /routes/shepherd/appInfo.js: -------------------------------------------------------------------------------- 1 | const formatBytes = (bytes, decimals) => { 2 | if (bytes === 0) { 3 | return '0 Bytes'; 4 | } 5 | 6 | const k = 1000; 7 | const dm = (decimals + 1) || 3; 8 | const sizes = [ 9 | 'Bytes', 10 | 'KB', 11 | 'MB', 12 | 'GB', 13 | 'TB', 14 | 'PB', 15 | 'EB', 16 | 'ZB', 17 | 'YB' 18 | ]; 19 | const i = Math.floor(Math.log(bytes) / Math.log(k)); 20 | 21 | return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; 22 | } 23 | 24 | module.exports = (shepherd) => { 25 | shepherd.SystemInfo = () => { 26 | const os_data = { 27 | 'totalmem_bytes': shepherd.os.totalmem(), 28 | 'totalmem_readable': formatBytes(shepherd.os.totalmem()), 29 | 'arch': shepherd.os.arch(), 30 | 'cpu': shepherd.os.cpus()[0].model, 31 | 'cpu_cores': shepherd.os.cpus().length, 32 | 'platform': shepherd.os.platform(), 33 | 'os_release': shepherd.os.release(), 34 | 'os_type': shepherd.os.type(), 35 | }; 36 | 37 | return os_data; 38 | } 39 | 40 | shepherd.appInfo = () => { 41 | const sysInfo = shepherd.SystemInfo(); 42 | const releaseInfo = shepherd.appBasicInfo; 43 | const dirs = { 44 | agamaDir: shepherd.agamaDir, 45 | komodoDir: shepherd.komodoDir, 46 | komododBin: shepherd.komododBin, 47 | configLocation: `${shepherd.agamaDir}/config.json`, 48 | cacheLocation: `${shepherd.agamaDir}/shepherd`, 49 | }; 50 | 51 | return { 52 | sysInfo, 53 | releaseInfo, 54 | dirs, 55 | }; 56 | } 57 | 58 | /* 59 | * type: GET 60 | * 61 | */ 62 | shepherd.get('/sysinfo', (req, res, next) => { 63 | if (shepherd.checkToken(req.query.token)) { 64 | const obj = shepherd.SystemInfo(); 65 | res.send(obj); 66 | } else { 67 | const errorObj = { 68 | msg: 'error', 69 | result: 'unauthorized access', 70 | }; 71 | 72 | res.end(JSON.stringify(errorObj)); 73 | } 74 | }); 75 | 76 | /* 77 | * type: GET 78 | * 79 | */ 80 | shepherd.get('/appinfo', (req, res, next) => { 81 | if (shepherd.checkToken(req.query.token)) { 82 | const obj = shepherd.appInfo(); 83 | res.send(obj); 84 | } else { 85 | const errorObj = { 86 | msg: 'error', 87 | result: 'unauthorized access', 88 | }; 89 | 90 | res.end(JSON.stringify(errorObj)); 91 | } 92 | }); 93 | 94 | return shepherd; 95 | }; -------------------------------------------------------------------------------- /routes/shepherd/auth.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | /* 3 | * type: GET 4 | * 5 | */ 6 | shepherd.get('/auth/status', (req, res, next) => { 7 | if (shepherd.checkToken(req.query.token)) { 8 | let successObj; 9 | let _status = false; 10 | 11 | if (Object.keys(shepherd.coindInstanceRegistry).length) { 12 | if (Object.keys(shepherd.electrumCoins).length > 1 && 13 | shepherd.electrumCoins.auth) { 14 | _status = true; 15 | } else if (Object.keys(shepherd.electrumCoins).length === 1 && !shepherd.electrumCoins.auth) { 16 | _status = true; 17 | } 18 | } else if (Object.keys(shepherd.electrumCoins).length > 1 && shepherd.electrumCoins.auth) { 19 | _status = true; 20 | } else if (Object.keys(shepherd.electrumCoins).length === 1 && !Object.keys(shepherd.coindInstanceRegistry).length) { 21 | _status = true; 22 | } 23 | 24 | successObj = { 25 | status: _status ? 'unlocked' : 'locked', 26 | }; 27 | 28 | res.end(JSON.stringify(successObj)); 29 | } else { 30 | const errorObj = { 31 | msg: 'error', 32 | result: 'unauthorized access', 33 | }; 34 | 35 | res.end(JSON.stringify(errorObj)); 36 | } 37 | }); 38 | 39 | shepherd.checkToken = (token) => { 40 | if (token === shepherd.appSessionHash || 41 | process.argv.indexOf('devmode') > -1) { 42 | return true; 43 | } 44 | }; 45 | 46 | return shepherd; 47 | }; -------------------------------------------------------------------------------- /routes/shepherd/binsUtils.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | // osx and linux 3 | shepherd.binFixRights = () => { 4 | const osPlatform = shepherd.os.platform(); 5 | const _bins = [ 6 | shepherd.komododBin, 7 | shepherd.komodocliBin 8 | ]; 9 | 10 | if (osPlatform === 'darwin' || 11 | osPlatform === 'linux') { 12 | for (let i = 0; i < _bins.length; i++) { 13 | shepherd._fs.stat(_bins[i], (err, stat) => { 14 | if (!err) { 15 | if (parseInt(stat.mode.toString(8), 10) !== 100775) { 16 | shepherd.log(`${_bins[i]} fix permissions`); 17 | shepherd.fsnode.chmodSync(_bins[i], '0775'); 18 | } 19 | } else { 20 | shepherd.log(`error: ${_bins[i]} not found`); 21 | } 22 | }); 23 | } 24 | } 25 | } 26 | 27 | shepherd.killRogueProcess = (processName) => { 28 | // kill rogue process copies on start 29 | let processGrep; 30 | const osPlatform = shepherd.os.platform(); 31 | 32 | switch (osPlatform) { 33 | case 'darwin': 34 | processGrep = "ps -p $(ps -A | grep -m1 " + processName + " | awk '{print $1}') | grep -i " + processName; 35 | break; 36 | case 'linux': 37 | processGrep = 'ps -p $(pidof ' + processName + ') | grep -i ' + processName; 38 | break; 39 | case 'win32': 40 | processGrep = 'tasklist'; 41 | break; 42 | } 43 | 44 | shepherd.exec(processGrep, (error, stdout, stderr) => { 45 | if (stdout.indexOf(processName) > -1) { 46 | const pkillCmd = osPlatform === 'win32' ? `taskkill /f /im ${processName}.exe` : `pkill -15 ${processName}`; 47 | 48 | shepherd.log(`found another ${processName} process(es)`); 49 | shepherd.writeLog(`found another ${processName} process(es)`); 50 | 51 | shepherd.exec(pkillCmd, (error, stdout, stderr) => { 52 | shepherd.log(`${pkillCmd} is issued`); 53 | shepherd.writeLog(`${pkillCmd} is issued`); 54 | 55 | if (error !== null) { 56 | shepherd.log(`${pkillCmd} exec error: ${error}`); 57 | shepherd.writeLog(`${pkillCmd} exec error: ${error}`); 58 | }; 59 | }); 60 | } 61 | 62 | if (error !== null) { 63 | shepherd.log(`${processGrep} exec error: ${error}`); 64 | shepherd.writeLog(`${processGrep} exec error: ${error}`); 65 | }; 66 | }); 67 | } 68 | 69 | return shepherd; 70 | }; -------------------------------------------------------------------------------- /routes/shepherd/coindWalletKeys.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | /* 3 | * type: GET 4 | * 5 | */ 6 | shepherd.get('/coindwalletkeys', (req, res, next) => { 7 | if (shepherd.checkToken(req.query.token)) { 8 | const wif = require('wif'); 9 | const fs = require('fs'); 10 | const chain = req.query.chain; 11 | 12 | // ref: https://gist.github.com/kendricktan/1e62495150ad236b38616d733aac4eb9 13 | let _walletDatLocation = chain === 'komodo' || chain === 'null' ? `${shepherd.komodoDir}/wallet.dat` : `${shepherd.komodoDir}/${chain}/wallet.dat`; 14 | _walletDatLocation = chain === 'CHIPS' ? `${shepherd.chipsDir}/wallet.dat` : _walletDatLocation; 15 | 16 | try { 17 | shepherd._fs.access(_walletDatLocation, shepherd.fs.constants.R_OK, (err) => { 18 | if (err) { 19 | shepherd.log(`error reading ${_walletDatLocation}`); 20 | successObj = { 21 | msg: 'error', 22 | result: `error reading ${_walletDatLocation}`, 23 | }; 24 | 25 | res.end(JSON.stringify(successObj)); 26 | } else { 27 | shepherd.log(`reading ${_walletDatLocation}`); 28 | fs.readFile(_walletDatLocation, (err, data) => { 29 | if (err) { 30 | shepherd.log(`read wallet.dat err: ${err}`); 31 | successObj = { 32 | msg: 'error', 33 | result: `error reading ${_walletDatLocation}`, 34 | }; 35 | 36 | res.end(JSON.stringify(successObj)); 37 | } else { 38 | const re = /\x30\x81\xD3\x02\x01\x01\x04\x20(.{32})/gm; 39 | const dataHexStr = data.toString('latin1'); 40 | privateKeys = dataHexStr.match(re); 41 | 42 | if (!privateKeys) { 43 | shepherd.log('wallet is encrypted?'); 44 | 45 | successObj = { 46 | msg: 'error', 47 | result: 'wallet is encrypted?', 48 | }; 49 | 50 | res.end(JSON.stringify(successObj)); 51 | } else { 52 | let _keys = []; 53 | privateKeys = privateKeys.map(x => x.replace('\x30\x81\xD3\x02\x01\x01\x04\x20', '')); 54 | privateKeys = privateKeys.filter((v, i, a) => a.indexOf(v) === i); 55 | shepherd.log(`found ${privateKeys.length} keys`); 56 | 57 | for (let i = 0; i < privateKeys.length; i++) { 58 | const privateKey = new Buffer(Buffer.from(privateKeys[i], 'latin1').toString('hex'), 'hex'); 59 | const key = wif.encode(0xbc, privateKey, true); 60 | const keyObj = wif.decode(key); 61 | const wifKey = wif.encode(keyObj); 62 | 63 | const keyPair = shepherd.bitcoinJS.ECPair.fromWIF(wifKey, shepherd.electrumJSNetworks.komodo); 64 | const _keyPair = { 65 | priv: keyPair.toWIF(), 66 | pub: keyPair.getAddress(), 67 | }; 68 | 69 | if (req.query.search) { 70 | if (_keyPair.pub.indexOf(req.query.search) > -1) { 71 | _keys.push(_keyPair); 72 | } 73 | } else { 74 | _keys.push(_keyPair); 75 | } 76 | } 77 | 78 | successObj = { 79 | msg: 'success', 80 | result: _keys, 81 | }; 82 | 83 | res.end(JSON.stringify(successObj)); 84 | } 85 | } 86 | }); 87 | } 88 | }); 89 | } catch (e) { 90 | successObj = { 91 | msg: 'error', 92 | result: `error reading ${_walletDatLocation}`, 93 | }; 94 | 95 | res.end(JSON.stringify(successObj)); 96 | } 97 | } else { 98 | const errorObj = { 99 | msg: 'error', 100 | result: 'unauthorized access', 101 | }; 102 | 103 | res.end(JSON.stringify(errorObj)); 104 | } 105 | }); 106 | 107 | return shepherd; 108 | }; -------------------------------------------------------------------------------- /routes/shepherd/coins.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | /* 3 | * type: GET 4 | * 5 | */ 6 | shepherd.get('/InstantDEX/allcoins', (req, res, next) => { 7 | if (shepherd.checkToken(req.query.token)) { 8 | let successObj; 9 | let nativeCoindList = []; 10 | let electrumCoinsList = []; 11 | 12 | for (let key in shepherd.electrumCoins) { 13 | if (key !== 'auth') { 14 | electrumCoinsList.push(shepherd.electrumCoins[key].abbr); 15 | } 16 | } 17 | 18 | for (let key in shepherd.coindInstanceRegistry) { 19 | nativeCoindList.push(key === 'komodod' ? 'KMD' : key); 20 | } 21 | 22 | successObj = { 23 | native: nativeCoindList, 24 | spv: electrumCoinsList, 25 | total: Object.keys(shepherd.electrumCoins).length - 1 + Object.keys(nativeCoindList).length, 26 | }; 27 | 28 | res.end(JSON.stringify(successObj)); 29 | } else { 30 | const errorObj = { 31 | msg: 'error', 32 | result: 'unauthorized access', 33 | }; 34 | 35 | res.end(JSON.stringify(errorObj)); 36 | } 37 | }); 38 | 39 | return shepherd; 40 | }; -------------------------------------------------------------------------------- /routes/shepherd/coinsList.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | /* 3 | * type: GET 4 | * 5 | */ 6 | shepherd.get('/coinslist', (req, res, next) => { 7 | if (shepherd.checkToken(req.query.token)) { 8 | if (shepherd.fs.existsSync(`${shepherd.agamaDir}/shepherd/coinslist.json`)) { 9 | shepherd.fs.readFile(`${shepherd.agamaDir}/shepherd/coinslist.json`, 'utf8', (err, data) => { 10 | if (err) { 11 | const errorObj = { 12 | msg: 'error', 13 | result: err, 14 | }; 15 | 16 | res.end(JSON.stringify(errorObj)); 17 | } else { 18 | const successObj = { 19 | msg: 'success', 20 | result: data ? JSON.parse(data) : '', 21 | }; 22 | 23 | res.end(JSON.stringify(successObj)); 24 | } 25 | }); 26 | } else { 27 | const errorObj = { 28 | msg: 'error', 29 | result: 'coin list doesn\'t exist', 30 | }; 31 | 32 | res.end(JSON.stringify(errorObj)); 33 | } 34 | } else { 35 | const errorObj = { 36 | msg: 'error', 37 | result: 'unauthorized access', 38 | }; 39 | 40 | res.end(JSON.stringify(errorObj)); 41 | } 42 | }); 43 | 44 | /* 45 | * type: POST 46 | * params: payload 47 | */ 48 | shepherd.post('/coinslist', (req, res, next) => { 49 | if (shepherd.checkToken(req.body.token)) { 50 | const _payload = req.body.payload; 51 | 52 | if (!_payload) { 53 | const errorObj = { 54 | msg: 'error', 55 | result: 'no payload provided', 56 | }; 57 | 58 | res.end(JSON.stringify(errorObj)); 59 | } else { 60 | shepherd.fs.writeFile(`${shepherd.agamaDir}/shepherd/coinslist.json`, JSON.stringify(_payload), (err) => { 61 | if (err) { 62 | const errorObj = { 63 | msg: 'error', 64 | result: err, 65 | }; 66 | 67 | res.end(JSON.stringify(errorObj)); 68 | } else { 69 | const successObj = { 70 | msg: 'success', 71 | result: 'done', 72 | }; 73 | 74 | res.end(JSON.stringify(successObj)); 75 | } 76 | }); 77 | } 78 | } else { 79 | const errorObj = { 80 | msg: 'error', 81 | result: 'unauthorized access', 82 | }; 83 | 84 | res.end(JSON.stringify(errorObj)); 85 | } 86 | }); 87 | 88 | return shepherd; 89 | }; -------------------------------------------------------------------------------- /routes/shepherd/confMaxconnections.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); 2 | 3 | module.exports = (shepherd) => { 4 | shepherd.getMaxconKMDConf = () => { 5 | return new shepherd.Promise((resolve, reject) => { 6 | fs.readFile(`${shepherd.komodoDir}/komodo.conf`, 'utf8', (err, data) => { 7 | if (err) { 8 | shepherd.log('kmd conf maxconnections param read failed'); 9 | resolve('unset'); 10 | } else { 11 | const _maxcon = data.match(/maxconnections=\s*(.*)/); 12 | 13 | if (!_maxcon) { 14 | shepherd.log('kmd conf maxconnections param is unset'); 15 | resolve(false); 16 | } else { 17 | shepherd.log(`kmd conf maxconnections param is already set to ${_maxcon[1]}`); 18 | resolve(_maxcon[1]); 19 | } 20 | } 21 | }); 22 | }); 23 | } 24 | 25 | shepherd.setMaxconKMDConf = (limit) => { 26 | return new shepherd.Promise((resolve, reject) => { 27 | fs.readFile(`${shepherd.komodoDir}/komodo.conf`, 'utf8', (err, data) => { 28 | const _maxconVal = limit ? 1 : 10; 29 | 30 | if (err) { 31 | shepherd.log(`error reading ${shepherd.komodoDir}/komodo.conf`); 32 | resolve(false); 33 | } else { 34 | if (data.indexOf('maxconnections=') > -1) { 35 | const _maxcon = data.match(/maxconnections=\s*(.*)/); 36 | 37 | data = data.replace(`maxconnections=${_maxcon[1]}`, `maxconnections=${_maxconVal}`); 38 | } else { 39 | data = `${data}\nmaxconnections=${_maxconVal}\n`; 40 | } 41 | 42 | fs.writeFile(`${shepherd.komodoDir}/komodo.conf`, data, (err) => { 43 | if (err) { 44 | shepherd.log(`error writing ${shepherd.komodoDir}/komodo.conf maxconnections=${_maxconVal}`); 45 | resolve(false); 46 | } else { 47 | shepherd.log(`kmd conf maxconnections is set to ${_maxconVal}`); 48 | resolve(true); 49 | } 50 | }); 51 | } 52 | }); 53 | }); 54 | } 55 | 56 | return shepherd; 57 | }; -------------------------------------------------------------------------------- /routes/shepherd/config.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | shepherd.loadLocalConfig = () => { 3 | if (shepherd.fs.existsSync(`${shepherd.agamaDir}/config.json`)) { 4 | let localAppConfig = shepherd.fs.readFileSync(`${shepherd.agamaDir}/config.json`, 'utf8'); 5 | 6 | shepherd.log('app config set from local file'); 7 | shepherd.writeLog('app config set from local file'); 8 | 9 | // find diff between local and hardcoded configs 10 | // append diff to local config 11 | const compareJSON = (obj1, obj2) => { 12 | let result = {}; 13 | 14 | for (let i in obj1) { 15 | if (!obj2.hasOwnProperty(i)) { 16 | result[i] = obj1[i]; 17 | } 18 | } 19 | 20 | return result; 21 | }; 22 | 23 | if (localAppConfig) { 24 | const compareConfigs = compareJSON(shepherd.appConfig, JSON.parse(localAppConfig)); 25 | 26 | if (Object.keys(compareConfigs).length) { 27 | const newConfig = Object.assign(JSON.parse(localAppConfig), compareConfigs); 28 | 29 | shepherd.log('config diff is found, updating local config'); 30 | shepherd.log('config diff:'); 31 | shepherd.log(compareConfigs); 32 | shepherd.writeLog('aconfig diff is found, updating local config'); 33 | shepherd.writeLog('config diff:'); 34 | shepherd.writeLog(compareConfigs); 35 | 36 | shepherd.saveLocalAppConf(newConfig); 37 | return newConfig; 38 | } else { 39 | return JSON.parse(localAppConfig); 40 | } 41 | } else { 42 | return shepherd.appConfig; 43 | } 44 | } else { 45 | shepherd.log('local config file is not found!'); 46 | shepherd.writeLog('local config file is not found!'); 47 | shepherd.saveLocalAppConf(shepherd.appConfig); 48 | 49 | return shepherd.appConfig; 50 | } 51 | }; 52 | 53 | shepherd.saveLocalAppConf = (appSettings) => { 54 | let appConfFileName = `${shepherd.agamaDir}/config.json`; 55 | 56 | shepherd._fs.access(shepherd.agamaDir, shepherd.fs.constants.R_OK, (err) => { 57 | if (!err) { 58 | 59 | const FixFilePermissions = () => { 60 | return new shepherd.Promise((resolve, reject) => { 61 | const result = 'config.json file permissions updated to Read/Write'; 62 | 63 | shepherd.fsnode.chmodSync(appConfFileName, '0666'); 64 | 65 | setTimeout(() => { 66 | shepherd.log(result); 67 | shepherd.writeLog(result); 68 | resolve(result); 69 | }, 1000); 70 | }); 71 | } 72 | 73 | const FsWrite = () => { 74 | return new shepherd.Promise((resolve, reject) => { 75 | const result = 'config.json write file is done'; 76 | 77 | shepherd.fs.writeFile(appConfFileName, 78 | JSON.stringify(appSettings) 79 | .replace(/,/g, ',\n') // format json in human readable form 80 | .replace(/":/g, '": ') 81 | .replace(/{/g, '{\n') 82 | .replace(/}/g, '\n}'), 'utf8', (err) => { 83 | if (err) 84 | return shepherd.log(err); 85 | }); 86 | 87 | shepherd.fsnode.chmodSync(appConfFileName, '0666'); 88 | setTimeout(() => { 89 | shepherd.log(result); 90 | shepherd.log(`app conf.json file is created successfully at: ${shepherd.agamaDir}`); 91 | shepherd.writeLog(`app conf.json file is created successfully at: ${shepherd.agamaDir}`); 92 | resolve(result); 93 | }, 2000); 94 | }); 95 | } 96 | 97 | FsWrite() 98 | .then(FixFilePermissions()); 99 | } 100 | }); 101 | } 102 | 103 | /* 104 | * type: POST 105 | * params: payload 106 | */ 107 | shepherd.post('/appconf', (req, res, next) => { 108 | if (shepherd.checkToken(req.body.token)) { 109 | if (!req.body.payload) { 110 | const errorObj = { 111 | msg: 'error', 112 | result: 'no payload provided', 113 | }; 114 | 115 | res.end(JSON.stringify(errorObj)); 116 | } else { 117 | shepherd.saveLocalAppConf(req.body.payload); 118 | 119 | const successObj = { 120 | msg: 'success', 121 | result: 'config saved', 122 | }; 123 | 124 | res.end(JSON.stringify(successObj)); 125 | } 126 | } else { 127 | const errorObj = { 128 | msg: 'error', 129 | result: 'unauthorized access', 130 | }; 131 | 132 | res.end(JSON.stringify(errorObj)); 133 | } 134 | }); 135 | 136 | /* 137 | * type: POST 138 | * params: none 139 | */ 140 | shepherd.post('/appconf/reset', (req, res, next) => { 141 | if (shepherd.checkToken(req.body.token)) { 142 | shepherd.saveLocalAppConf(shepherd.defaultAppConfig); 143 | 144 | const successObj = { 145 | msg: 'success', 146 | result: 'config saved', 147 | }; 148 | 149 | res.end(JSON.stringify(successObj)); 150 | } else { 151 | const errorObj = { 152 | msg: 'error', 153 | result: 'unauthorized access', 154 | }; 155 | 156 | res.end(JSON.stringify(errorObj)); 157 | } 158 | }); 159 | 160 | /* 161 | * type: GET 162 | * 163 | */ 164 | shepherd.get('/appconf', (req, res, next) => { 165 | if (shepherd.checkToken(req.query.token)) { 166 | const obj = shepherd.loadLocalConfig(); 167 | res.send(obj); 168 | } else { 169 | const errorObj = { 170 | msg: 'error', 171 | result: 'unauthorized access', 172 | }; 173 | 174 | res.end(JSON.stringify(errorObj)); 175 | } 176 | }); 177 | 178 | return shepherd; 179 | }; -------------------------------------------------------------------------------- /routes/shepherd/debugLog.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | /* 3 | * type: POST 4 | * params: herd, lastLines 5 | */ 6 | shepherd.post('/debuglog', (req, res) => { 7 | if (shepherd.checkToken(req.body.token)) { 8 | let _herd = req.body.herdname; 9 | let _ac = req.body.ac; 10 | let _lastNLines = req.body.lastLines; 11 | let _location; 12 | 13 | if (shepherd.os.platform() === 'darwin') { 14 | shepherd.komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.HOME}/Library/Application Support/Komodo`; 15 | } 16 | 17 | if (shepherd.os.platform() === 'linux') { 18 | shepherd.komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.HOME}/.komodo`; 19 | } 20 | 21 | if (shepherd.os.platform() === 'win32') { 22 | shepherd.komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.APPDATA}/Komodo`; 23 | shepherd.komodoDir = shepherd.path.normalize(shepherd.komodoDir); 24 | } 25 | 26 | if (_herd === 'komodo') { 27 | _location = shepherd.komodoDir; 28 | } 29 | 30 | if (_ac) { 31 | _location = `${shepherd.komodoDir}/${_ac}`; 32 | 33 | if (_ac === 'CHIPS') { 34 | _location = shepherd.chipsDir; 35 | } 36 | } 37 | 38 | shepherd.readDebugLog(`${_location}/debug.log`, _lastNLines) 39 | .then((result) => { 40 | const _obj = { 41 | msg: 'success', 42 | result: result, 43 | }; 44 | 45 | res.end(JSON.stringify(_obj)); 46 | }, (result) => { 47 | const _obj = { 48 | msg: 'error', 49 | result: result, 50 | }; 51 | 52 | res.end(JSON.stringify(_obj)); 53 | }); 54 | } else { 55 | const errorObj = { 56 | msg: 'error', 57 | result: 'unauthorized access', 58 | }; 59 | 60 | res.end(JSON.stringify(errorObj)); 61 | } 62 | }); 63 | 64 | shepherd.get('/coind/stdout', (req, res) => { 65 | if (shepherd.checkToken(req.query.token)) { 66 | const _daemonName = req.query.chain !== 'komodod' ? req.query.chain : 'komodod'; 67 | const _daemonLogName = `${shepherd.agamaDir}/${_daemonName}.log`; 68 | 69 | shepherd.readDebugLog(_daemonLogName, 'all') 70 | .then((result) => { 71 | const _obj = { 72 | msg: 'success', 73 | result: result, 74 | }; 75 | 76 | res.end(JSON.stringify(_obj)); 77 | }, (result) => { 78 | const _obj = { 79 | msg: 'error', 80 | result: result, 81 | }; 82 | 83 | res.end(JSON.stringify(_obj)); 84 | }); 85 | } else { 86 | const errorObj = { 87 | msg: 'error', 88 | result: 'unauthorized access', 89 | }; 90 | 91 | res.end(JSON.stringify(errorObj)); 92 | } 93 | }); 94 | 95 | shepherd.readDebugLog = (fileLocation, lastNLines) => { 96 | return new shepherd.Promise( 97 | (resolve, reject) => { 98 | if (lastNLines) { 99 | try { 100 | shepherd._fs.access(fileLocation, shepherd.fs.constants.R_OK, (err) => { 101 | if (err) { 102 | shepherd.log(`error reading ${fileLocation}`); 103 | shepherd.writeLog(`error reading ${fileLocation}`); 104 | reject(`readDebugLog error: ${err}`); 105 | } else { 106 | shepherd.log(`reading ${fileLocation}`); 107 | shepherd._fs.readFile(fileLocation, 'utf-8', (err, data) => { 108 | if (err) { 109 | shepherd.writeLog(`readDebugLog err: ${err}`); 110 | shepherd.log(`readDebugLog err: ${err}`); 111 | } 112 | 113 | const lines = data.trim().split('\n'); 114 | let lastLine; 115 | 116 | if (lastNLines === 'all') { 117 | lastLine = data.trim(); 118 | } else { 119 | lastLine = lines.slice(lines.length - lastNLines, lines.length).join('\n'); 120 | } 121 | 122 | resolve(lastLine); 123 | }); 124 | } 125 | }); 126 | } catch (e) { 127 | reject(`readDebugLog error: ${e}`); 128 | } 129 | } else { 130 | reject('readDebugLog error: lastNLines param is not provided!'); 131 | } 132 | } 133 | ); 134 | }; 135 | 136 | return shepherd; 137 | }; -------------------------------------------------------------------------------- /routes/shepherd/dex/coind.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | /* 3 | * list native coind 4 | * type: 5 | * params: 6 | */ 7 | shepherd.get('/coind/list', (req, res, next) => { 8 | const successObj = { 9 | msg: 'success', 10 | result: shepherd.nativeCoindList, 11 | }; 12 | 13 | res.end(JSON.stringify(successObj)); 14 | }); 15 | 16 | shepherd.scanNativeCoindBins = () => { 17 | let nativeCoindList = {}; 18 | 19 | // check if coind bins are present in agama 20 | for (let key in shepherd.nativeCoind) { 21 | nativeCoindList[key] = { 22 | name: shepherd.nativeCoind[key].name, 23 | port: shepherd.nativeCoind[key].port, 24 | bin: shepherd.nativeCoind[key].bin, 25 | bins: { 26 | daemon: false, 27 | cli: false, 28 | }, 29 | }; 30 | 31 | if (shepherd.fs.existsSync(`${shepherd.coindRootDir}/${key}/${shepherd.nativeCoind[key].bin}d${shepherd.os.platform() === 'win32' ? '.exe' : ''}`)) { 32 | nativeCoindList[key].bins.daemon = true; 33 | } 34 | 35 | if (shepherd.fs.existsSync(`${shepherd.coindRootDir}/${key}/${shepherd.nativeCoind[key].bin}-cli${shepherd.os.platform() === 'win32' ? '.exe' : ''}`)) { 36 | nativeCoindList[key].bins.cli = true; 37 | } 38 | } 39 | 40 | return nativeCoindList; 41 | } 42 | 43 | return shepherd; 44 | }; -------------------------------------------------------------------------------- /routes/shepherd/dex/coins.json: -------------------------------------------------------------------------------- 1 | [{"coin":"MNZ","asset":"MNZ","rpcport":14337},{"coin":"BTCZ","name":"bitcoinz","rpcport":1979,"taddr":28,"pubtype":184,"p2shtype":189,"wiftype":128,"txfee":10000}, {"coin":"MAGA","name":"magacoin","rpcport":5332,"pubtype":23,"p2shtype":50,"wiftype":176,"txfee":100000}, {"coin":"BLK","name":"blackcoin","rpcport":15715,"pubtype":25,"p2shtype":85,"wiftype":153,"txfee":10000}, {"coin":"ZEN","name":"zen","rpcport":8231,"pubtype":137,"taddr":32,"p2shtype":150,"wiftype":128,"txfee":10000},{"coin":"BSD","name":"bitsend","rpcport":8800,"pubtype":102,"p2shtype":5,"wiftype":204,"txfee":10000}, {"coin":"IOP","name":"IoP","rpcport":8337,"pubtype":117,"p2shtype":174,"wiftype":49,"txfee":10000}, {"coin":"BLOCK","name":"blocknetdx","rpcport":41414,"pubtype":26,"p2shtype":28,"wiftype":154,"txfee":10000}, {"coin":"CHIPS", "name": "chips", "rpcport":57776,"pubtype":60, "p2shtype":85, "wiftype":188, "txfee":10000},{"coin":"888","name":"octocoin","rpcport":22888,"pubtype":18,"p2shtype":5,"wiftype":176,"txfee":2000000}, {"coin":"ARG","name":"argentum","rpcport":13581,"pubtype":23,"p2shtype":5,"wiftype":151,"txfee":50000}, {"coin":"GLT","name":"globaltoken","rpcport":9320,"pubtype":38,"p2shtype":5,"wiftype":166,"txfee":10000}, {"coin":"ZER","name":"zero","rpcport":23801,"taddr":28,"pubtype":184,"p2shtype":189,"wiftype":128,"txfee":1000}, {"coin":"HODLC","name":"hodlcoin","rpcport":11989,"pubtype":40,"p2shtype":5,"wiftype":168,"txfee":5000}, {"coin":"UIS","name":"unitus","rpcport":50604,"pubtype":68,"p2shtype":10,"wiftype":132,"txfee":1000000}, {"coin":"CRW","name":"crown","rpcport":9341,"pubtype":0,"p2shtype":5,"wiftype":128,"txfee":10000}, {"coin":"HUC","name":"huntercoin","rpcport":8399,"pubtype":40,"p2shtype":13,"wiftype":168,"txfee":100000}, {"coin":"PIVX","name":"pivx","rpcport":51473,"pubtype":30,"p2shtype":13,"wiftype":212,"txfee":10000}, {"coin":"BDL","name":"bitdeal","rpcport":9332,"pubtype":38,"p2shtype":5,"wiftype":176,"txfee":100000}, {"coin":"ARC","name":"arcticcoin","confpath":"`${process.env.HOME}`/.arcticcore/arcticcoin.conf","rpcport":7208,"pubtype":23,"p2shtype":8,"wiftype":176,"txfee":10000}, {"coin":"ZCL","name":"zclassic","rpcport":8023,"taddr":28,"pubtype":184,"p2shtype":189,"wiftype":128,"txfee":1000}, {"coin":"VIA","name":"viacoin","rpcport":5222,"pubtype":71,"p2shtype":33,"wiftype":199,"txfee":100000}, {"coin":"ERC","name":"europecoin","rpcport":11989,"pubtype":33,"p2shtype":5,"wiftype":168,"txfee":10000},{"coin":"FAIR","name":"faircoin","confpath":"`${process.env.HOME}`/.faircoin2/faircoin.conf","rpcport":40405,"pubtype":95,"p2shtype":36,"wiftype":223,"txfee":1000000}, {"coin":"FLO","name":"florincoin","rpcport":7313,"pubtype":35,"p2shtype":8,"wiftype":176,"txfee":100000}, {"coin":"SXC","name":"sexcoin","rpcport":9561,"pubtype":62,"p2shtype":5,"wiftype":190,"txfee":100000}, {"coin":"CREA","name":"creativecoin","rpcport":17711,"pubtype":28,"p2shtype":5,"wiftype":176,"txfee":100000}, {"coin":"TRC","name":"terracoin","rpcport":13332,"pubtype":0,"p2shtype":5,"wiftype":128,"txfee":1000}, {"coin":"BTA","name":"bata","rpcport":5493,"pubtype":25,"p2shtype":5,"wiftype":188,"txfee":100000}, {"coin":"SMC","name":"smartcoin","rpcport":58583,"pubtype":63,"p2shtype":5,"wiftype":191,"txfee":1000000}, {"coin":"NMC","name":"namecoin","rpcport":8336,"pubtype":52,"p2shtype":13,"wiftype":180,"txfee":100000}, {"coin":"NAV","name":"navcoin","isPoS":1,"confpath":"`${process.env.HOME}`/.navcoin4/navcoin.conf","rpcport":44444,"pubtype":53,"p2shtype":85,"wiftype":150,"txfee":10000}, {"coin":"MOON","name":"Mooncoin","rpcport":44663,"pubtype":3,"p2shtype":22,"wiftype":131,"txfee":100000}, {"coin":"EMC2","name":"einsteinium","rpcport":41879,"pubtype":33,"p2shtype":5,"wiftype":176,"txfee":100000},{"coin":"SYS","name":"syscoin","rpcport":8370,"pubtype":0,"p2shtype":5,"wiftype":128,"txfee":1000}, {"coin":"I0C","name":"i0coin","rpcport":7332,"pubtype":105,"p2shtype":5,"wiftype":128,"txfee":1000}, {"coin":"DASH","confpath":"`${process.env.HOME}`/.dashcore/dash.conf","name":"dashcore","rpcport":9998,"pubtype":76,"p2shtype":16,"wiftype":204,"txfee":10000}, {"coin":"STRAT", "name": "stratis", "active":0, "rpcport":16174,"pubtype":63, "p2shtype":125, "wiftype":191, "txfee":10000}, {"confpath":"`${process.env.HOME}`/.muecore/mue.conf","coin":"MUE","name":"muecore","rpcport":29683,"pubtype":16,"p2shtype":76,"wiftype":126,"txfee":10000}, {"coin":"MONA","name":"monacoin","rpcport":9402,"pubtype":50,"p2shtype":5,"wiftype":176,"txfee":100000},{"coin":"XMY","name":"myriadcoin","rpcport":10889,"pubtype":50,"p2shtype":9,"wiftype":178,"txfee":5000}, {"coin":"MAC","name":"machinecoin","rpcport":40332,"pubtype":50,"p2shtype":5,"wiftype":178,"txfee":50000}, {"coin":"BTX","name":"bitcore","rpcport":8556,"pubtype":0,"p2shtype":5,"wiftype":128,"txfee":50000}, {"coin":"XRE","name":"revolvercoin","rpcport":8775,"pubtype":0,"p2shtype":5,"wiftype":128,"txfee":1000}, {"coin":"LBC","name":"lbrycrd","rpcport":9245,"pubtype":85,"p2shtype":122,"wiftype":28,"txfee":1000}, {"coin":"SIB","name":"sibcoin","rpcport":1944,"pubtype":63,"p2shtype":40,"wiftype":128,"txfee":10000}, {"coin":"VTC", "name":"vertcoin", "rpcport":5888, "pubtype":71, "p2shtype":5, "wiftype":128, "txfee":100000 }, {"coin":"REVS","active":0, "asset":"REVS","rpcport":10196}, {"coin":"JUMBLR","active":0, "asset":"JUMBLR","rpcport":15106}, {"coin":"DOGE","name":"dogecoin","rpcport":22555,"pubtype":30,"p2shtype":22,"wiftype":158,"txfee":100000000}, {"coin":"HUSH","name":"hush","rpcport":8822,"taddr":28,"pubtype":184,"p2shtype":189,"wiftype":128,"txfee":1000 }, {"active":0,"coin":"ZEC","name":"zcash","rpcport":8232,"taddr":28,"pubtype":184,"p2shtype":189,"wiftype":128,"txfee":10000 }, {"coin":"DGB","name":"digibyte","rpcport":14022,"pubtype":30,"p2shtype":5,"wiftype":128,"txfee":100000}, {"coin":"MZC", "name":"mazacoin", "pubtype":50, "p2shtype":9, "wiftype":224, "txfee":10000}, {"coin":"UNO", "name":"unobtanium", "pubtype":130, "p2shtype":30, "wiftype":224, "txfee":1000000}, {"coin":"ZET", "name":"zetacoin", "pubtype":80, "p2shtype":9,"rpcport":8332, "wiftype":224, "txfee":10000}, {"coin":"BTM", "name":"bitmark", "pubtype":85, "p2shtype":5, "wiftype":213, "txfee":10000}, {"coin":"CARB", "name":"carboncoin", "pubtype":47, "p2shtype":5, "wiftype":175, "txfee":10000}, {"coin":"ANC", "name":"anoncoin", "pubtype":23, "p2shtype":5, "wiftype":151, "txfee":2000000}, {"coin":"FRK", "name":"franko", "pubtype":35, "p2shtype":5, "wiftype":163, "txfee":10000}, {"coin":"GAME", "rpcport":40001, "name":"gamecredits", "pubtype":38, "p2shtype":5, "wiftype":166, "txfee":100000}, {"coin":"LTC", "name":"litecoin", "rpcport":9332, "pubtype":48, "p2shtype":5, "wiftype":176, "txfee":100000 }, {"coin":"SUPERNET","asset":"SUPERNET","rpcport":11341}, {"coin":"WLC","asset":"WLC","rpcport":12167}, {"coin":"PANGEA","asset":"PANGEA","rpcport":14068}, {"coin":"DEX","asset":"DEX","rpcport":11890}, {"coin":"BET","asset":"BET","rpcport":14250}, {"coin":"CRYPTO","asset":"CRYPTO","rpcport":8516}, {"coin":"HODL","asset":"HODL","rpcport":14431}, {"coin":"SHARK","asset":"SHARK","rpcport":10114}, {"coin":"BOTS","asset":"BOTS","rpcport":11964}, {"coin":"MGW","asset":"MGW","rpcport":12386}, {"coin":"COQUI","asset":"COQUI","rpcport":14276}, {"coin":"KV","asset":"KV","rpcport":8299}, {"coin":"CEAL","asset":"CEAL","rpcport":11116}, {"coin":"MESH","asset":"MESH","rpcport":9455}] -------------------------------------------------------------------------------- /routes/shepherd/dex/electrumServersList.js: -------------------------------------------------------------------------------- 1 | // TODO: merge with spv mode 2 | 3 | const electrumServersList = { 4 | "ARG": [{"173.212.225.176": 50081},{"136.243.45.140": 50081}], 5 | "BET": [{"electrum2.cipig.net":10012},{"electrum1.cipig.net":10012}], 6 | "BTC": [{"electrum2.cipig.net":10000},{"electrum1.cipig.net":10000}], 7 | "BOTS": [{"electrum2.cipig.net":10007},{"electrum1.cipig.net":10007}], 8 | "CHIPS": [{"173.212.225.176": 50076},{"136.243.45.140": 50076}], 9 | "COQUI": [{"electrum2.cipig.net":10011},{"electrum1.cipig.net":10011}], 10 | "CRW": [{"173.212.225.176": 50041},{"136.243.45.140": 50041}], 11 | "CRYPTO": [{"electrum2.cipig.net":10008},{"electrum1.cipig.net":10008}], 12 | "DASH": [{"173.212.225.176": 50098},{"136.243.45.140": 50098}], 13 | "DEX": [{"electrum2.cipig.net":10006},{"electrum1.cipig.net":10006}], 14 | "DGB": [{"136.243.45.140": 50022},{"173.212.225.176": 50022}], 15 | "DOGE": [{"173.212.225.176": 50015},{"136.243.45.140": 50015}], 16 | "EMC2": [{"173.212.225.176": 50079},{"136.243.45.140": 50079}], 17 | "FAIR": [{"173.212.225.176": 50005},{"136.243.45.140": 50005}], 18 | "HODL": [{"electrum2.cipig.net":10009},{"electrum1.cipig.net":10009}], 19 | "HUSH": [{"173.212.225.176": 50013},{"136.243.45.140": 50013}], 20 | "JUMBLR": [{"electrum2.cipig.net": 10004},{"electrum1.cipig.net": 10004}], 21 | "KMD": [{"electrum2.cipig.net":10001},{"electrum1.cipig.net":10001}], 22 | "LTC": [{"173.212.225.176": 50012},{"136.243.45.140": 50012}], 23 | "MNZ": [{"electrum2.cipig.net":10002},{"electrum1.cipig.net":10002}], 24 | "MONA": [{"173.212.225.176": 50002},{"136.243.45.140": 50002}], 25 | "MSHARK": [{"electrum2.cipig.net": 10013},{"electrum1.cipig.net": 10013}], 26 | "NMC": [{"173.212.225.176": 50036},{"136.243.45.140": 50036}], 27 | "PANGEA": [{"electrum2.cipig.net": 10010},{"electrum1.cipig.net": 10010}], 28 | "REVS": [{"electrum2.cipig.net": 10003},{"electrum1.cipig.net": 10003}], 29 | "SUPERNET": [{"electrum2.cipig.net": 10005},{"electrum1.cipig.net": 10005}], 30 | "VIA": [{"173.212.225.176": 50033},{"136.243.45.140": 50033}], 31 | "VTC": [{"173.212.225.176": 50088},{"136.243.45.140": 50088}], 32 | "WLC": [{"electrum2.cipig.net": 10014},{"electrum1.cipig.net": 10014}], 33 | "ZEC": [{"173.212.225.176": 50032},{"136.243.45.140": 50032}] 34 | }; 35 | 36 | module.exports = (shepherd) => { 37 | shepherd.electrumServersList = electrumServersList; 38 | return shepherd; 39 | }; -------------------------------------------------------------------------------- /routes/shepherd/dex/mmRequest.js: -------------------------------------------------------------------------------- 1 | const request = require('request'); 2 | 3 | module.exports = (shepherd) => { 4 | // payload 5 | // record all calls 6 | shepherd.post('/mm/request', (req, res, next) => { 7 | let _payload = req.body.payload; 8 | _payload.userpass = shepherd.mmupass; 9 | const options = { 10 | url: `http://localhost:7783`, 11 | method: 'POST', 12 | body: JSON.stringify(_payload), 13 | }; 14 | 15 | shepherd.log(_payload); 16 | 17 | // send back body on both success and error 18 | // this bit replicates iguana core's behaviour 19 | request(options, (error, response, body) => { 20 | if (response && 21 | response.statusCode && 22 | response.statusCode === 200) { 23 | const _parsedBody = JSON.parse(body); 24 | shepherd.mmPublic[_payload.mapToProp] = _parsedBody; 25 | res.end(body); 26 | } else { 27 | res.end(body ? body : JSON.stringify({ 28 | result: 'error', 29 | error: { 30 | code: -777, 31 | message: `unable to call method ${_payload.method} at port 7783`, 32 | }, 33 | })); 34 | } 35 | }); 36 | }); 37 | 38 | return shepherd; 39 | }; -------------------------------------------------------------------------------- /routes/shepherd/downloadBins.js: -------------------------------------------------------------------------------- 1 | const remoteBinLocation = { 2 | win32: 'https://artifacts.supernet.org/latest/windows/', 3 | darwin: 'https://artifacts.supernet.org/latest/osx/', 4 | linux: 'https://artifacts.supernet.org/latest/linux/', 5 | }; 6 | const localBinLocation = { 7 | win32: 'assets/bin/win64/', 8 | darwin: 'assets/bin/osx/', 9 | linux: 'assets/bin/linux64/', 10 | }; 11 | const latestBins = { 12 | win32: [ 13 | 'komodo-cli.exe', 14 | 'komodod.exe', 15 | 'libcrypto-1_1.dll', 16 | 'libcurl-4.dll', 17 | 'libcurl.dll', 18 | 'libgcc_s_sjlj-1.dll', 19 | 'libnanomsg.dll', 20 | 'libssl-1_1.dll', 21 | 'libwinpthread-1.dll', 22 | 'nanomsg.dll', 23 | 'pthreadvc2.dll', 24 | ], 25 | darwin: [ 26 | 'komodo-cli', 27 | 'komodod', 28 | 'libgcc_s.1.dylib', 29 | 'libgomp.1.dylib', 30 | 'libnanomsg.5.0.0.dylib', 31 | 'libstdc++.6.dylib', // encode %2B 32 | ], 33 | linux: [ 34 | 'komodo-cli', 35 | 'komodod', 36 | ], 37 | }; 38 | 39 | let binsToUpdate = []; 40 | 41 | module.exports = (shepherd) => { 42 | /* 43 | * Check bins file size 44 | * type: 45 | * params: 46 | */ 47 | // TODO: promises 48 | shepherd.get('/update/bins/check', (req, res, next) => { 49 | if (shepherd.checkToken(req.query.token)) { 50 | const rootLocation = shepherd.path.join(__dirname, '../../'); 51 | const successObj = { 52 | msg: 'success', 53 | result: 'bins', 54 | }; 55 | 56 | res.end(JSON.stringify(successObj)); 57 | 58 | const _os = shepherd.os.platform(); 59 | shepherd.log(`checking bins: ${_os}`); 60 | 61 | shepherd.io.emit('patch', { 62 | patch: { 63 | type: 'bins-check', 64 | status: 'progress', 65 | message: `checking bins: ${_os}`, 66 | }, 67 | }); 68 | // get list of bins/dlls that can be updated to the latest 69 | for (let i = 0; i < latestBins[_os].length; i++) { 70 | shepherd.remoteFileSize(remoteBinLocation[_os] + latestBins[_os][i], (err, remoteBinSize) => { 71 | const localBinSize = shepherd.fs.statSync(rootLocation + localBinLocation[_os] + latestBins[_os][i]).size; 72 | 73 | shepherd.log('remote url: ' + (remoteBinLocation[_os] + latestBins[_os][i]) + ' (' + remoteBinSize + ')'); 74 | shepherd.log('local file: ' + (rootLocation + localBinLocation[_os] + latestBins[_os][i]) + ' (' + localBinSize + ')'); 75 | 76 | if (remoteBinSize !== localBinSize) { 77 | shepherd.log(`${latestBins[_os][i]} can be updated`); 78 | binsToUpdate.push({ 79 | name: latestBins[_os][i], 80 | rSize: remoteBinSize, 81 | lSize: localBinSize, 82 | }); 83 | } 84 | 85 | if (i === latestBins[_os].length - 1) { 86 | shepherd.io.emit('patch', { 87 | patch: { 88 | type: 'bins-check', 89 | status: 'done', 90 | fileList: binsToUpdate, 91 | }, 92 | }); 93 | } 94 | }); 95 | } 96 | } else { 97 | const errorObj = { 98 | msg: 'error', 99 | result: 'unauthorized access', 100 | }; 101 | 102 | res.end(JSON.stringify(errorObj)); 103 | } 104 | }); 105 | 106 | /* 107 | * Update bins 108 | * type: 109 | * params: 110 | */ 111 | shepherd.get('/update/bins', (req, res, next) => { 112 | if (shepherd.checkToken(req.query.token)) { 113 | const rootLocation = shepherd.path.join(__dirname, '../../'); 114 | const _os = shepherd.os.platform(); 115 | const successObj = { 116 | msg: 'success', 117 | result: { 118 | filesCount: binsToUpdate.length, 119 | list: binsToUpdate, 120 | }, 121 | }; 122 | 123 | res.end(JSON.stringify(successObj)); 124 | 125 | for (let i = 0; i < binsToUpdate.length; i++) { 126 | shepherd.downloadFile({ 127 | remoteFile: remoteBinLocation[_os] + binsToUpdate[i].name, 128 | localFile: `${rootLocation}${localBinLocation[_os]}patch/${binsToUpdate[i].name}`, 129 | onProgress: (received, total) => { 130 | const percentage = (received * 100) / total; 131 | 132 | if (percentage.toString().indexOf('.10') > -1) { 133 | shepherd.io.emit('patch', { 134 | msg: { 135 | type: 'bins-update', 136 | status: 'progress', 137 | file: binsToUpdate[i].name, 138 | bytesTotal: total, 139 | bytesReceived: received, 140 | }, 141 | }); 142 | // shepherd.log(`${binsToUpdate[i].name} ${percentage}% | ${received} bytes out of ${total} bytes.`); 143 | } 144 | } 145 | }) 146 | .then(() => { 147 | // verify that remote file is matching to DL'ed file 148 | const localBinSize = shepherd.fs.statSync(`${rootLocation}${localBinLocation[_os]}patch/${binsToUpdate[i].name}`).size; 149 | shepherd.log('compare dl file size'); 150 | 151 | if (localBinSize === binsToUpdate[i].rSize) { 152 | shepherd.io.emit('patch', { 153 | msg: { 154 | type: 'bins-update', 155 | file: binsToUpdate[i].name, 156 | status: 'done', 157 | }, 158 | }); 159 | shepherd.log(`file ${binsToUpdate[i].name} succesfully downloaded`); 160 | } else { 161 | shepherd.io.emit('patch', { 162 | msg: { 163 | type: 'bins-update', 164 | file: binsToUpdate[i].name, 165 | message: 'size mismatch', 166 | }, 167 | }); 168 | shepherd.log(`error: ${binsToUpdate[i].name} file size doesnt match remote!`); 169 | } 170 | }); 171 | } 172 | } else { 173 | const errorObj = { 174 | msg: 'error', 175 | result: 'unauthorized access', 176 | }; 177 | 178 | res.end(JSON.stringify(errorObj)); 179 | } 180 | }); 181 | 182 | return shepherd; 183 | }; -------------------------------------------------------------------------------- /routes/shepherd/downloadPatch.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | /* 3 | * DL app patch 4 | * type: GET 5 | * params: patchList 6 | */ 7 | shepherd.get('/update/patch', (req, res, next) => { 8 | if (shepherd.checkToken(req.query.token)) { 9 | const successObj = { 10 | msg: 'success', 11 | result: 'dl started', 12 | }; 13 | 14 | res.end(JSON.stringify(successObj)); 15 | 16 | shepherd.updateAgama(); 17 | } else { 18 | const errorObj = { 19 | msg: 'error', 20 | result: 'unauthorized access', 21 | }; 22 | 23 | res.end(JSON.stringify(errorObj)); 24 | } 25 | }); 26 | 27 | shepherd.updateAgama = () => { 28 | const rootLocation = shepherd.path.join(__dirname, '../../'); 29 | 30 | shepherd.downloadFile({ 31 | remoteFile: 'https://github.com/pbca26/dl-test/raw/master/patch.zip', 32 | localFile: `${rootLocation}patch.zip`, 33 | onProgress: (received, total) => { 34 | const percentage = (received * 100) / total; 35 | 36 | if (percentage.toString().indexOf('.10') > -1) { 37 | shepherd.io.emit('patch', { 38 | msg: { 39 | status: 'progress', 40 | type: 'ui', 41 | progress: percentage, 42 | bytesTotal: total, 43 | bytesReceived: received, 44 | }, 45 | }); 46 | //shepherd.log(`patch ${percentage}% | ${received} bytes out of ${total} bytes.`); 47 | } 48 | } 49 | }) 50 | .then(() => { 51 | shepherd.remoteFileSize('https://github.com/pbca26/dl-test/raw/master/patch.zip', (err, remotePatchSize) => { 52 | // verify that remote file is matching to DL'ed file 53 | const localPatchSize = shepherd.fs.statSync(`${rootLocation}patch.zip`).size; 54 | shepherd.log('compare dl file size'); 55 | 56 | if (localPatchSize === remotePatchSize) { 57 | const zip = new shepherd.AdmZip(`${rootLocation}patch.zip`); 58 | 59 | shepherd.log('patch succesfully downloaded'); 60 | shepherd.log('extracting contents'); 61 | 62 | if (shepherd.appConfig.dev) { 63 | if (!shepherd.fs.existsSync(`${rootLocation}/patch`)) { 64 | shepherd.fs.mkdirSync(`${rootLocation}/patch`); 65 | } 66 | } 67 | 68 | zip.extractAllTo(/*target path*/rootLocation + (shepherd.appConfig.dev ? '/patch' : ''), /*overwrite*/true); 69 | // TODO: extract files in chunks 70 | shepherd.io.emit('patch', { 71 | msg: { 72 | type: 'ui', 73 | status: 'done', 74 | }, 75 | }); 76 | shepherd.fs.unlinkSync(`${rootLocation}patch.zip`); 77 | } else { 78 | shepherd.io.emit('patch', { 79 | msg: { 80 | type: 'ui', 81 | status: 'error', 82 | message: 'size mismatch', 83 | }, 84 | }); 85 | shepherd.log('patch file size doesnt match remote!'); 86 | } 87 | }); 88 | }); 89 | } 90 | 91 | /* 92 | * check latest version 93 | * type: 94 | * params: 95 | */ 96 | shepherd.get('/update/patch/check', (req, res, next) => { 97 | if (shepherd.checkToken(req.query.token)) { 98 | const rootLocation = shepherd.path.join(__dirname, '../../'); 99 | const options = { 100 | url: 'https://github.com/pbca26/dl-test/raw/master/version', 101 | method: 'GET', 102 | }; 103 | 104 | shepherd.request(options, (error, response, body) => { 105 | if (response && 106 | response.statusCode && 107 | response.statusCode === 200) { 108 | const remoteVersion = body.split('\n'); 109 | const localVersionFile = shepherd.fs.readFileSync(`${rootLocation}version`, 'utf8'); 110 | let localVersion; 111 | 112 | if (localVersionFile.indexOf('\r\n') > -1) { 113 | localVersion = localVersionFile.split('\r\n'); 114 | } else { 115 | localVersion = localVersionFile.split('\n'); 116 | } 117 | 118 | if (remoteVersion[0] === localVersion[0]) { 119 | const successObj = { 120 | msg: 'success', 121 | result: 'latest', 122 | }; 123 | 124 | res.end(JSON.stringify(successObj)); 125 | } else { 126 | const successObj = { 127 | msg: 'success', 128 | result: 'update', 129 | version: { 130 | local: localVersion[0], 131 | remote: remoteVersion[0], 132 | }, 133 | }; 134 | 135 | res.end(JSON.stringify(successObj)); 136 | } 137 | } else { 138 | res.end({ 139 | err: 'error getting update', 140 | }); 141 | } 142 | }); 143 | } else { 144 | const errorObj = { 145 | msg: 'error', 146 | result: 'unauthorized access', 147 | }; 148 | 149 | res.end(JSON.stringify(errorObj)); 150 | } 151 | }); 152 | 153 | /* 154 | * unpack zip 155 | * type: 156 | * params: 157 | */ 158 | shepherd.get('/unpack', (req, res, next) => { 159 | if (shepherd.checkToken(req.query.token)) { 160 | const dlLocation = shepherd.path.join(__dirname, '../../'); 161 | const zip = new shepherd.AdmZip(`${dlLocation}patch.zip`); 162 | zip.extractAllTo(/*target path*/ `${dlLocation}/patch/unpack`, /*overwrite*/true); 163 | 164 | const successObj = { 165 | msg: 'success', 166 | result: 'unpack started', 167 | }; 168 | 169 | res.end(JSON.stringify(successObj)); 170 | } else { 171 | const errorObj = { 172 | msg: 'error', 173 | result: 'unauthorized access', 174 | }; 175 | 176 | res.end(JSON.stringify(errorObj)); 177 | } 178 | }); 179 | 180 | return shepherd; 181 | }; -------------------------------------------------------------------------------- /routes/shepherd/downloadUtil.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | /** 3 | * Promise based download file method 4 | */ 5 | shepherd.downloadFile = (configuration) => { 6 | return new shepherd.Promise((resolve, reject) => { 7 | // Save variable to know progress 8 | let receivedBytes = 0; 9 | let totalBytes = 0; 10 | 11 | let req = shepherd.request({ 12 | method: 'GET', 13 | uri: configuration.remoteFile, 14 | agentOptions: { 15 | keepAlive: true, 16 | keepAliveMsecs: 15000, 17 | }, 18 | }); 19 | 20 | let out = shepherd.fs.createWriteStream(configuration.localFile); 21 | req.pipe(out); 22 | 23 | req.on('response', (data) => { 24 | // Change the total bytes value to get progress later. 25 | totalBytes = parseInt(data.headers['content-length']); 26 | }); 27 | 28 | // Get progress if callback exists 29 | if (configuration.hasOwnProperty('onProgress')) { 30 | req.on('data', (chunk) => { 31 | // Update the received bytes 32 | receivedBytes += chunk.length; 33 | configuration.onProgress(receivedBytes, totalBytes); 34 | }); 35 | } else { 36 | req.on('data', (chunk) => { 37 | // Update the received bytes 38 | receivedBytes += chunk.length; 39 | }); 40 | } 41 | 42 | req.on('end', () => { 43 | resolve(); 44 | }); 45 | }); 46 | } 47 | 48 | return shepherd; 49 | }; -------------------------------------------------------------------------------- /routes/shepherd/downloadZcparams.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | shepherd.zcashParamsDownloadLinks = { 3 | 'agama.komodoplatform.com': { 4 | proving: 'https://agama.komodoplatform.com/file/supernet/sprout-proving.key', 5 | verifying: 'https://agama.komodoplatform.com/file/supernet/sprout-verifying.key', 6 | }, 7 | 'agama-yq0ysrdtr.stackpathdns.com': { 8 | proving: 'http://agama-yq0ysrdtr.stackpathdns.com/file/supernet/sprout-proving.key', 9 | verifying: 'http://agama-yq0ysrdtr.stackpathdns.com/file/supernet/sprout-verifying.key', 10 | }, 11 | 'zcash.dl.mercerweiss.com': { 12 | proving: 'https://zcash.dl.mercerweiss.com/sprout-proving.key', 13 | verifying: 'https://zcash.dl.mercerweiss.com/sprout-verifying.key', 14 | }, 15 | }; 16 | 17 | shepherd.zcashParamsExist = () => { 18 | let _checkList = { 19 | rootDir: shepherd._fs.existsSync(shepherd.zcashParamsDir), 20 | provingKey: shepherd._fs.existsSync(`${shepherd.zcashParamsDir}/sprout-proving.key`), 21 | provingKeySize: false, 22 | verifyingKey: shepherd._fs.existsSync(`${shepherd.zcashParamsDir}/sprout-verifying.key`), 23 | verifyingKeySize: false, 24 | errors: false, 25 | }; 26 | 27 | if (_checkList.rootDir && 28 | _checkList.provingKey || 29 | _checkList.verifyingKey) { 30 | // verify each key size 31 | const _provingKeySize = _checkList.provingKey ? shepherd.fs.lstatSync(`${shepherd.zcashParamsDir}/sprout-proving.key`) : 0; 32 | const _verifyingKeySize = _checkList.verifyingKey ? shepherd.fs.lstatSync(`${shepherd.zcashParamsDir}/sprout-verifying.key`) : 0; 33 | 34 | if (Number(_provingKeySize.size) === 910173851) { // bytes 35 | _checkList.provingKeySize = true; 36 | } 37 | if (Number(_verifyingKeySize.size) === 1449) { 38 | _checkList.verifyingKeySize = true; 39 | } 40 | 41 | shepherd.log('zcashparams exist'); 42 | } else { 43 | shepherd.log('zcashparams doesnt exist'); 44 | } 45 | 46 | if (!_checkList.rootDir || 47 | !_checkList.provingKey || 48 | !_checkList.verifyingKey || 49 | !_checkList.provingKeySize || 50 | !_checkList.verifyingKeySize) { 51 | _checkList.errors = true; 52 | } 53 | 54 | return _checkList; 55 | } 56 | 57 | shepherd.zcashParamsExistPromise = () => { 58 | return new shepherd.Promise((resolve, reject) => { 59 | const _verify = shepherd.zcashParamsExist(); 60 | resolve(_verify); 61 | }); 62 | }; 63 | 64 | /* 65 | * Update bins 66 | * type: 67 | * params: 68 | */ 69 | shepherd.get('/zcparamsdl', (req, res, next) => { 70 | if (shepherd.checkToken(req.query.token)) { 71 | // const dlLocation = shepherd.zcashParamsDir + '/test'; 72 | const dlLocation = shepherd.zcashParamsDir; 73 | const dlOption = req.query.dloption; 74 | 75 | const successObj = { 76 | msg: 'success', 77 | result: 'zcash params dl started', 78 | }; 79 | 80 | res.end(JSON.stringify(successObj)); 81 | 82 | for (let key in shepherd.zcashParamsDownloadLinks[dlOption]) { 83 | shepherd.downloadFile({ 84 | remoteFile: shepherd.zcashParamsDownloadLinks[dlOption][key], 85 | localFile: `${dlLocation}/sprout-${key}.key`, 86 | onProgress: (received, total) => { 87 | const percentage = (received * 100) / total; 88 | 89 | if (percentage.toString().indexOf('.10') > -1) { 90 | shepherd.io.emit('zcparams', { 91 | msg: { 92 | type: 'zcpdownload', 93 | status: 'progress', 94 | file: key, 95 | bytesTotal: total, 96 | bytesReceived: received, 97 | progress: percentage, 98 | }, 99 | }); 100 | // shepherd.log(`${key} ${percentage}% | ${received} bytes out of ${total} bytes.`); 101 | } 102 | } 103 | }) 104 | .then(() => { 105 | const checkZcashParams = shepherd.zcashParamsExist(); 106 | 107 | shepherd.log(`${key} dl done`); 108 | 109 | if (checkZcashParams.error) { 110 | shepherd.io.emit('zcparams', { 111 | msg: { 112 | type: 'zcpdownload', 113 | file: key, 114 | status: 'error', 115 | message: 'size mismatch', 116 | progress: 100, 117 | }, 118 | }); 119 | } else { 120 | shepherd.io.emit('zcparams', { 121 | msg: { 122 | type: 'zcpdownload', 123 | file: key, 124 | progress: 100, 125 | status: 'done', 126 | }, 127 | }); 128 | shepherd.log(`file ${key} succesfully downloaded`); 129 | } 130 | }); 131 | } 132 | } else { 133 | const errorObj = { 134 | msg: 'error', 135 | result: 'unauthorized access', 136 | }; 137 | 138 | res.end(JSON.stringify(errorObj)); 139 | } 140 | }); 141 | 142 | return shepherd; 143 | }; -------------------------------------------------------------------------------- /routes/shepherd/electrum/auth.js: -------------------------------------------------------------------------------- 1 | const bs58check = require('bs58check'); 2 | const bitcoinZcash = require('bitcoinjs-lib-zcash'); 3 | const bitcoin = require('bitcoinjs-lib'); 4 | 5 | module.exports = (shepherd) => { 6 | shepherd.post('/electrum/login', (req, res, next) => { 7 | if (shepherd.checkToken(req.body.token)) { 8 | let _wifError = false; 9 | 10 | for (let key in shepherd.electrumCoins) { 11 | if (key !== 'auth') { 12 | const _abbr = key; 13 | const _seed = req.body.seed; 14 | let keys; 15 | let isWif = false; 16 | 17 | if (req.body.seed.match('^[a-zA-Z0-9]{34}$') && 18 | shepherd.appConfig.experimentalFeatures) { 19 | shepherd.log('watchonly pub addr'); 20 | shepherd.electrumKeys[_abbr] = { 21 | priv: req.body.seed, 22 | pub: req.body.seed, 23 | }; 24 | } else { 25 | try { 26 | bs58check.decode(_seed); 27 | isWif = true; 28 | } catch (e) {} 29 | 30 | if (isWif) { 31 | try { 32 | let key = shepherd.isZcash(_abbr.toLowerCase()) ? bitcoinZcash.ECPair.fromWIF(_seed, shepherd.getNetworkData(_abbr.toLowerCase()), true) : bitcoin.ECPair.fromWIF(_seed, shepherd.getNetworkData(_abbr.toLowerCase()), true); 33 | keys = { 34 | priv: key.toWIF(), 35 | pub: key.getAddress(), 36 | }; 37 | } catch (e) { 38 | _wifError = true; 39 | break; 40 | } 41 | } else { 42 | keys = shepherd.seedToWif(_seed, shepherd.findNetworkObj(_abbr), req.body.iguana); 43 | } 44 | 45 | shepherd.electrumKeys[_abbr] = { 46 | priv: keys.priv, 47 | pub: keys.pub, 48 | }; 49 | } 50 | } 51 | } 52 | 53 | shepherd.electrumCoins.auth = true; 54 | 55 | // shepherd.log(JSON.stringify(shepherd.electrumKeys, null, '\t'), true); 56 | 57 | const successObj = { 58 | msg: _wifError ? 'error' : 'success', 59 | result: 'true', 60 | }; 61 | 62 | res.end(JSON.stringify(successObj)); 63 | } else { 64 | const errorObj = { 65 | msg: 'error', 66 | result: 'unauthorized access', 67 | }; 68 | 69 | res.end(JSON.stringify(errorObj)); 70 | } 71 | }); 72 | 73 | shepherd.post('/electrum/lock', (req, res, next) => { 74 | if (shepherd.checkToken(req.body.token)) { 75 | shepherd.electrumCoins.auth = false; 76 | shepherd.electrumKeys = {}; 77 | 78 | const successObj = { 79 | msg: 'success', 80 | result: 'true', 81 | }; 82 | 83 | res.end(JSON.stringify(successObj)); 84 | } else { 85 | const errorObj = { 86 | msg: 'error', 87 | result: 'unauthorized access', 88 | }; 89 | 90 | res.end(JSON.stringify(errorObj)); 91 | } 92 | }); 93 | 94 | shepherd.post('/electrum/logout', (req, res, next) => { 95 | if (shepherd.checkToken(req.body.token)) { 96 | shepherd.electrumCoins = { 97 | auth: false, 98 | }; 99 | shepherd.electrumKeys = {}; 100 | 101 | const obj = { 102 | msg: 'success', 103 | result: 'result', 104 | }; 105 | 106 | res.end(JSON.stringify(obj)); 107 | } else { 108 | const errorObj = { 109 | msg: 'error', 110 | result: 'unauthorized access', 111 | }; 112 | 113 | res.end(JSON.stringify(errorObj)); 114 | } 115 | }); 116 | 117 | return shepherd; 118 | }; -------------------------------------------------------------------------------- /routes/shepherd/electrum/balance.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | shepherd.get('/electrum/getbalance', (req, res, next) => { 3 | if (shepherd.checkToken(req.query.token)) { 4 | const network = req.query.network || shepherd.findNetworkObj(req.query.coin); 5 | const ecl = new shepherd.electrumJSCore(shepherd.electrumServers[network].port, shepherd.electrumServers[network].address, shepherd.electrumServers[network].proto); // tcp or tls 6 | 7 | shepherd.log('electrum getbalance =>', true); 8 | 9 | ecl.connect(); 10 | ecl.blockchainAddressGetBalance(req.query.address) 11 | .then((json) => { 12 | if (json && 13 | json.hasOwnProperty('confirmed') && 14 | json.hasOwnProperty('unconfirmed')) { 15 | if (network === 'komodo') { 16 | ecl.blockchainAddressListunspent(req.query.address) 17 | .then((utxoList) => { 18 | if (utxoList && 19 | utxoList.length) { 20 | // filter out < 10 KMD amounts 21 | let _utxo = []; 22 | 23 | for (let i = 0; i < utxoList.length; i++) { 24 | shepherd.log(`utxo ${utxoList[i]['tx_hash']} sats ${utxoList[i].value} value ${Number(utxoList[i].value) * 0.00000001}`, true); 25 | 26 | if (Number(utxoList[i].value) * 0.00000001 >= 10) { 27 | _utxo.push(utxoList[i]); 28 | } 29 | } 30 | 31 | shepherd.log('filtered utxo list =>', true); 32 | shepherd.log(_utxo, true); 33 | 34 | if (_utxo && 35 | _utxo.length) { 36 | let interestTotal = 0; 37 | 38 | shepherd.Promise.all(_utxo.map((_utxoItem, index) => { 39 | return new shepherd.Promise((resolve, reject) => { 40 | shepherd.getTransaction(_utxoItem['tx_hash'], network, ecl) 41 | .then((_rawtxJSON) => { 42 | shepherd.log('electrum gettransaction ==>', true); 43 | shepherd.log((index + ' | ' + (_rawtxJSON.length - 1)), true); 44 | shepherd.log(_rawtxJSON, true); 45 | 46 | // decode tx 47 | const _network = shepherd.getNetworkData(network); 48 | const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, network, _network); 49 | 50 | if (decodedTx && 51 | decodedTx.format && 52 | decodedTx.format.locktime > 0) { 53 | interestTotal += shepherd.kmdCalcInterest(decodedTx.format.locktime, _utxoItem.value); 54 | } 55 | 56 | shepherd.log('decoded tx =>', true); 57 | shepherd.log(decodedTx, true); 58 | 59 | resolve(true); 60 | }); 61 | }); 62 | })) 63 | .then(promiseResult => { 64 | ecl.close(); 65 | 66 | const successObj = { 67 | msg: 'success', 68 | result: { 69 | balance: Number((0.00000001 * json.confirmed).toFixed(8)), 70 | unconfirmed: Number((0.00000001 * json.unconfirmed).toFixed(8)), 71 | unconfirmedSats: json.unconfirmed, 72 | balanceSats: json.confirmed, 73 | interest: Number(interestTotal.toFixed(8)), 74 | interestSats: Math.floor(interestTotal * 100000000), 75 | total: interestTotal > 0 ? Number((0.00000001 * json.confirmed + interestTotal).toFixed(8)) : 0, 76 | totalSats: interestTotal > 0 ? json.confirmed + Math.floor(interestTotal * 100000000) : 0, 77 | }, 78 | }; 79 | 80 | res.end(JSON.stringify(successObj)); 81 | }); 82 | } else { 83 | ecl.close(); 84 | 85 | const successObj = { 86 | msg: 'success', 87 | result: { 88 | balance: Number((0.00000001 * json.confirmed).toFixed(8)), 89 | unconfirmed: Number((0.00000001 * json.unconfirmed).toFixed(8)), 90 | unconfirmedSats: json.unconfirmed, 91 | balanceSats: json.confirmed, 92 | interest: 0, 93 | interestSats: 0, 94 | total: 0, 95 | totalSats: 0, 96 | }, 97 | }; 98 | 99 | res.end(JSON.stringify(successObj)); 100 | } 101 | } else { 102 | ecl.close(); 103 | 104 | const successObj = { 105 | msg: 'success', 106 | result: { 107 | balance: Number((0.00000001 * json.confirmed).toFixed(8)), 108 | unconfirmed: Number((0.00000001 * json.unconfirmed).toFixed(8)), 109 | unconfirmedSats: json.unconfirmed, 110 | balanceSats: json.confirmed, 111 | interest: 0, 112 | interestSats: 0, 113 | total: 0, 114 | totalSats: 0, 115 | }, 116 | }; 117 | 118 | res.end(JSON.stringify(successObj)); 119 | } 120 | }); 121 | } else { 122 | ecl.close(); 123 | shepherd.log('electrum getbalance ==>', true); 124 | shepherd.log(json, true); 125 | 126 | const successObj = { 127 | msg: 'success', 128 | result: { 129 | balance: Number((0.00000001 * json.confirmed).toFixed(8)), 130 | unconfirmed: Number((0.00000001 * json.unconfirmed).toFixed(8)), 131 | unconfirmedSats: json.unconfirmed, 132 | balanceSats: json.confirmed, 133 | }, 134 | }; 135 | 136 | res.end(JSON.stringify(successObj)); 137 | } 138 | } else { 139 | ecl.close(); 140 | 141 | const successObj = { 142 | msg: 'error', 143 | result: shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA, 144 | }; 145 | 146 | res.end(JSON.stringify(successObj)); 147 | } 148 | }); 149 | } else { 150 | const errorObj = { 151 | msg: 'error', 152 | result: 'unauthorized access', 153 | }; 154 | 155 | res.end(JSON.stringify(errorObj)); 156 | } 157 | }); 158 | 159 | return shepherd; 160 | }; -------------------------------------------------------------------------------- /routes/shepherd/electrum/block.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | shepherd.get('/electrum/getblockinfo', (req, res, next) => { 3 | if (shepherd.checkToken(req.query.token)) { 4 | shepherd.electrumGetBlockInfo(req.query.height, req.query.network) 5 | .then((json) => { 6 | const successObj = { 7 | msg: 'success', 8 | result: json, 9 | }; 10 | 11 | res.end(JSON.stringify(successObj)); 12 | }); 13 | } else { 14 | const errorObj = { 15 | msg: 'error', 16 | result: 'unauthorized access', 17 | }; 18 | 19 | res.end(JSON.stringify(errorObj)); 20 | } 21 | }); 22 | 23 | shepherd.electrumGetBlockInfo = (height, network) => { 24 | return new shepherd.Promise((resolve, reject) => { 25 | const ecl = new shepherd.electrumJSCore(shepherd.electrumServers[network].port, shepherd.electrumServers[network].address, shepherd.electrumServers[network].proto); // tcp or tls 26 | 27 | ecl.connect(); 28 | ecl.blockchainBlockGetHeader(height) 29 | .then((json) => { 30 | ecl.close(); 31 | shepherd.log('electrum getblockinfo ==>', true); 32 | shepherd.log(json, true); 33 | 34 | resolve(json); 35 | }); 36 | }); 37 | } 38 | 39 | shepherd.get('/electrum/getcurrentblock', (req, res, next) => { 40 | if (shepherd.checkToken(req.query.token)) { 41 | shepherd.electrumGetCurrentBlock(req.query.network) 42 | .then((json) => { 43 | const successObj = { 44 | msg: 'success', 45 | result: json, 46 | }; 47 | 48 | res.end(JSON.stringify(successObj)); 49 | }); 50 | } else { 51 | const errorObj = { 52 | msg: 'error', 53 | result: 'unauthorized access', 54 | }; 55 | 56 | res.end(JSON.stringify(errorObj)); 57 | } 58 | }); 59 | 60 | shepherd.electrumGetCurrentBlock = (network) => { 61 | return new shepherd.Promise((resolve, reject) => { 62 | const ecl = new shepherd.electrumJSCore(shepherd.electrumServers[network].port, shepherd.electrumServers[network].address, shepherd.electrumServers[network].proto); // tcp or tls 63 | 64 | ecl.connect(); 65 | ecl.blockchainNumblocksSubscribe() 66 | .then((json) => { 67 | ecl.close(); 68 | shepherd.log('electrum currentblock ==>', true); 69 | shepherd.log(json, true); 70 | 71 | resolve(json); 72 | }); 73 | }); 74 | } 75 | 76 | return shepherd; 77 | }; -------------------------------------------------------------------------------- /routes/shepherd/electrum/coins.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | shepherd.findCoinName = (network) => { 3 | for (let key in shepherd.electrumServers) { 4 | if (key === network) { 5 | return shepherd.electrumServers[key].abbr; 6 | } 7 | } 8 | } 9 | 10 | shepherd.addElectrumCoin = (coin) => { 11 | const servers = shepherd.electrumServers[coin === 'KMD' ? 'komodo' : coin.toLowerCase()].serverList; 12 | // select random server 13 | const getRandomIntInclusive = (min, max) => { 14 | min = Math.ceil(min); 15 | max = Math.floor(max); 16 | 17 | return Math.floor(Math.random() * (max - min + 1)) + min; // the maximum is inclusive and the minimum is inclusive 18 | } 19 | let randomServer; 20 | 21 | // pick a random server to communicate with 22 | if (servers && 23 | servers.length > 0) { 24 | const _randomServerId = getRandomIntInclusive(0, servers.length - 1); 25 | const _randomServer = servers[_randomServerId]; 26 | const _serverDetails = _randomServer.split(':'); 27 | 28 | if (_serverDetails.length === 2) { 29 | randomServer = { 30 | ip: _serverDetails[0], 31 | port: _serverDetails[1], 32 | }; 33 | } 34 | } 35 | 36 | for (let key in shepherd.electrumServers) { 37 | if (shepherd.electrumServers[key].abbr === coin) { 38 | shepherd.electrumCoins[coin] = { 39 | name: key, 40 | abbr: coin, 41 | server: { 42 | ip: randomServer ? randomServer.ip : shepherd.electrumServers[key].address, 43 | port: randomServer ? randomServer.port : shepherd.electrumServers[key].port, 44 | }, 45 | serverList: shepherd.electrumServers[key].serverList ? shepherd.electrumServers[key].serverList : 'none', 46 | txfee: 'calculated' /*shepherd.electrumServers[key].txfee*/, 47 | }; 48 | 49 | shepherd.log(`default ${coin} electrum server ${shepherd.electrumServers[key].address + ':' + shepherd.electrumServers[key].port}`, true); 50 | 51 | if (randomServer) { 52 | shepherd.log(`random ${coin} electrum server ${randomServer.ip + ':' + randomServer.port}`, true); 53 | } else { 54 | shepherd.log(`${coin} doesnt have any backup electrum servers`, true); 55 | } 56 | 57 | if (Object.keys(shepherd.electrumKeys).length > 0) { 58 | const _keys = shepherd.wifToWif(shepherd.electrumKeys[Object.keys(shepherd.electrumKeys)[0]].priv, coin); 59 | 60 | shepherd.electrumKeys[coin] = { 61 | priv: _keys.priv, 62 | pub: _keys.pub, 63 | }; 64 | } 65 | 66 | return true; 67 | } 68 | } 69 | } 70 | 71 | shepherd.get('/electrum/coin/changepub', (req, res, next) => { 72 | if (shepherd.checkToken(req.query.token)) { 73 | shepherd.electrumKeys[req.query.coin].pub = req.query.pub; 74 | 75 | const successObj = { 76 | msg: 'success', 77 | result: 'true', 78 | }; 79 | 80 | res.end(JSON.stringify(successObj)); 81 | } else { 82 | const errorObj = { 83 | msg: 'error', 84 | result: 'unauthorized access', 85 | }; 86 | 87 | res.end(JSON.stringify(errorObj)); 88 | } 89 | }); 90 | 91 | shepherd.get('/electrum/coins/add', (req, res, next) => { 92 | if (shepherd.checkToken(req.query.token)) { 93 | const result = shepherd.addElectrumCoin(req.query.coin); 94 | 95 | const successObj = { 96 | msg: 'success', 97 | result, 98 | }; 99 | 100 | res.end(JSON.stringify(successObj)); 101 | } else { 102 | const errorObj = { 103 | msg: 'error', 104 | result: 'unauthorized access', 105 | }; 106 | 107 | res.end(JSON.stringify(errorObj)); 108 | } 109 | }); 110 | 111 | shepherd.get('/electrum/coins', (req, res, next) => { 112 | if (shepherd.checkToken(req.query.token)) { 113 | let _electrumCoins = JSON.parse(JSON.stringify(shepherd.electrumCoins)); // deep cloning 114 | 115 | for (let key in _electrumCoins) { 116 | if (shepherd.electrumKeys[key]) { 117 | _electrumCoins[key].pub = shepherd.electrumKeys[key].pub; 118 | } 119 | } 120 | 121 | const successObj = { 122 | msg: 'success', 123 | result: _electrumCoins, 124 | }; 125 | 126 | res.end(JSON.stringify(successObj)); 127 | } else { 128 | const errorObj = { 129 | msg: 'error', 130 | result: 'unauthorized access', 131 | }; 132 | 133 | res.end(JSON.stringify(errorObj)); 134 | } 135 | }); 136 | 137 | return shepherd; 138 | }; -------------------------------------------------------------------------------- /routes/shepherd/electrum/createtx-split.js: -------------------------------------------------------------------------------- 1 | const bitcoinJSForks = require('bitcoinforksjs-lib'); 2 | const bitcoinZcash = require('bitcoinjs-lib-zcash'); 3 | const bitcoinPos = require('bitcoinjs-lib-pos'); 4 | 5 | module.exports = (shepherd) => { 6 | // utxo split 1 -> 1, multiple outputs 7 | shepherd.post('/electrum/createrawtx-split', (req, res, next) => { 8 | if (shepherd.checkToken(req.body.token)) { 9 | const wif = req.body.payload.wif; 10 | const utxo = req.body.payload.utxo; 11 | const targets = req.body.payload.targets; 12 | const network = req.body.payload.network; 13 | const change = req.body.payload.change; 14 | const outputAddress = req.body.payload.outputAddress; 15 | const changeAddress = req.body.payload.changeAddress; 16 | 17 | let key = shepherd.isZcash(network) ? bitcoinZcash.ECPair.fromWIF(wif, shepherd.getNetworkData(network)) : shepherd.bitcoinJS.ECPair.fromWIF(wif, shepherd.getNetworkData(network)); 18 | let tx; 19 | 20 | if (shepherd.isZcash(network)) { 21 | tx = new bitcoinZcash.TransactionBuilder(shepherd.getNetworkData(network)); 22 | } else if (shepherd.isPos(network)) { 23 | tx = new bitcoinPos.TransactionBuilder(shepherd.getNetworkData(network)); 24 | } else { 25 | tx = new shepherd.bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network)); 26 | } 27 | 28 | shepherd.log('buildSignedTx', true); 29 | shepherd.log(`buildSignedTx pub key ${key.getAddress().toString()}`, true); 30 | 31 | for (let i = 0; i < utxo.length; i++) { 32 | tx.addInput(utxo[i].txid, utxo[i].vout); 33 | } 34 | 35 | for (let i = 0; i < targets.length; i++) { 36 | if (shepherd.isPos(network)) { 37 | tx.addOutput(outputAddress, Number(targets[i]), shepherd.getNetworkData(network)); 38 | } else { 39 | tx.addOutput(outputAddress, Number(targets[i])); 40 | } 41 | } 42 | 43 | if (Number(change) > 0) { 44 | if (shepherd.isPos(network)) { 45 | tx.addOutput(changeAddress, Number(change), shepherd.getNetworkData(network)); 46 | } else { 47 | shepherd.log(`change ${change}`, true); 48 | tx.addOutput(changeAddress, Number(change)); 49 | } 50 | } 51 | 52 | if (network === 'komodo' || 53 | network === 'KMD') { 54 | const _locktime = Math.floor(Date.now() / 1000) - 777; 55 | tx.setLockTime(_locktime); 56 | shepherd.log(`kmd tx locktime set to ${_locktime}`, true); 57 | } 58 | 59 | for (let i = 0; i < utxo.length; i++) { 60 | if (shepherd.isPos(network)) { 61 | tx.sign(shepherd.getNetworkData(network), i, key); 62 | } else { 63 | tx.sign(i, key); 64 | } 65 | } 66 | 67 | const rawtx = tx.build().toHex(); 68 | 69 | const successObj = { 70 | msg: 'success', 71 | result: rawtx, 72 | }; 73 | 74 | res.end(JSON.stringify(successObj)); 75 | } else { 76 | const errorObj = { 77 | msg: 'error', 78 | result: 'unauthorized access', 79 | }; 80 | 81 | res.end(JSON.stringify(errorObj)); 82 | } 83 | }); 84 | 85 | return shepherd; 86 | }; -------------------------------------------------------------------------------- /routes/shepherd/electrum/estimate.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | shepherd.get('/electrum/estimatefee', (req, res, next) => { 3 | if (shepherd.checkToken(req.query.token)) { 4 | const ecl = new shepherd.electrumJSCore(shepherd.electrumServers[req.query.network].port, shepherd.electrumServers[req.query.network].address, shepherd.electrumServers[req.query.network].proto); // tcp or tls 5 | 6 | ecl.connect(); 7 | ecl.blockchainEstimatefee(req.query.blocks) 8 | .then((json) => { 9 | ecl.close(); 10 | shepherd.log('electrum estimatefee ==>', true); 11 | 12 | const successObj = { 13 | msg: 'success', 14 | result: json, 15 | }; 16 | 17 | res.end(JSON.stringify(successObj)); 18 | }); 19 | } else { 20 | const errorObj = { 21 | msg: 'error', 22 | result: 'unauthorized access', 23 | }; 24 | 25 | res.end(JSON.stringify(errorObj)); 26 | } 27 | }); 28 | 29 | shepherd.estimateTxSize = (numVins, numOuts) => { 30 | // in x 180 + out x 34 + 10 plus or minus in 31 | return numVins * 180 + numOuts * 34 + 11; 32 | } 33 | 34 | return shepherd; 35 | }; -------------------------------------------------------------------------------- /routes/shepherd/electrum/interest.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | shepherd.kmdCalcInterest = (locktime, value) => { // value in sats 3 | const timestampDiff = Math.floor(Date.now() / 1000) - locktime - 777; 4 | const hoursPassed = Math.floor(timestampDiff / 3600); 5 | const minutesPassed = Math.floor((timestampDiff - (hoursPassed * 3600)) / 60); 6 | const secondsPassed = timestampDiff - (hoursPassed * 3600) - (minutesPassed * 60); 7 | let timestampDiffMinutes = timestampDiff / 60; 8 | let interest = 0; 9 | 10 | shepherd.log('kmdCalcInterest', true); 11 | shepherd.log(`locktime ${locktime}`, true); 12 | shepherd.log(`minutes converted ${timestampDiffMinutes}`, true); 13 | shepherd.log(`passed ${hoursPassed}h ${minutesPassed}m ${secondsPassed}s`, true); 14 | 15 | // calc interest 16 | if (timestampDiffMinutes >= 60) { 17 | if (timestampDiffMinutes > 365 * 24 * 60) { 18 | timestampDiffMinutes = 365 * 24 * 60; 19 | } 20 | timestampDiffMinutes -= 59; 21 | 22 | // shepherd.log(`minutes if statement ${timestampDiffMinutes}`, true); 23 | 24 | // TODO: check if interest is > 5% yr 25 | // calc ytd and 5% for 1 yr 26 | // const hoursInOneYear = 365 * 24; 27 | // const hoursDiff = hoursInOneYear - hoursPassed; 28 | 29 | interest = ((Number(value) * 0.00000001) / 10512000) * timestampDiffMinutes; 30 | shepherd.log(`interest ${interest}`, true); 31 | } 32 | 33 | return interest; 34 | } 35 | 36 | return shepherd; 37 | }; -------------------------------------------------------------------------------- /routes/shepherd/electrum/merkle.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | // get merkle root 3 | shepherd.getMerkleRoot = (txid, proof, pos) => { 4 | const reverse = require('buffer-reverse'); 5 | const _sha256 = (data) => { 6 | return shepherd.crypto.createHash('sha256').update(data).digest(); 7 | } 8 | let hash = txid; 9 | let serialized; 10 | 11 | shepherd.log(`getMerkleRoot txid ${txid}`, true); 12 | shepherd.log(`getMerkleRoot pos ${pos}`, true); 13 | shepherd.log('getMerkleRoot proof', true); 14 | shepherd.log(`getMerkleRoot ${proof}`, true); 15 | 16 | for (i = 0; i < proof.length; i++) { 17 | const _hashBuff = new Buffer(hash, 'hex'); 18 | const _proofBuff = new Buffer(proof[i], 'hex'); 19 | 20 | if ((pos & 1) == 0) { 21 | serialized = Buffer.concat([reverse(_hashBuff), reverse(_proofBuff)]); 22 | } else { 23 | serialized = Buffer.concat([reverse(_proofBuff), reverse(_hashBuff)]); 24 | } 25 | 26 | hash = reverse(_sha256(_sha256(serialized))).toString('hex'); 27 | pos /= 2; 28 | } 29 | 30 | return hash; 31 | } 32 | 33 | shepherd.verifyMerkle = (txid, height, serverList, mainServer, network) => { 34 | // select random server 35 | const getRandomIntInclusive = (min, max) => { 36 | min = Math.ceil(min); 37 | max = Math.floor(max); 38 | 39 | return Math.floor(Math.random() * (max - min + 1)) + min; // the maximum is inclusive and the minimum is inclusive 40 | } 41 | 42 | const _rnd = getRandomIntInclusive(0, serverList.length - 1); 43 | const randomServer = serverList[_rnd]; 44 | const _randomServer = randomServer.split(':'); 45 | const _mainServer = mainServer.split(':'); 46 | 47 | let ecl = new shepherd.electrumJSCore(_mainServer[1], _mainServer[0], _mainServer[2]); // tcp or tls 48 | 49 | return new shepherd.Promise((resolve, reject) => { 50 | shepherd.log(`main server: ${mainServer}`, true); 51 | shepherd.log(`verification server: ${randomServer}`, true); 52 | 53 | ecl.connect(); 54 | ecl.blockchainTransactionGetMerkle(txid, height) 55 | .then((merkleData) => { 56 | if (merkleData && 57 | merkleData.merkle && 58 | merkleData.pos) { 59 | shepherd.log('electrum getmerkle =>', true); 60 | shepherd.log(merkleData, true); 61 | ecl.close(); 62 | 63 | const _res = shepherd.getMerkleRoot(txid, merkleData.merkle, merkleData.pos); 64 | shepherd.log(_res, true); 65 | 66 | ecl = new shepherd.electrumJSCore(_randomServer[1], _randomServer[0], _mainServer[2]); 67 | ecl.connect(); 68 | 69 | shepherd.getBlockHeader(height, network, ecl) 70 | .then((blockInfo) => { 71 | if (blockInfo && 72 | blockInfo['merkle_root']) { 73 | ecl.close(); 74 | shepherd.log('blockinfo =>', true); 75 | shepherd.log(blockInfo, true); 76 | shepherd.log(blockInfo['merkle_root'], true); 77 | 78 | if (blockInfo && 79 | blockInfo['merkle_root']) { 80 | if (_res === blockInfo['merkle_root']) { 81 | resolve(true); 82 | } else { 83 | resolve(false); 84 | } 85 | } else { 86 | ecl.close(); 87 | resolve(shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA); 88 | } 89 | } else { 90 | ecl.close(); 91 | resolve(shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA); 92 | } 93 | }); 94 | } else { 95 | ecl.close(); 96 | resolve(shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA); 97 | } 98 | }); 99 | }); 100 | } 101 | 102 | shepherd.verifyMerkleByCoin = (coin, txid, height) => { 103 | const _serverList = shepherd.electrumCoins[coin].serverList; 104 | 105 | shepherd.log(`verifyMerkleByCoin`, true); 106 | shepherd.log(shepherd.electrumCoins[coin].server, true); 107 | shepherd.log(shepherd.electrumCoins[coin].serverList, true); 108 | 109 | return new shepherd.Promise((resolve, reject) => { 110 | if (_serverList !== 'none') { 111 | let _filteredServerList = []; 112 | 113 | for (let i = 0; i < _serverList.length; i++) { 114 | if (_serverList[i] !== shepherd.electrumCoins[coin].server.ip + ':' + shepherd.electrumCoins[coin].server.port) { 115 | _filteredServerList.push(_serverList[i]); 116 | } 117 | } 118 | 119 | shepherd.verifyMerkle( 120 | txid, 121 | height, 122 | _filteredServerList, 123 | shepherd.electrumCoins[coin].server.ip + ':' + shepherd.electrumCoins[coin].server.port + ':' + shepherd.electrumServers[coin === 'KMD' || coin === 'komodo' ? 'komodo' : coin.toLowerCase()].proto, 124 | coin 125 | ) 126 | .then((proof) => { 127 | resolve(proof); 128 | }); 129 | } else { 130 | resolve(false); 131 | } 132 | }); 133 | } 134 | 135 | shepherd.get('/electrum/merkle/verify', (req, res, next) => { 136 | if (shepherd.checkToken(req.query.token)) { 137 | shepherd.verifyMerkleByCoin(req.query.coin, req.query.txid, req.query.height) 138 | .then((verifyMerkleRes) => { 139 | const successObj = { 140 | msg: 'success', 141 | result: { 142 | merkleProof: verifyMerkleRes, 143 | }, 144 | }; 145 | 146 | res.end(JSON.stringify(successObj)); 147 | }); 148 | } else { 149 | const errorObj = { 150 | msg: 'error', 151 | result: 'unauthorized access', 152 | }; 153 | 154 | res.end(JSON.stringify(errorObj)); 155 | } 156 | }); 157 | 158 | return shepherd; 159 | }; 160 | -------------------------------------------------------------------------------- /routes/shepherd/electrum/network.js: -------------------------------------------------------------------------------- 1 | const txDecoder = { 2 | default: require('../../electrumjs/electrumjs.txdecoder.js'), 3 | zcash: require('../../electrumjs/electrumjs.txdecoder-2bytes.js'), 4 | pos: require('../../electrumjs/electrumjs.txdecoder-pos.js'), 5 | }; 6 | 7 | module.exports = (shepherd) => { 8 | shepherd.isZcash = (network) => { 9 | if (network === 'ZEC' || 10 | network === 'zec' || 11 | network === 'zcash' || 12 | network === 'ZCASH' || 13 | network === 'HUSH' || 14 | network === 'hush' || 15 | network === 'ZCL' || 16 | network === 'zcl' || 17 | network === 'BTCZ' || 18 | network === 'btcz') { 19 | return true; 20 | } 21 | }; 22 | 23 | shepherd.isPos = (network) => { 24 | if (network === 'BLK' || 25 | network === 'blk') { 26 | return true; 27 | } 28 | }; 29 | 30 | shepherd.electrumJSTxDecoder = (rawtx, networkName, network) => { 31 | if (shepherd.isZcash(networkName)) { 32 | return txDecoder.zcash(rawtx, network); 33 | } else if (shepherd.isPos(networkName)) { 34 | return txDecoder.pos(rawtx, network); 35 | } else { 36 | return txDecoder.default(rawtx, network); 37 | } 38 | }; 39 | 40 | shepherd.getNetworkData = (network) => { 41 | const coin = shepherd.findNetworkObj(network) || shepherd.findNetworkObj(network.toUpperCase()) || shepherd.findNetworkObj(network.toLowerCase()); 42 | const coinUC = coin ? coin.toUpperCase() : null; 43 | 44 | if (coin === 'SUPERNET' || 45 | coin === 'REVS' || 46 | coin === 'SUPERNET' || 47 | coin === 'PANGEA' || 48 | coin === 'DEX' || 49 | coin === 'JUMBLR' || 50 | coin === 'BET' || 51 | coin === 'CRYPTO' || 52 | coin === 'COQUI' || 53 | coin === 'HODL' || 54 | coin === 'SHARK' || 55 | coin === 'MSHARK' || 56 | coin === 'BOTS' || 57 | coin === 'MGW' || 58 | coin === 'MVP' || 59 | coin === 'KV' || 60 | coin === 'CEAL' || 61 | coin === 'MESH' || 62 | coin === 'WLC' || 63 | coin === 'MNZ' || 64 | coin === 'BTCH' || 65 | coin === 'KMD' || 66 | coin === 'BEER' || 67 | coin === 'PIZZA' || 68 | coin === 'VOTE' || 69 | coin === 'KOMODO' || 70 | coinUC === 'SUPERNET' || 71 | coinUC === 'REVS' || 72 | coinUC === 'SUPERNET' || 73 | coinUC === 'PANGEA' || 74 | coinUC === 'DEX' || 75 | coinUC === 'JUMBLR' || 76 | coinUC === 'BET' || 77 | coinUC === 'CRYPTO' || 78 | coinUC === 'COQUI' || 79 | coinUC === 'HODL' || 80 | coinUC === 'SHARK' || 81 | coinUC === 'MSHARK' || 82 | coinUC === 'BOTS' || 83 | coinUC === 'MGW' || 84 | coinUC === 'MVP' || 85 | coinUC === 'KV' || 86 | coinUC === 'CEAL' || 87 | coinUC === 'MESH' || 88 | coinUC === 'WLC' || 89 | coinUC === 'MNZ' || 90 | coinUC === 'BTCH' || 91 | coinUC === 'BEER' || 92 | coinUC === 'PIZZA' || 93 | coinUC === 'VOTE' || 94 | coinUC === 'KMD' || 95 | coinUC === 'KOMODO') { 96 | return shepherd.electrumJSNetworks.komodo; 97 | } else { 98 | return shepherd.electrumJSNetworks[network]; 99 | } 100 | } 101 | 102 | shepherd.findNetworkObj = (coin) => { 103 | for (let key in shepherd.electrumServers) { 104 | if (shepherd.electrumServers[key].abbr === coin) { 105 | return key; 106 | } 107 | } 108 | } 109 | 110 | shepherd.get('/electrum/servers', (req, res, next) => { 111 | if (shepherd.checkToken(req.query.token)) { 112 | if (req.query.abbr) { 113 | let _electrumServers = {}; 114 | 115 | for (let key in shepherd.electrumServers) { 116 | _electrumServers[shepherd.electrumServers[key].abbr] = shepherd.electrumServers[key]; 117 | } 118 | 119 | const successObj = { 120 | msg: 'success', 121 | result: { 122 | servers: _electrumServers, 123 | }, 124 | }; 125 | 126 | res.end(JSON.stringify(successObj)); 127 | } else { 128 | const successObj = { 129 | msg: 'success', 130 | result: { 131 | servers: shepherd.electrumServers, 132 | }, 133 | }; 134 | 135 | res.end(JSON.stringify(successObj)); 136 | } 137 | } else { 138 | const errorObj = { 139 | msg: 'error', 140 | result: 'unauthorized access', 141 | }; 142 | 143 | res.end(JSON.stringify(errorObj)); 144 | } 145 | }); 146 | 147 | shepherd.get('/electrum/coins/server/set', (req, res, next) => { 148 | if (shepherd.checkToken(req.query.token)) { 149 | shepherd.electrumCoins[req.query.coin].server = { 150 | ip: req.query.address, 151 | port: req.query.port, 152 | }; 153 | 154 | for (let key in shepherd.electrumServers) { 155 | if (shepherd.electrumServers[key].abbr === req.query.coin) { // a bit risky 156 | shepherd.electrumServers[key].address = req.query.address; 157 | shepherd.electrumServers[key].port = req.query.port; 158 | break; 159 | } 160 | } 161 | 162 | // shepherd.log(JSON.stringify(shepherd.electrumCoins[req.query.coin], null, '\t'), true); 163 | 164 | const successObj = { 165 | msg: 'success', 166 | result: true, 167 | }; 168 | 169 | res.end(JSON.stringify(successObj)); 170 | } else { 171 | const errorObj = { 172 | msg: 'error', 173 | result: 'unauthorized access', 174 | }; 175 | 176 | res.end(JSON.stringify(errorObj)); 177 | } 178 | }); 179 | 180 | shepherd.get('/electrum/servers/test', (req, res, next) => { 181 | if (shepherd.checkToken(req.query.token)) { 182 | const ecl = new shepherd.electrumJSCore(req.query.port, req.query.address, 'tcp'); // tcp or tls 183 | 184 | ecl.connect(); 185 | ecl.serverVersion() 186 | .then((serverData) => { 187 | ecl.close(); 188 | shepherd.log('serverData', true); 189 | shepherd.log(serverData, true); 190 | 191 | if (serverData && 192 | typeof serverData === 'string' && 193 | serverData.indexOf('Electrum') > -1) { 194 | const successObj = { 195 | msg: 'success', 196 | result: true, 197 | }; 198 | 199 | res.end(JSON.stringify(successObj)); 200 | } else { 201 | const successObj = { 202 | msg: 'error', 203 | result: false, 204 | }; 205 | 206 | res.end(JSON.stringify(successObj)); 207 | } 208 | }); 209 | } else { 210 | const errorObj = { 211 | msg: 'error', 212 | result: 'unauthorized access', 213 | }; 214 | 215 | res.end(JSON.stringify(errorObj)); 216 | } 217 | }); 218 | 219 | return shepherd; 220 | }; -------------------------------------------------------------------------------- /routes/shepherd/explorer/overview.js: -------------------------------------------------------------------------------- 1 | const remoteExplorers = require('./remoteExplorers'); 2 | const request = require('request'); 3 | const fs = require('fs-extra'); 4 | const path = require('path'); 5 | 6 | let remoteExplorersArray = []; 7 | 8 | for (let key in remoteExplorers) { 9 | remoteExplorersArray.push(key); 10 | } 11 | 12 | const sortByDate = (data, sortKey) => { 13 | return data.sort(function(b, a) { 14 | if (a[sortKey] < b[sortKey]) { 15 | return -1; 16 | } 17 | 18 | if (a[sortKey] > b[sortKey]) { 19 | return 1; 20 | } 21 | 22 | return 0; 23 | }); 24 | } 25 | 26 | module.exports = (shepherd) => { 27 | shepherd.get('/explorer/overview', (req, res, next) => { 28 | if (req.query.coin) { 29 | const options = { 30 | url: `${remoteExplorers[req.query.coin]}/ext/getlasttxs/0.00000001`, 31 | method: 'GET', 32 | }; 33 | 34 | request(options, (error, response, body) => { 35 | const _parsedBody = JSON.parse(body); 36 | 37 | if (response && 38 | response.statusCode && 39 | response.statusCode === 200) { 40 | res.end(body); 41 | } else { 42 | res.end(body ? body : JSON.stringify({ 43 | result: 'error', 44 | error: { 45 | code: -777, 46 | message: `unable to retrieve remote data from remoteExplorers[req.query.coin]`, 47 | }, 48 | })); 49 | } 50 | }); 51 | } else { 52 | Promise.all(remoteExplorersArray.map((coin, index) => { 53 | shepherd.log(`explorer ${coin} overview`); 54 | 55 | return new Promise((resolve, reject) => { 56 | const options = { 57 | url: `${remoteExplorers[coin]}/ext/getlasttxs/0.00000001`, 58 | method: 'GET', 59 | }; 60 | 61 | request(options, (error, response, body) => { 62 | if (response && 63 | response.statusCode && 64 | response.statusCode === 200) { 65 | resolve({ 66 | coin, 67 | result: body, 68 | }); 69 | } else { 70 | resolve({ 71 | coin, 72 | result: 'unable to get lasttx', 73 | }); 74 | } 75 | }); 76 | }); 77 | })) 78 | .then(result => { 79 | const returnObj = { 80 | msg: 'success', 81 | result, 82 | }; 83 | 84 | res.end(JSON.stringify(returnObj)); 85 | 86 | /*if (result && 87 | result.length) { 88 | } else { 89 | const returnObj = { 90 | msg: 'success', 91 | result: _returnObj, 92 | }; 93 | 94 | res.end(JSON.stringify(returnObj)); 95 | }*/ 96 | }); 97 | } 98 | }); 99 | 100 | shepherd.get('/explorer/overview/test', (req, res, next) => { 101 | const testFileLocation = path.join(__dirname, '../explorer/test.json'); 102 | const testFile = fs.readJsonSync(testFileLocation, { throws: false }); 103 | const resSizeLimit = 1000; 104 | let items = []; 105 | 106 | for (let i = 0; i < testFile.result.length; i++) { 107 | const _parseData = JSON.parse(testFile.result[i].result).data; 108 | 109 | for (let j = 0; j < _parseData.length; j++) { 110 | items.push({ 111 | coin: testFile.result[i].coin, 112 | txid: _parseData[j].txid, 113 | blockhash: _parseData[j].blockhash, 114 | blockindex: _parseData[j].blockindex, 115 | timestamp: _parseData[j].timestamp, 116 | total: _parseData[j].total, 117 | vout: _parseData[j].vout, 118 | vin: _parseData[j].vin, 119 | }); 120 | } 121 | } 122 | 123 | items = sortByDate(items, 'timestamp'); 124 | items = items.slice(0, resSizeLimit + 1); 125 | 126 | res.end(JSON.stringify(items)); 127 | }); 128 | 129 | return shepherd; 130 | }; -------------------------------------------------------------------------------- /routes/shepherd/explorer/remoteExplorers.js: -------------------------------------------------------------------------------- 1 | const remoteExplorers = { 2 | KMD: 'http://kmd.komodochainz.info', 3 | MSHARK: 'http://MSHARK.explorer.supernet.org', 4 | REVS: 'http://revs.explorer.supernet.org', 5 | SUPERNET: 'http://SUPERNET.explorer.supernet.org', 6 | DEX: 'http://DEX.explorer.supernet.org', 7 | PANGEA: 'http://PANGEA.explorer.supernet.org', 8 | JUMBLR: 'http://JUMBLR.explorer.supernet.org', 9 | BET: 'http://BET.explorer.supernet.org', 10 | CRYPTO: 'http://CRYPTO.explorer.supernet.org', 11 | HODL: 'http://HODL.explorer.supernet.org', 12 | SHARK: 'http://SHARK.explorer.supernet.org', 13 | BOTS: 'http://BOTS.explorer.supernet.org', 14 | MGW: 'http://MGW.explorer.supernet.org', 15 | WLC: 'http://WIRELESS.explorer.supernet.org', 16 | CHIPS: 'http://CHIPS1.explorer.supernet.org', 17 | COQUI: 'https://explorer.coqui.cash', 18 | MNZ: 'https://www.mnzexplorer.com', 19 | }; 20 | 21 | module.exports = remoteExplorers; -------------------------------------------------------------------------------- /routes/shepherd/init.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); 2 | const path = require('path'); 3 | let _foldersInitRan = false; 4 | 5 | module.exports = (shepherd) => { 6 | shepherd.readVersionFile = () => { 7 | // read app version 8 | const rootLocation = path.join(__dirname, '../../'); 9 | const localVersionFile = fs.readFileSync(`${rootLocation}version`, 'utf8'); 10 | 11 | return localVersionFile; 12 | } 13 | 14 | shepherd.createAgamaDirs = () => { 15 | if (!_foldersInitRan) { 16 | const rootLocation = path.join(__dirname, '../../'); 17 | 18 | fs.readdir(rootLocation, (err, items) => { 19 | for (let i = 0; i < items.length; i++) { 20 | if (items[i].substr(0, 3) === 'gen') { 21 | console.log(items[i]); 22 | fs.unlinkSync(rootLocation + items[i]); 23 | } 24 | } 25 | }); 26 | 27 | if (!fs.existsSync(shepherd.agamaDir)) { 28 | fs.mkdirSync(shepherd.agamaDir); 29 | 30 | if (fs.existsSync(shepherd.agamaDir)) { 31 | shepherd.log(`created agama folder at ${shepherd.agamaDir}`); 32 | shepherd.writeLog(`created agama folder at ${shepherd.agamaDir}`); 33 | } 34 | } else { 35 | shepherd.log('agama folder already exists'); 36 | } 37 | 38 | if (!fs.existsSync(`${shepherd.agamaDir}/shepherd`)) { 39 | fs.mkdirSync(`${shepherd.agamaDir}/shepherd`); 40 | 41 | if (fs.existsSync(`${shepherd.agamaDir}/shepherd`)) { 42 | shepherd.log(`created shepherd folder at ${shepherd.agamaDir}/shepherd`); 43 | shepherd.writeLog(`create shepherd folder at ${shepherd.agamaDir}/shepherd`); 44 | } 45 | } else { 46 | shepherd.log('agama/shepherd folder already exists'); 47 | } 48 | 49 | if (!fs.existsSync(`${shepherd.agamaDir}/shepherd/pin`)) { 50 | fs.mkdirSync(`${shepherd.agamaDir}/shepherd/pin`); 51 | 52 | if (fs.existsSync(`${shepherd.agamaDir}/shepherd/pin`)) { 53 | shepherd.log(`created pin folder at ${shepherd.agamaDir}/shepherd/pin`); 54 | shepherd.writeLog(`create pin folder at ${shepherd.agamaDir}/shepherd/pin`); 55 | } 56 | } else { 57 | shepherd.log('shepherd/pin folder already exists'); 58 | } 59 | 60 | if (!fs.existsSync(shepherd.zcashParamsDir)) { 61 | fs.mkdirSync(shepherd.zcashParamsDir); 62 | } else { 63 | shepherd.log('zcashparams folder already exists'); 64 | } 65 | 66 | _foldersInitRan = true; 67 | } 68 | } 69 | 70 | return shepherd; 71 | }; -------------------------------------------------------------------------------- /routes/shepherd/kickstart.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); 2 | const path = require('path'); 3 | 4 | module.exports = (shepherd) => { 5 | /* 6 | * type: GET 7 | * params: coin, type 8 | */ 9 | shepherd.get('/kick', (req, res, next) => { 10 | if (shepherd.checkToken(req.query.token)) { 11 | const _coin = req.query.coin; 12 | const _keepWallet = req.query.keepwallet; 13 | 14 | if (!_coin) { 15 | const errorObj = { 16 | msg: 'error', 17 | result: 'no coin name provided', 18 | }; 19 | 20 | res.end(JSON.stringify(errorObj)); 21 | } else { 22 | const _location = path.join(_coin === 'KMD' ? shepherd.komodoDir : `${shepherd.komodoDir}/${_coin}`); 23 | 24 | if (fs.existsSync(_location)) { 25 | const items = fs.readdirSync(_location); 26 | 27 | for (let i = 0; i < items.length; i++) { 28 | if (items[i].indexOf('wallet.dat') === -1) { 29 | fs.removeSync(`${_location}/${items[i]}`); 30 | } else if (!_keepWallet) { 31 | fs.removeSync(`${_location}/${items[i]}`); 32 | } 33 | } 34 | } 35 | 36 | const successObj = { 37 | msg: 'success', 38 | result: `${_coin} native is kicked`, 39 | }; 40 | 41 | res.end(JSON.stringify(successObj)); 42 | } 43 | } else { 44 | const errorObj = { 45 | msg: 'error', 46 | result: 'unauthorized access', 47 | }; 48 | 49 | res.end(JSON.stringify(errorObj)); 50 | } 51 | }); 52 | 53 | return shepherd; 54 | }; -------------------------------------------------------------------------------- /routes/shepherd/log.js: -------------------------------------------------------------------------------- 1 | module.exports = (shepherd) => { 2 | shepherd.log = (msg, isSpvOut) => { 3 | if (shepherd.appConfig.dev || 4 | shepherd.appConfig.debug) { 5 | console.log(msg); 6 | } 7 | 8 | if (!isSpvOut) { 9 | shepherd.appRuntimeLog.push({ 10 | time: Date.now(), 11 | msg: msg, 12 | }); 13 | } else { 14 | shepherd.appRuntimeSPVLog.push({ 15 | time: Date.now(), 16 | msg: msg, 17 | }); 18 | } 19 | } 20 | 21 | shepherd.writeLog = (data) => { 22 | const logLocation = `${shepherd.agamaDir}/shepherd`; 23 | const timeFormatted = new Date(Date.now()).toLocaleString('en-US', { hour12: false }); 24 | 25 | if (shepherd.appConfig.debug) { 26 | if (shepherd.fs.existsSync(`${logLocation}/agamalog.txt`)) { 27 | shepherd.fs.appendFile(`${logLocation}/agamalog.txt`, `${timeFormatted} ${data}\r\n`, (err) => { 28 | if (err) { 29 | shepherd.log('error writing log file'); 30 | } 31 | }); 32 | } else { 33 | shepherd.fs.writeFile(`${logLocation}/agamalog.txt`, `${timeFormatted} ${data}\r\n`, (err) => { 34 | if (err) { 35 | shepherd.log('error writing log file'); 36 | } 37 | }); 38 | } 39 | } 40 | } 41 | 42 | shepherd.get('/log/runtime', (req, res, next) => { 43 | if (shepherd.checkToken(req.query.token)) { 44 | const successObj = { 45 | msg: 'success', 46 | result: req.query.spv && req.query.spv === 'true' ? shepherd.appRuntimeSPVLog : shepherd.appRuntimeLog, 47 | }; 48 | 49 | res.end(JSON.stringify(successObj)); 50 | } else { 51 | const errorObj = { 52 | msg: 'error', 53 | result: 'unauthorized access', 54 | }; 55 | 56 | res.end(JSON.stringify(errorObj)); 57 | } 58 | }); 59 | 60 | shepherd.getAppRuntimeLog = () => { 61 | return new shepherd.Promise((resolve, reject) => { 62 | resolve(shepherd.appRuntimeLog); 63 | }); 64 | }; 65 | 66 | /* 67 | * type: POST 68 | * params: payload 69 | */ 70 | shepherd.post('/guilog', (req, res, next) => { 71 | if (shepherd.checkToken(req.body.token)) { 72 | const logLocation = `${shepherd.agamaDir}/shepherd`; 73 | 74 | if (!shepherd.guiLog[shepherd.appSessionHash]) { 75 | shepherd.guiLog[shepherd.appSessionHash] = {}; 76 | } 77 | 78 | if (shepherd.guiLog[shepherd.appSessionHash][req.body.timestamp]) { 79 | shepherd.guiLog[shepherd.appSessionHash][req.body.timestamp].status = req.body.status; 80 | shepherd.guiLog[shepherd.appSessionHash][req.body.timestamp].response = req.body.response; 81 | } else { 82 | shepherd.guiLog[shepherd.appSessionHash][req.body.timestamp] = { 83 | function: req.body.function, 84 | type: req.body.type, 85 | url: req.body.url, 86 | payload: req.body.payload, 87 | status: req.body.status, 88 | }; 89 | } 90 | 91 | shepherd.fs.writeFile(`${logLocation}/agamalog.json`, JSON.stringify(shepherd.guiLog), (err) => { 92 | if (err) { 93 | shepherd.writeLog('error writing gui log file'); 94 | } 95 | 96 | const returnObj = { 97 | msg: 'success', 98 | result: 'gui log entry is added', 99 | }; 100 | 101 | res.end(JSON.stringify(returnObj)); 102 | }); 103 | } else { 104 | const errorObj = { 105 | msg: 'error', 106 | result: 'unauthorized access', 107 | }; 108 | 109 | res.end(JSON.stringify(errorObj)); 110 | } 111 | }); 112 | 113 | /* 114 | * type: GET 115 | * params: type 116 | */ 117 | shepherd.get('/getlog', (req, res, next) => { 118 | if (shepherd.checkToken(req.query.token)) { 119 | const logExt = req.query.type === 'txt' ? 'txt' : 'json'; 120 | 121 | if (shepherd.fs.existsSync(`${shepherd.agamaDir}/shepherd/agamalog.${logExt}`)) { 122 | shepherd.fs.readFile(`${shepherd.agamaDir}/shepherd/agamalog.${logExt}`, 'utf8', (err, data) => { 123 | if (err) { 124 | const errorObj = { 125 | msg: 'error', 126 | result: err, 127 | }; 128 | 129 | res.end(JSON.stringify(errorObj)); 130 | } else { 131 | const successObj = { 132 | msg: 'success', 133 | result: data ? JSON.parse(data) : '', 134 | }; 135 | 136 | res.end(JSON.stringify(successObj)); 137 | } 138 | }); 139 | } else { 140 | const errorObj = { 141 | msg: 'error', 142 | result: `agama.${logExt} doesnt exist`, 143 | }; 144 | 145 | res.end(JSON.stringify(errorObj)); 146 | } 147 | } else { 148 | const errorObj = { 149 | msg: 'error', 150 | result: 'unauthorized access', 151 | }; 152 | 153 | res.end(JSON.stringify(errorObj)); 154 | } 155 | }); 156 | 157 | shepherd.printDirs = () => { 158 | shepherd.log(`agama dir: ${shepherd.agamaDir}`); 159 | shepherd.log('--------------------------') 160 | shepherd.log(`komodo dir: ${shepherd.komododBin}`); 161 | shepherd.log(`komodo bin: ${shepherd.komodoDir}`); 162 | shepherd.writeLog(`agama dir: ${shepherd.agamaDir}`); 163 | shepherd.writeLog(`komodo dir: ${shepherd.komododBin}`); 164 | shepherd.writeLog(`komodo bin: ${shepherd.komodoDir}`); 165 | } 166 | 167 | return shepherd; 168 | }; -------------------------------------------------------------------------------- /routes/shepherd/paths.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fixPath = require('fix-path'); 3 | const os = require('os'); 4 | 5 | module.exports = (shepherd) => { 6 | shepherd.pathsAgama = () => { 7 | switch (os.platform()) { 8 | case 'darwin': 9 | fixPath(); 10 | shepherd.agamaDir = `${process.env.HOME}/Library/Application Support/Agama`; 11 | break; 12 | 13 | case 'linux': 14 | shepherd.agamaDir = `${process.env.HOME}/.agama`; 15 | break; 16 | 17 | case 'win32': 18 | shepherd.agamaDir = `${process.env.APPDATA}/Agama`; 19 | shepherd.agamaDir = path.normalize(shepherd.agamaDir); 20 | break; 21 | } 22 | } 23 | 24 | shepherd.pathsDaemons = () => { 25 | switch (os.platform()) { 26 | case 'darwin': 27 | fixPath(); 28 | shepherd.agamaTestDir = `${process.env.HOME}/Library/Application Support/Agama/test`, 29 | shepherd.komododBin = path.join(__dirname, '../../assets/bin/osx/komodod'), 30 | shepherd.komodocliBin = path.join(__dirname, '../../assets/bin/osx/komodo-cli'), 31 | shepherd.komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.HOME}/Library/Application Support/Komodo`, 32 | shepherd.zcashdBin = '/Applications/ZCashSwingWalletUI.app/Contents/MacOS/zcashd', 33 | shepherd.zcashcliBin = '/Applications/ZCashSwingWalletUI.app/Contents/MacOS/zcash-cli', 34 | shepherd.zcashDir = `${process.env.HOME}/Library/Application Support/Zcash`, 35 | shepherd.zcashParamsDir = `${process.env.HOME}/Library/Application Support/ZcashParams`, 36 | shepherd.chipsBin = path.join(__dirname, '../../assets/bin/osx/chipsd'), 37 | shepherd.chipscliBin = path.join(__dirname, '../../assets/bin/osx/chips-cli'), 38 | shepherd.chipsDir = `${process.env.HOME}/Library/Application Support/Chips`, 39 | shepherd.coindRootDir = path.join(__dirname, '../../assets/bin/osx/dex/coind'), 40 | shepherd.mmBin = path.join(__dirname, '../../node_modules/marketmaker/bin/darwin/x64/marketmaker'); 41 | break; 42 | 43 | case 'linux': 44 | shepherd.agamaTestDir = `${process.env.HOME}/.agama/test`, 45 | shepherd.komododBin = path.join(__dirname, '../../assets/bin/linux64/komodod'), 46 | shepherd.komodocliBin = path.join(__dirname, '../../assets/bin/linux64/komodo-cli'), 47 | shepherd.komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.HOME}/.komodo`, 48 | shepherd.zcashParamsDir = `${process.env.HOME}/.zcash-params`, 49 | shepherd.chipsBin = path.join(__dirname, '../../assets/bin/linux64/chipsd'), 50 | shepherd.chipscliBin = path.join(__dirname, '../../assets/bin/linux64/chips-cli'), 51 | shepherd.chipsDir = `${process.env.HOME}/.chips`, 52 | shepherd.coindRootDir = path.join(__dirname, '../../assets/bin/linux64/dex/coind'), 53 | shepherd.mmBin = path.join(__dirname, '../../node_modules/marketmaker/bin/linux/x64/marketmaker'); 54 | break; 55 | 56 | case 'win32': 57 | shepherd.agamaTestDir = `${process.env.APPDATA}/Agama/test`; 58 | shepherd.agamaTestDir = path.normalize(shepherd.agamaTestDir); 59 | shepherd.komododBin = path.join(__dirname, '../../assets/bin/win64/komodod.exe'), 60 | shepherd.komododBin = path.normalize(shepherd.komododBin), 61 | shepherd.komodocliBin = path.join(__dirname, '../../assets/bin/win64/komodo-cli.exe'), 62 | shepherd.komodocliBin = path.normalize(shepherd.komodocliBin), 63 | shepherd.komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.APPDATA}/Komodo`, 64 | shepherd.komodoDir = path.normalize(shepherd.komodoDir); 65 | shepherd.chipsBin = path.join(__dirname, '../../assets/bin/win64/chipsd.exe'), 66 | shepherd.chipsBin = path.normalize(shepherd.chipsBin), 67 | shepherd.chipscliBin = path.join(__dirname, '../../assets/bin/win64/chips-cli.exe'), 68 | shepherd.chipscliBin = path.normalize(shepherd.chipscliBin), 69 | shepherd.chipsDir = `${process.env.APPDATA}/Chips`, 70 | shepherd.chipsDir = path.normalize(shepherd.chipsDir); 71 | shepherd.zcashParamsDir = `${process.env.APPDATA}/ZcashParams`; 72 | shepherd.zcashParamsDir = path.normalize(shepherd.zcashParamsDir); 73 | shepherd.coindRootDir = path.join(__dirname, '../../assets/bin/osx/dex/coind'); 74 | shepherd.coindRootDir = path.normalize(shepherd.coindRootDir); 75 | shepherd.mmBin = path.join(__dirname, '../../node_modules/marketmaker/bin/win32/x64/marketmaker.exe'); 76 | shepherd.mmBin = path.normalize(shepherd.mmBin); 77 | break; 78 | } 79 | } 80 | 81 | return shepherd; 82 | }; -------------------------------------------------------------------------------- /routes/shepherd/pin.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); 2 | const aes256 = require('nodejs-aes256'); 3 | 4 | module.exports = (shepherd) => { 5 | /* 6 | * type: POST 7 | * params: none 8 | */ 9 | shepherd.post('/encryptkey', (req, res, next) => { 10 | if (shepherd.checkToken(req.body.token)) { 11 | if (req.body.key && 12 | req.body.string && 13 | req.body.pubkey) { 14 | const encryptedString = aes256.encrypt(req.body.key, req.body.string); 15 | 16 | // test pin security 17 | // - at least 1 char in upper case 18 | // - at least 1 digit 19 | // - at least one special character 20 | // - min length 8 21 | 22 | const _pin = req.body.key; 23 | const _pinTest = _pin.match('^(?=.*[A-Z])(?=.*[^<>{}\"/|;:.,~!?@#$%^=&*\\]\\\\()\\[_+]*$)(?=.*[0-9])(?=.*[a-z]).{8}$'); 24 | 25 | fs.writeFile(`${shepherd.agamaDir}/shepherd/pin/${req.body.pubkey}.pin`, encryptedString, (err) => { 26 | if (err) { 27 | shepherd.log('error writing pin file'); 28 | } 29 | 30 | const returnObj = { 31 | msg: 'success', 32 | result: encryptedString, 33 | }; 34 | 35 | res.end(JSON.stringify(returnObj)); 36 | }); 37 | } else { 38 | const _paramsList = [ 39 | 'key', 40 | 'string', 41 | 'pubkey' 42 | ]; 43 | let errorObj = { 44 | msg: 'error', 45 | result: '', 46 | }; 47 | let _errorParamsList = []; 48 | 49 | for (let i = 0; i < _paramsList.length; i++) { 50 | if (!req.query[_paramsList[i]]) { 51 | _errorParamsList.push(_paramsList[i]); 52 | } 53 | } 54 | 55 | errorObj.result = `missing param ${_errorParamsList.join(', ')}`; 56 | res.end(JSON.stringify(errorObj)); 57 | } 58 | } else { 59 | const errorObj = { 60 | msg: 'error', 61 | result: 'unauthorized access', 62 | }; 63 | 64 | res.end(JSON.stringify(errorObj)); 65 | } 66 | }); 67 | 68 | shepherd.post('/decryptkey', (req, res, next) => { 69 | if (shepherd.checkToken(req.body.token)) { 70 | if (req.body.key && 71 | req.body.pubkey) { 72 | if (fs.existsSync(`${shepherd.agamaDir}/shepherd/pin/${req.body.pubkey}.pin`)) { 73 | fs.readFile(`${shepherd.agamaDir}/shepherd/pin/${req.body.pubkey}.pin`, 'utf8', (err, data) => { 74 | if (err) { 75 | const errorObj = { 76 | msg: 'error', 77 | result: err, 78 | }; 79 | 80 | res.end(JSON.stringify(errorObj)); 81 | } else { 82 | const encryptedKey = aes256.decrypt(req.body.key, data); 83 | // test if stored encrypted passphrase is decrypted correctly 84 | // if not then the key is wrong 85 | const _regexTest = encryptedKey.match(/^[0-9a-zA-Z ]+$/g); 86 | let returnObj; 87 | 88 | if (!_regexTest) { 89 | returnObj = { 90 | msg: 'error', 91 | result: 'wrong key', 92 | }; 93 | } else { 94 | returnObj = { 95 | msg: 'success', 96 | result: encryptedKey, 97 | }; 98 | } 99 | 100 | res.end(JSON.stringify(returnObj)); 101 | } 102 | }); 103 | } else { 104 | const errorObj = { 105 | msg: 'error', 106 | result: `file ${req.query.pubkey}.pin doesnt exist`, 107 | }; 108 | 109 | res.end(JSON.stringify(errorObj)); 110 | } 111 | } else { 112 | const errorObj = { 113 | msg: 'error', 114 | result: 'missing key or pubkey param', 115 | }; 116 | 117 | res.end(JSON.stringify(errorObj)); 118 | } 119 | } else { 120 | const errorObj = { 121 | msg: 'error', 122 | result: 'unauthorized access', 123 | }; 124 | 125 | res.end(JSON.stringify(errorObj)); 126 | } 127 | }); 128 | 129 | shepherd.get('/getpinlist', (req, res, next) => { 130 | if (shepherd.checkToken(req.body.token)) { 131 | if (fs.existsSync(`${shepherd.agamaDir}/shepherd/pin`)) { 132 | fs.readdir(`${shepherd.agamaDir}/shepherd/pin`, (err, items) => { 133 | let _pins = []; 134 | 135 | for (let i = 0; i < items.length; i++) { 136 | if (items[i].substr(items[i].length - 4, 4) === '.pin') { 137 | _pins.push(items[i].substr(0, items[i].length - 4)); 138 | } 139 | } 140 | 141 | if (!items.length) { 142 | const errorObj = { 143 | msg: 'error', 144 | result: 'no pins', 145 | }; 146 | 147 | res.end(JSON.stringify(errorObj)); 148 | } else { 149 | const successObj = { 150 | msg: 'success', 151 | result: _pins, 152 | }; 153 | 154 | res.end(JSON.stringify(successObj)); 155 | } 156 | }); 157 | } else { 158 | const errorObj = { 159 | msg: 'error', 160 | result: 'pin folder doesnt exist', 161 | }; 162 | 163 | res.end(JSON.stringify(errorObj)); 164 | } 165 | } else { 166 | const errorObj = { 167 | msg: 'error', 168 | result: 'unauthorized access', 169 | }; 170 | 171 | res.end(JSON.stringify(errorObj)); 172 | } 173 | }); 174 | 175 | return shepherd; 176 | }; -------------------------------------------------------------------------------- /routes/shepherd/quitDaemon.js: -------------------------------------------------------------------------------- 1 | const portscanner = require('portscanner'); 2 | const execFile = require('child_process').execFile; 3 | 4 | module.exports = (shepherd) => { 5 | shepherd.quitKomodod = (timeout = 100) => { 6 | // if komodod is under heavy load it may not respond to cli stop the first time 7 | // exit komodod gracefully 8 | let coindExitInterval = {}; 9 | shepherd.lockDownAddCoin = true; 10 | 11 | for (let key in shepherd.coindInstanceRegistry) { 12 | if (shepherd.appConfig.stopNativeDaemonsOnQuit) { 13 | const chain = key !== 'komodod' ? key : null; 14 | let _coindQuitCmd = shepherd.komodocliBin; 15 | 16 | // any coind 17 | if (shepherd.nativeCoindList[key.toLowerCase()]) { 18 | _coindQuitCmd = `${shepherd.coindRootDir}/${key.toLowerCase()}/${shepherd.nativeCoindList[key.toLowerCase()].bin.toLowerCase()}-cli`; 19 | } 20 | if (key === 'CHIPS') { 21 | _coindQuitCmd = shepherd.chipscliBin; 22 | } 23 | 24 | const execCliStop = () => { 25 | let _arg = []; 26 | if (chain && 27 | !shepherd.nativeCoindList[key.toLowerCase()] && key !== 'CHIPS') { 28 | _arg.push(`-ac_name=${chain}`); 29 | 30 | if (shepherd.appConfig.dataDir.length) { 31 | _arg.push(`-datadir=${shepherd.appConfig.dataDir + (key !== 'komodod' ? '/' + key : '')}`); 32 | } 33 | } else if (key === 'komodod' && shepherd.appConfig.dataDir.length) { 34 | _arg.push(`-datadir=${shepherd.appConfig.dataDir}`); 35 | } 36 | 37 | _arg.push('stop'); 38 | execFile(`${_coindQuitCmd}`, _arg, (error, stdout, stderr) => { 39 | shepherd.log(`stdout: ${stdout}`); 40 | shepherd.log(`stderr: ${stderr}`); 41 | shepherd.log(`send stop sig to ${key}`); 42 | 43 | if (stdout.indexOf('EOF reached') > -1 || 44 | stderr.indexOf('EOF reached') > -1 || 45 | (error && error.toString().indexOf('Command failed') > -1 && !stderr) || // win "special snowflake" case 46 | stdout.indexOf('connect to server: unknown (code -1)') > -1 || 47 | stderr.indexOf('connect to server: unknown (code -1)') > -1) { 48 | delete shepherd.coindInstanceRegistry[key]; 49 | clearInterval(coindExitInterval[key]); 50 | } 51 | 52 | // workaround for AGT-65 53 | const _port = shepherd.assetChainPorts[key]; 54 | setTimeout(() => { 55 | portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => { 56 | // Status is 'open' if currently in use or 'closed' if available 57 | if (status === 'closed') { 58 | delete shepherd.coindInstanceRegistry[key]; 59 | clearInterval(coindExitInterval[key]); 60 | } 61 | }); 62 | }, 100); 63 | 64 | if (error !== null) { 65 | shepherd.log(`exec error: ${error}`); 66 | } 67 | 68 | setTimeout(() => { 69 | shepherd.killRogueProcess(key === 'CHIPS' ? 'chips-cli' : 'komodo-cli'); 70 | }, 100); 71 | }); 72 | } 73 | 74 | execCliStop(); 75 | coindExitInterval[key] = setInterval(() => { 76 | execCliStop(); 77 | }, timeout); 78 | } else { 79 | delete shepherd.coindInstanceRegistry[key]; 80 | } 81 | } 82 | } 83 | 84 | shepherd.post('/coind/stop', (req, res) => { 85 | if (shepherd.checkToken(req.body.token)) { 86 | const _chain = req.body.chain; 87 | let _coindQuitCmd = shepherd.komodocliBin; 88 | let _arg = []; 89 | 90 | if (_chain) { 91 | _arg.push(`-ac_name=${_chain}`); 92 | 93 | if (shepherd.appConfig.dataDir.length) { 94 | _arg.push(`-datadir=${shepherd.appConfig.dataDir + (_chain ? '/' + _chain : '')}`); 95 | } 96 | } else if (!_chain && shepherd.appConfig.dataDir.length) { 97 | _arg.push(`-datadir=${shepherd.appConfig.dataDir}`); 98 | } 99 | 100 | _arg.push('stop'); 101 | execFile(`${_coindQuitCmd}`, _arg, (error, stdout, stderr) => { 102 | shepherd.log(`stdout: ${stdout}`); 103 | shepherd.log(`stderr: ${stderr}`); 104 | shepherd.log(`send stop sig to ${_chain ? _chain : 'komodo'}`); 105 | 106 | if (stdout.indexOf('EOF reached') > -1 || 107 | stderr.indexOf('EOF reached') > -1 || 108 | (error && error.toString().indexOf('Command failed') > -1 && !stderr) || // win "special snowflake" case 109 | stdout.indexOf('connect to server: unknown (code -1)') > -1 || 110 | stderr.indexOf('connect to server: unknown (code -1)') > -1) { 111 | delete shepherd.coindInstanceRegistry[_chain ? _chain : 'komodod']; 112 | 113 | const obj = { 114 | msg: 'success', 115 | result: 'result', 116 | }; 117 | 118 | res.end(JSON.stringify(obj)); 119 | } else { 120 | if (stdout.indexOf('Komodo server stopping') > -1) { 121 | delete shepherd.coindInstanceRegistry[_chain ? _chain : 'komodod']; 122 | 123 | const obj = { 124 | msg: 'success', 125 | result: 'result', 126 | }; 127 | 128 | res.end(JSON.stringify(obj)); 129 | } else { 130 | const obj = { 131 | msg: 'error', 132 | result: 'result', 133 | }; 134 | 135 | res.end(JSON.stringify(obj)); 136 | } 137 | } 138 | }); 139 | } else { 140 | const errorObj = { 141 | msg: 'error', 142 | result: 'unauthorized access', 143 | }; 144 | 145 | res.end(JSON.stringify(errorObj)); 146 | } 147 | }); 148 | 149 | shepherd.post('/coins/remove', (req, res) => { 150 | if (shepherd.checkToken(req.body.token)) { 151 | const _chain = req.body.chain; 152 | 153 | if (req.body.mode === 'native') { 154 | delete shepherd.coindInstanceRegistry[_chain ? _chain : 'komodod']; 155 | 156 | const obj = { 157 | msg: 'success', 158 | result: 'result', 159 | }; 160 | 161 | res.end(JSON.stringify(obj)); 162 | } else { 163 | delete shepherd.electrumCoins[_chain === 'komodo' ? 'KMD' : _chain]; 164 | 165 | if (Object.keys(shepherd.electrumCoins).length - 1 === 0) { 166 | shepherd.electrumCoins.auth = false; 167 | shepherd.electrumKeys = {}; 168 | } 169 | 170 | const obj = { 171 | msg: 'success', 172 | result: 'result', 173 | }; 174 | 175 | res.end(JSON.stringify(obj)); 176 | } 177 | } else { 178 | const errorObj = { 179 | msg: 'error', 180 | result: 'unauthorized access', 181 | }; 182 | 183 | res.end(JSON.stringify(errorObj)); 184 | } 185 | }); 186 | 187 | return shepherd; 188 | }; 189 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | version=0.2.0.29a 2 | type=a-beta 3 | minversion=0.2.0.29 -------------------------------------------------------------------------------- /version_build: -------------------------------------------------------------------------------- 1 | 0.2.0.29a-beta -------------------------------------------------------------------------------- /windeps/CopyWinDepsFiles.bat: -------------------------------------------------------------------------------- 1 | @echo OFF 2 | 3 | reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT 4 | 5 | if %OS%==32BIT echo This is a 32bit operating system 6 | if %OS%==64BIT echo This is a 64bit operating system 7 | 8 | if %OS%==32BIT ( 9 | echo This is a 32bit operating system 10 | echo 11 | echo 12 | echo Copying x86 files to C:\Windows\System32\ ... 13 | echo 14 | echo 15 | copy /Y %USERPROFILE%\IguanaApp\resources\app\windeps\x86\ucrtbased.dll C:\Windows\System32\ 16 | copy /Y %USERPROFILE%\IguanaApp\resources\app\windeps\x86\vcruntime140d.dll C:\Windows\System32\ 17 | echo 18 | echo 19 | echo z86 Files Copied! 20 | echo 21 | echo 22 | ) 23 | 24 | if %OS%==64BIT ( 25 | echo This is a 64bit operating system 26 | echo 27 | echo Copying x86 files to C:\Windows\SysWOW64\ ... 28 | echo 29 | copy /Y %USERPROFILE%\IguanaApp\resources\app\windeps\x86\ucrtbased.dll C:\Windows\SysWOW64\ 30 | copy /Y %USERPROFILE%\IguanaApp\resources\app\windeps\x86\vcruntime140d.dll C:\Windows\SysWOW64\ 31 | echo 32 | echo x86 Files Copied! 33 | echo 34 | echo Copying x64 files to C:\Windows\System32\ ... 35 | echo 36 | copy /Y %USERPROFILE%\IguanaApp\resources\app\windeps\x64\ucrtbased.dll C:\Windows\System32\ 37 | copy /Y %USERPROFILE%\IguanaApp\resources\app\windeps\x64\vcruntime140d.dll C:\Windows\System32\ 38 | echo 39 | echo x64 Files Copied! 40 | ) 41 | 42 | echo 43 | echo 44 | echo If you see 0 files copied message, 45 | echo make sure to run this script as Administrator. 46 | echo Right click the file or link and select option "Run As Administrator" 47 | echo 48 | echo 49 | pause -------------------------------------------------------------------------------- /windeps/ReadMe.md: -------------------------------------------------------------------------------- 1 | ### Dependency DLL files for Windows 2 | 3 | These dependency DLL files are tested on Windows 7 x64 (64bit), and Windows 10 x64 (64bit) windows. 4 | 5 | The DLL files are required for `iguana.exe`. 6 | 7 | #### For 64bit Windows 7 and Windows 10, do this: 8 | 9 | 10 | 1. Copy files from **x64** directory and paste it under `C:\Windows\System32\` 11 | 12 | 2. Copy files from **x86** directory and paste it under `C:\Windows\SysWOW64\` 13 | 14 | 15 | #### For 32bit Windows 7 and Windows 10 (if there's any 32bit Windows 10 etc.) 16 | 17 | 18 | 2. Copy files from **x86** directory and paste it under `C:\Windows\System32\` 19 | 20 | Now iguana.exe should work fine. -------------------------------------------------------------------------------- /windeps/x64/ucrtbased.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/windeps/x64/ucrtbased.dll -------------------------------------------------------------------------------- /windeps/x64/vcruntime140d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/windeps/x64/vcruntime140d.dll -------------------------------------------------------------------------------- /windeps/x86/ucrtbased.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/windeps/x86/ucrtbased.dll -------------------------------------------------------------------------------- /windeps/x86/vcruntime140d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SuperNETorg/Agama/c969b85942f3b7993c92995ce17cf5aef6c1f19c/windeps/x86/vcruntime140d.dll --------------------------------------------------------------------------------