├── .gitignore ├── LICENSE ├── README.md ├── assets └── screenshot.png ├── commands └── start.js ├── debug.js ├── index.js ├── package-lock.json ├── package.json ├── src └── .gitkeep ├── test └── .gitkeep ├── truffle-plugin.json └── ui ├── .gitignore ├── README.md ├── build ├── asset-manifest.json ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json ├── robots.txt └── static │ ├── css │ ├── main.cbe58bb4.chunk.css │ └── main.cbe58bb4.chunk.css.map │ └── js │ ├── 2.ff18b484.chunk.js │ ├── 2.ff18b484.chunk.js.LICENSE.txt │ ├── 2.ff18b484.chunk.js.map │ ├── 3.c7b18d5c.chunk.js │ ├── 3.c7b18d5c.chunk.js.map │ ├── main.16c0b3de.chunk.js │ ├── main.16c0b3de.chunk.js.map │ ├── runtime-main.776f02b0.js │ └── runtime-main.776f02b0.js.map ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── App.css ├── App.test.tsx ├── App.tsx ├── components │ ├── Accounts.tsx │ ├── DebugTooltip.tsx │ ├── Debugger.tsx │ ├── Home.tsx │ ├── KeyboardShortcuts.tsx │ ├── Line.tsx │ ├── Navigation.tsx │ ├── Settings.tsx │ ├── Source.tsx │ ├── Sources.tsx │ ├── StatusIcon.tsx │ ├── StatusMessage.tsx │ ├── SyntaxStyle.tsx │ ├── Tab.tsx │ ├── Tabs.tsx │ ├── Transaction.tsx │ ├── Tray.tsx │ └── Variables.tsx ├── index.css ├── index.tsx ├── react-app-env.d.ts ├── reportWebVitals.ts ├── setupTests.ts ├── styles │ ├── H3.tsx │ ├── Icon.tsx │ ├── IconBase.tsx │ ├── List.tsx │ ├── Loading.tsx │ ├── LoadingSmall.tsx │ ├── MetaWrapper.tsx │ ├── PrimaryButton.tsx │ ├── Tab.tsx │ ├── TabButton.tsx │ ├── Tooltip.tsx │ └── colors.ts ├── types │ └── truffle.d.ts └── utils │ ├── getDecodedValue.ts │ └── getWeb3.ts ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2021 ConsenSys 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Truffle Visual Debugger 2 | 3 | Debug all the things! 4 | 5 | ![screenshot](assets/screenshot.png) 6 | 7 | ## Installation 8 | 9 | Begin by adding to your Truffle project via the following: 10 | 11 | ``` 12 | npm i truffle-plugin-debugger 13 | ``` 14 | 15 | Add the following to your `truffle-config.json`: 16 | 17 | ``` 18 | plugins: [ 19 | "truffle-plugin-debugger" 20 | ] 21 | ``` 22 | 23 | ## Usage 24 | 25 | To run the plugin, simply run the following command from the root of your project: 26 | 27 | ``` 28 | truffle run debug 29 | ``` 30 | 31 | The list available commands is currently as follows: 32 | 33 | - [start](#start) 34 | 35 | 36 | ### `Start` 37 | 38 | The following starts the debugger... 39 | 40 | ``` 41 | truffle run debug start 42 | ``` 43 | 44 | If all goes well you should see the following output... 45 | 46 | ``` 47 | Starting Visual Debugger... 48 | Started and listening at http://localhost:54321 49 | ``` 50 | 51 | Open the [link](http://localhost:54321) and off you go! 52 | 53 | ## Support 54 | 55 | Support for this plugin is available via the Truffle community available [here](https://www.trufflesuite.com/community). -------------------------------------------------------------------------------- /assets/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/assets/screenshot.png -------------------------------------------------------------------------------- /commands/start.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | const bodyParser = require('body-parser') 4 | const port = 54321; 5 | const fs = require('fs'); 6 | var cors = require('cors'); 7 | 8 | const debug = async (config) => { 9 | 10 | app.use(bodyParser.json()); 11 | app.use('/debug', express.static(`${__dirname}/../ui/build`)); 12 | app.use(cors()); 13 | 14 | console.log(`Starting Visual Debugger...`); 15 | 16 | try { 17 | 18 | app.get('/test', (req, res) => { 19 | 20 | res.send(`${__dirname}/../ui/build`); 21 | 22 | }); 23 | 24 | app.get('/status', (req, res) => { 25 | res.send('Visual Debugger is listening...'); 26 | }); 27 | 28 | app.get('/artifacts', (req, res) => { 29 | 30 | const contractPath = config.contracts_build_directory || `${__dirname}/sample/`; 31 | const artifacts = []; 32 | 33 | fs.readdirSync(contractPath).forEach(file => { 34 | if (file === ".DS_Store") return; // TODO - a more elegant exclusion list 35 | 36 | data = fs.readFileSync(`${contractPath}/${file}`, "utf8"); 37 | artifacts.push(JSON.parse(data)); 38 | }); 39 | 40 | res.json(artifacts); 41 | }); 42 | 43 | app.use(function(req, res) { 44 | res.redirect('/debug'); 45 | }); 46 | 47 | app.listen(port, () => { 48 | console.log(`Started and listening at http://localhost:${port}`) 49 | }); 50 | 51 | } catch (err) { 52 | console.log(`An error occurred starting the listener:\n\n${err}`); 53 | } 54 | 55 | } 56 | 57 | module.exports = debug; -------------------------------------------------------------------------------- /debug.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | 3 | const debug = require("./commands/start"); 4 | 5 | module.exports = (config) => { 6 | 7 | if (config.help) { 8 | console.log(`Usage: truffle run debug [command]`); 9 | console.log(`Commands: debug`); 10 | return; 11 | } 12 | 13 | if (config._.length < 2) { 14 | console.log("No command provided. Run truffle run debug --help to see the full list."); 15 | return; 16 | } 17 | 18 | switch (config._[1]) { 19 | case "start": 20 | debug(config); 21 | break; 22 | default: 23 | console.log("Command not found. Run truffle run debug --help to see the full list."); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const debug = require('./debug'); 2 | 3 | const config = { 4 | _: [ 5 | "", 6 | "debug" 7 | ] 8 | }; 9 | 10 | debug(config); -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "truffle-plugin-debugger", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.7", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 11 | "requires": { 12 | "mime-types": "~2.1.24", 13 | "negotiator": "0.6.2" 14 | } 15 | }, 16 | "array-flatten": { 17 | "version": "1.1.1", 18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 20 | }, 21 | "body-parser": { 22 | "version": "1.19.0", 23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 24 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 25 | "requires": { 26 | "bytes": "3.1.0", 27 | "content-type": "~1.0.4", 28 | "debug": "2.6.9", 29 | "depd": "~1.1.2", 30 | "http-errors": "1.7.2", 31 | "iconv-lite": "0.4.24", 32 | "on-finished": "~2.3.0", 33 | "qs": "6.7.0", 34 | "raw-body": "2.4.0", 35 | "type-is": "~1.6.17" 36 | } 37 | }, 38 | "bytes": { 39 | "version": "3.1.0", 40 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 41 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 42 | }, 43 | "content-disposition": { 44 | "version": "0.5.3", 45 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 46 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 47 | "requires": { 48 | "safe-buffer": "5.1.2" 49 | } 50 | }, 51 | "content-type": { 52 | "version": "1.0.4", 53 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 54 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 55 | }, 56 | "cookie": { 57 | "version": "0.4.0", 58 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 59 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 60 | }, 61 | "cookie-signature": { 62 | "version": "1.0.6", 63 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 64 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 65 | }, 66 | "cors": { 67 | "version": "2.8.5", 68 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 69 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 70 | "requires": { 71 | "object-assign": "^4", 72 | "vary": "^1" 73 | } 74 | }, 75 | "debug": { 76 | "version": "2.6.9", 77 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 78 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 79 | "requires": { 80 | "ms": "2.0.0" 81 | } 82 | }, 83 | "depd": { 84 | "version": "1.1.2", 85 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 86 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 87 | }, 88 | "destroy": { 89 | "version": "1.0.4", 90 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 91 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 92 | }, 93 | "dotenv": { 94 | "version": "8.2.0", 95 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", 96 | "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" 97 | }, 98 | "ee-first": { 99 | "version": "1.1.1", 100 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 101 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 102 | }, 103 | "encodeurl": { 104 | "version": "1.0.2", 105 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 106 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 107 | }, 108 | "escape-html": { 109 | "version": "1.0.3", 110 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 111 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 112 | }, 113 | "etag": { 114 | "version": "1.8.1", 115 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 116 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 117 | }, 118 | "express": { 119 | "version": "4.17.1", 120 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 121 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 122 | "requires": { 123 | "accepts": "~1.3.7", 124 | "array-flatten": "1.1.1", 125 | "body-parser": "1.19.0", 126 | "content-disposition": "0.5.3", 127 | "content-type": "~1.0.4", 128 | "cookie": "0.4.0", 129 | "cookie-signature": "1.0.6", 130 | "debug": "2.6.9", 131 | "depd": "~1.1.2", 132 | "encodeurl": "~1.0.2", 133 | "escape-html": "~1.0.3", 134 | "etag": "~1.8.1", 135 | "finalhandler": "~1.1.2", 136 | "fresh": "0.5.2", 137 | "merge-descriptors": "1.0.1", 138 | "methods": "~1.1.2", 139 | "on-finished": "~2.3.0", 140 | "parseurl": "~1.3.3", 141 | "path-to-regexp": "0.1.7", 142 | "proxy-addr": "~2.0.5", 143 | "qs": "6.7.0", 144 | "range-parser": "~1.2.1", 145 | "safe-buffer": "5.1.2", 146 | "send": "0.17.1", 147 | "serve-static": "1.14.1", 148 | "setprototypeof": "1.1.1", 149 | "statuses": "~1.5.0", 150 | "type-is": "~1.6.18", 151 | "utils-merge": "1.0.1", 152 | "vary": "~1.1.2" 153 | } 154 | }, 155 | "finalhandler": { 156 | "version": "1.1.2", 157 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 158 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 159 | "requires": { 160 | "debug": "2.6.9", 161 | "encodeurl": "~1.0.2", 162 | "escape-html": "~1.0.3", 163 | "on-finished": "~2.3.0", 164 | "parseurl": "~1.3.3", 165 | "statuses": "~1.5.0", 166 | "unpipe": "~1.0.0" 167 | } 168 | }, 169 | "forwarded": { 170 | "version": "0.1.2", 171 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 172 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 173 | }, 174 | "fresh": { 175 | "version": "0.5.2", 176 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 177 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 178 | }, 179 | "http-errors": { 180 | "version": "1.7.2", 181 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 182 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 183 | "requires": { 184 | "depd": "~1.1.2", 185 | "inherits": "2.0.3", 186 | "setprototypeof": "1.1.1", 187 | "statuses": ">= 1.5.0 < 2", 188 | "toidentifier": "1.0.0" 189 | } 190 | }, 191 | "iconv-lite": { 192 | "version": "0.4.24", 193 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 194 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 195 | "requires": { 196 | "safer-buffer": ">= 2.1.2 < 3" 197 | } 198 | }, 199 | "inherits": { 200 | "version": "2.0.3", 201 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 202 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 203 | }, 204 | "ipaddr.js": { 205 | "version": "1.9.1", 206 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 207 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 208 | }, 209 | "media-typer": { 210 | "version": "0.3.0", 211 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 212 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 213 | }, 214 | "merge-descriptors": { 215 | "version": "1.0.1", 216 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 217 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 218 | }, 219 | "methods": { 220 | "version": "1.1.2", 221 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 222 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 223 | }, 224 | "mime": { 225 | "version": "1.6.0", 226 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 227 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 228 | }, 229 | "mime-db": { 230 | "version": "1.47.0", 231 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", 232 | "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" 233 | }, 234 | "mime-types": { 235 | "version": "2.1.30", 236 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", 237 | "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", 238 | "requires": { 239 | "mime-db": "1.47.0" 240 | } 241 | }, 242 | "ms": { 243 | "version": "2.0.0", 244 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 245 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 246 | }, 247 | "negotiator": { 248 | "version": "0.6.2", 249 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 250 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 251 | }, 252 | "object-assign": { 253 | "version": "4.1.1", 254 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 255 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 256 | }, 257 | "on-finished": { 258 | "version": "2.3.0", 259 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 260 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 261 | "requires": { 262 | "ee-first": "1.1.1" 263 | } 264 | }, 265 | "parseurl": { 266 | "version": "1.3.3", 267 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 268 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 269 | }, 270 | "path-to-regexp": { 271 | "version": "0.1.7", 272 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 273 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 274 | }, 275 | "proxy-addr": { 276 | "version": "2.0.6", 277 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", 278 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", 279 | "requires": { 280 | "forwarded": "~0.1.2", 281 | "ipaddr.js": "1.9.1" 282 | } 283 | }, 284 | "qs": { 285 | "version": "6.7.0", 286 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 287 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 288 | }, 289 | "range-parser": { 290 | "version": "1.2.1", 291 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 292 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 293 | }, 294 | "raw-body": { 295 | "version": "2.4.0", 296 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 297 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 298 | "requires": { 299 | "bytes": "3.1.0", 300 | "http-errors": "1.7.2", 301 | "iconv-lite": "0.4.24", 302 | "unpipe": "1.0.0" 303 | } 304 | }, 305 | "safe-buffer": { 306 | "version": "5.1.2", 307 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 308 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 309 | }, 310 | "safer-buffer": { 311 | "version": "2.1.2", 312 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 313 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 314 | }, 315 | "send": { 316 | "version": "0.17.1", 317 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 318 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 319 | "requires": { 320 | "debug": "2.6.9", 321 | "depd": "~1.1.2", 322 | "destroy": "~1.0.4", 323 | "encodeurl": "~1.0.2", 324 | "escape-html": "~1.0.3", 325 | "etag": "~1.8.1", 326 | "fresh": "0.5.2", 327 | "http-errors": "~1.7.2", 328 | "mime": "1.6.0", 329 | "ms": "2.1.1", 330 | "on-finished": "~2.3.0", 331 | "range-parser": "~1.2.1", 332 | "statuses": "~1.5.0" 333 | }, 334 | "dependencies": { 335 | "ms": { 336 | "version": "2.1.1", 337 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 338 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 339 | } 340 | } 341 | }, 342 | "serve-static": { 343 | "version": "1.14.1", 344 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 345 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 346 | "requires": { 347 | "encodeurl": "~1.0.2", 348 | "escape-html": "~1.0.3", 349 | "parseurl": "~1.3.3", 350 | "send": "0.17.1" 351 | } 352 | }, 353 | "setprototypeof": { 354 | "version": "1.1.1", 355 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 356 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 357 | }, 358 | "statuses": { 359 | "version": "1.5.0", 360 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 361 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 362 | }, 363 | "toidentifier": { 364 | "version": "1.0.0", 365 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 366 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 367 | }, 368 | "type-is": { 369 | "version": "1.6.18", 370 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 371 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 372 | "requires": { 373 | "media-typer": "0.3.0", 374 | "mime-types": "~2.1.24" 375 | } 376 | }, 377 | "unpipe": { 378 | "version": "1.0.0", 379 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 380 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 381 | }, 382 | "utils-merge": { 383 | "version": "1.0.1", 384 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 385 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 386 | }, 387 | "vary": { 388 | "version": "1.1.2", 389 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 390 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 391 | } 392 | } 393 | } 394 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "truffle-plugin-debugger", 3 | "version": "0.0.2", 4 | "description": "", 5 | "main": "debug.js", 6 | "scripts": { 7 | "start-dev": "cd ui && yarn start", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "body-parser": "^1.19.0", 15 | "cors": "^2.8.5", 16 | "dotenv": "^8.2.0", 17 | "express": "^4.17.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/src/.gitkeep -------------------------------------------------------------------------------- /test/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/test/.gitkeep -------------------------------------------------------------------------------- /truffle-plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands": { 3 | "debug": "debug.js" 4 | } 5 | } -------------------------------------------------------------------------------- /ui/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /ui/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `yarn start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `yarn test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `yarn build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `yarn eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | -------------------------------------------------------------------------------- /ui/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "./static/css/main.cbe58bb4.chunk.css", 4 | "main.js": "./static/js/main.16c0b3de.chunk.js", 5 | "main.js.map": "./static/js/main.16c0b3de.chunk.js.map", 6 | "runtime-main.js": "./static/js/runtime-main.776f02b0.js", 7 | "runtime-main.js.map": "./static/js/runtime-main.776f02b0.js.map", 8 | "static/js/2.ff18b484.chunk.js": "./static/js/2.ff18b484.chunk.js", 9 | "static/js/2.ff18b484.chunk.js.map": "./static/js/2.ff18b484.chunk.js.map", 10 | "static/js/3.c7b18d5c.chunk.js": "./static/js/3.c7b18d5c.chunk.js", 11 | "static/js/3.c7b18d5c.chunk.js.map": "./static/js/3.c7b18d5c.chunk.js.map", 12 | "index.html": "./index.html", 13 | "static/css/main.cbe58bb4.chunk.css.map": "./static/css/main.cbe58bb4.chunk.css.map", 14 | "static/js/2.ff18b484.chunk.js.LICENSE.txt": "./static/js/2.ff18b484.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.776f02b0.js", 18 | "static/js/2.ff18b484.chunk.js", 19 | "static/css/main.cbe58bb4.chunk.css", 20 | "static/js/main.16c0b3de.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /ui/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/ui/build/favicon.ico -------------------------------------------------------------------------------- /ui/build/index.html: -------------------------------------------------------------------------------- 1 | Truffle Visual Debbuger
-------------------------------------------------------------------------------- /ui/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/ui/build/logo192.png -------------------------------------------------------------------------------- /ui/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/ui/build/logo512.png -------------------------------------------------------------------------------- /ui/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /ui/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /ui/build/static/css/main.cbe58bb4.chunk.css: -------------------------------------------------------------------------------- 1 | body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.App-body,body{background-color:#f8f5f0}.App-body{display:flex;flex-direction:column;font-size:1.2rem} 2 | /*# sourceMappingURL=main.cbe58bb4.chunk.css.map */ -------------------------------------------------------------------------------- /ui/build/static/css/main.cbe58bb4.chunk.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://src/index.css","webpack://src/App.css"],"names":[],"mappings":"AAAA,KACE,QAAS,CACT,mJAEY,CACZ,kCAAmC,CACnC,iCACF,CAEA,KACE,yEAEF,CCRA,eAHE,wBAQF,CALA,UAEE,YAAa,CACb,qBAAsB,CACtB,gBACF","file":"main.cbe58bb4.chunk.css","sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n","body {\n background-color: #F8F5F0;\n}\n\n.App-body {\n background-color: #F8F5F0;\n display: flex;\n flex-direction: column;\n font-size: 1.2rem;\n}"]} -------------------------------------------------------------------------------- /ui/build/static/js/2.ff18b484.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /*! 8 | * Determine if an object is a Buffer 9 | * 10 | * @author Feross Aboukhadijeh 11 | * @license MIT 12 | */ 13 | 14 | /*! 15 | * The buffer module from node.js, for the browser. 16 | * 17 | * @author Feross Aboukhadijeh 18 | * @license MIT 19 | */ 20 | 21 | /*! 22 | * The buffer module from node.js, for the browser. 23 | * 24 | * @author Feross Aboukhadijeh 25 | * @license MIT 26 | */ 27 | 28 | /*! https://mths.be/punycode v1.4.1 by @mathias */ 29 | 30 | /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ 31 | 32 | /*! safe-buffer. MIT License. Feross Aboukhadijeh */ 33 | 34 | /** 35 | * [js-sha3]{@link https://github.com/emn178/js-sha3} 36 | * 37 | * @version 0.5.7 38 | * @author Chen, Yi-Cyuan [emn178@gmail.com] 39 | * @copyright Chen, Yi-Cyuan 2015-2016 40 | * @license MIT 41 | */ 42 | 43 | /** 44 | * [js-sha3]{@link https://github.com/emn178/js-sha3} 45 | * 46 | * @version 0.8.0 47 | * @author Chen, Yi-Cyuan [emn178@gmail.com] 48 | * @copyright Chen, Yi-Cyuan 2015-2018 49 | * @license MIT 50 | */ 51 | 52 | /** @license React v0.20.2 53 | * scheduler.production.min.js 54 | * 55 | * Copyright (c) Facebook, Inc. and its affiliates. 56 | * 57 | * This source code is licensed under the MIT license found in the 58 | * LICENSE file in the root directory of this source tree. 59 | */ 60 | 61 | /** @license React v16.13.1 62 | * react-is.production.min.js 63 | * 64 | * Copyright (c) Facebook, Inc. and its affiliates. 65 | * 66 | * This source code is licensed under the MIT license found in the 67 | * LICENSE file in the root directory of this source tree. 68 | */ 69 | 70 | /** @license React v17.0.2 71 | * react-dom.production.min.js 72 | * 73 | * Copyright (c) Facebook, Inc. and its affiliates. 74 | * 75 | * This source code is licensed under the MIT license found in the 76 | * LICENSE file in the root directory of this source tree. 77 | */ 78 | 79 | /** @license React v17.0.2 80 | * react-jsx-runtime.production.min.js 81 | * 82 | * Copyright (c) Facebook, Inc. and its affiliates. 83 | * 84 | * This source code is licensed under the MIT license found in the 85 | * LICENSE file in the root directory of this source tree. 86 | */ 87 | 88 | /** @license React v17.0.2 89 | * react.production.min.js 90 | * 91 | * Copyright (c) Facebook, Inc. and its affiliates. 92 | * 93 | * This source code is licensed under the MIT license found in the 94 | * LICENSE file in the root directory of this source tree. 95 | */ 96 | -------------------------------------------------------------------------------- /ui/build/static/js/3.c7b18d5c.chunk.js: -------------------------------------------------------------------------------- 1 | (this.webpackJsonpui=this.webpackJsonpui||[]).push([[3],{1577:function(t,e,n){"use strict";n.r(e),n.d(e,"getCLS",(function(){return m})),n.d(e,"getFCP",(function(){return g})),n.d(e,"getFID",(function(){return F})),n.d(e,"getLCP",(function(){return k})),n.d(e,"getTTFB",(function(){return C}));var i,a,r,o,u=function(t,e){return{name:t,value:void 0===e?-1:e,delta:0,entries:[],id:"v1-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},c=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},s=function(t,e){var n=function n(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(t(i),e&&(removeEventListener("visibilitychange",n,!0),removeEventListener("pagehide",n,!0)))};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},f=function(t){addEventListener("pageshow",(function(e){e.persisted&&t(e)}),!0)},d="function"==typeof WeakSet?new WeakSet:new Set,p=function(t,e,n){var i;return function(){e.value>=0&&(n||d.has(e)||"hidden"===document.visibilityState)&&(e.delta=e.value-(i||0),(e.delta||void 0===i)&&(i=e.value,t(e)))}},m=function(t,e){var n,i=u("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),n())},r=c("layout-shift",a);r&&(n=p(t,i,e),s((function(){r.takeRecords().map(a),n()})),f((function(){i=u("CLS",0),n=p(t,i,e)})))},v=-1,l=function(){return"hidden"===document.visibilityState?0:1/0},h=function(){s((function(t){var e=t.timeStamp;v=e}),!0)},S=function(){return v<0&&(v=l(),h(),f((function(){setTimeout((function(){v=l(),h()}),0)}))),{get timeStamp(){return v}}},g=function(t,e){var n,i=S(),a=u("FCP"),r=c("paint",(function(t){"first-contentful-paint"===t.name&&(r&&r.disconnect(),t.startTime=0&&a1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,e){var n=function(){E(t,e),a()},i=function(){a()},a=function(){removeEventListener("pointerup",n,y),removeEventListener("pointercancel",i,y)};addEventListener("pointerup",n,y),addEventListener("pointercancel",i,y)}(e,t):E(e,t)}},b=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(e){return t(e,T,y)}))},F=function(t,e){var n,r=S(),m=u("FID"),v=function(t){t.startTime=0&&(n||u.has(t)||\"hidden\"===document.visibilityState)&&(t.delta=t.value-(i||0),(t.delta||void 0===i)&&(i=t.value,e(t)))}},f=function(e,t){var n,i=a(\"CLS\",0),u=function(e){e.hadRecentInput||(i.value+=e.value,i.entries.push(e),n())},f=r(\"layout-shift\",u);f&&(n=s(e,i,t),o((function(){f.takeRecords().map(u),n()})),c((function(){i=a(\"CLS\",0),n=s(e,i,t)})))},m=-1,v=function(){return\"hidden\"===document.visibilityState?0:1/0},d=function(){o((function(e){var t=e.timeStamp;m=t}),!0)},p=function(){return m<0&&(m=v(),d(),c((function(){setTimeout((function(){m=v(),d()}),0)}))),{get timeStamp(){return m}}},l=function(e,t){var n,i=p(),o=a(\"FCP\"),f=r(\"paint\",(function(e){\"first-contentful-paint\"===e.name&&(f&&f.disconnect(),e.startTime=0&&t1e12?new Date:performance.now())-e.timeStamp;\"pointerdown\"==e.type?function(e,t){var n=function(){y(e,t),a()},i=function(){a()},a=function(){removeEventListener(\"pointerup\",n,h),removeEventListener(\"pointercancel\",i,h)};addEventListener(\"pointerup\",n,h),addEventListener(\"pointercancel\",i,h)}(t,e):y(t,e)}},w=function(e){[\"mousedown\",\"keydown\",\"touchstart\",\"pointerdown\"].forEach((function(t){return e(t,E,h)}))},L=function(n,f){var m,v=p(),d=a(\"FID\"),l=function(e){e.startTime0)}),[a]),Object(En.jsxs)(re,{isCurrent:r,ref:o,children:[Object(En.jsx)(ie,{className:O?"fas fa-dot-circle":"fas fa-dot-circle faded",isBreakpoint:O,onClick:h}),Object(En.jsxs)(ce,{children:[Object(En.jsxs)(ae,{onClick:h,children:[" ".repeat(j),e+1,"."," "]}),Object(En.jsx)("span",{dangerouslySetInnerHTML:{__html:t}})]})]},"contract-source-".concat(e))},se=f.a.div(U||(U=Object(j.a)(["\n padding: 1rem 0.5rem;\n overflow-x: scroll;\n overflow-y: scroll;\n white-space: nowrap;\n"]))),le=function(n){var e,t=n.activeLine,r=n.selectedLine,a=n.contractSource,i=n.breakpoints,o=n.setBreakpoints,l=n.visible,u=n.sourceIsActive,d=n.sourceId,b=n.fileName,j=n.astId,f=[],p=Object(c.useState)(0),O=Object(s.a)(p,2),m=O[0],h=O[1],x=Object(c.useRef)(null),g=a.length.toString().length;a.forEach((function(n){var a=Object(c.createRef)();f.length===r&&(e=a),f.push(Object(En.jsx)(oe,{lineNumber:f.length,lineContents:n,isCurrent:u&&f.length===t,breakpoints:i,setBreakpoints:o,lineRef:a,sourceId:d,fileName:b,astId:j,lineNumberIndentLength:g-(f.length+1).toString().length},"contract-source-".concat(f.length)))})),Object(c.useEffect)((function(){e&&e.current&&e.current.scrollIntoView({behavior:"auto",block:"center"})}),[r]),Object(c.useLayoutEffect)((function(){l&&null!==x.current&&x.current.scrollTo({top:m,left:0,behavior:"auto"})}),[l]);return Object(En.jsx)(En.Fragment,{children:l?Object(En.jsx)(se,{onScroll:function(n){h(n.target.scrollTop)},ref:x,children:Object(En.jsx)(ee,{children:f})}):null})},ue=t(799),de=t.n(ue),be=t(800),je=t(321),fe=t.n(je),pe=t(317),Oe=function(n){var e=n.sources,t=n.activeTabIndex,r=n.breakpoints,a=n.setBreakpoints,i=n.activeLine,o=n.selectedLine,l=n.runningTabIndex,u=Object(c.useState)([]),b=Object(s.a)(u,2),j=b[0],f=b[1],p=e.map((function(n,e){var c=n.ast.id,s=n.sourcePath.replace(/^.*[\\/]/,""),u=[];if(0===j.length){fe.a.registerLanguage("solidity",pe.definer);var b=fe.a.highlight("solidity",n.source).value;de()().use(be.a).stringify({type:"root",children:b}).toString().split("\n").forEach((function(n){u.push(n)})),f((function(n){return[].concat(Object(d.a)(n),[u])}))}return Object(En.jsx)(le,{visible:c===t,contractSource:u.length>0?u:j[e],activeLine:i,selectedLine:o,breakpoints:r,setBreakpoints:a,sourceIsActive:c===l,sourceId:n.id,astId:c,fileName:s},"contract-".concat(c))}));return Object(En.jsx)(En.Fragment,{children:p})},me=t(223),he=function n(e){var t=e.type.typeClass;if(e.error)return"NA";if("magic"===t){var r=e.type.variable;if("block"===r||"message"===r||"transaction"===r)return e.value}return"contract"===t?e.value.address:"int"===t||"uint"===t?e.value.asBN.toString():"bool"===t?e.value.asBoolean:"string"===t?e.value.asString:"bytes"===t?e.value.asHex:"address"===t?e.value.asAddress:"struct"===t?e.value.map((function(e){var t=e.name,r=e.value;return Object(me.a)({},t,n(r))})).reduce((function(n,e){return Object.assign(n,e)}),{}):"array"===t?e.value.map(n):"".concat(t," is currently not supported")},xe=t(802),ge=t.n(xe),ve=f.a.div(R||(R=Object(j.a)(["\n background: ",';\n padding: 1rem;\n border-radius: 1rem;\n font-family: "Ubuntu Mono", monospace;\n margin-bottom: 1.25rem;\n font-size: 1em;\n * {\n background-color: inherit !important;\n font-family: "Ubuntu Mono", monospace;\n }\n ul,\n ul li {\n margin-top: 0em !important;\n paddding-top: 0em !important;\n }\n overflow-x: scroll;\n overflow-y: scroll;\n'])),wn),ye=function(n){var e=n.variables,t={};e&&Object.keys(e).forEach((function(n){var r=he(e[n]);t[n]=r}));return Object(En.jsx)(ve,{children:Object(En.jsx)(ge.a,{name:null,src:t,displayDataTypes:!1,collapseStringsAfterLength:34,collapsed:1})})},ke=f.a.div(P||(P=Object(j.a)(["\n background: ",";\n padding: 1rem;\n border-radius: 1rem;\n font-size: 1em;\n overflow-x: scroll;\n overflow-y: scroll;\n"])),wn),we=f.a.div(_||(_=Object(j.a)(["\n margin: 0.1rem 0;\n cursor: pointer;\n padding: 0.25rem 0.1rem;\n border-width: 0.1rem;\n border-radius: 0.5rem;\n\n &:hover {\n background-color: ",";\n }\n"])),"#f4f4f4"),Te=f.a.span(M||(M=Object(j.a)(["\n margin-left: 0.4rem;\n"]))),Se=f.a.span(z||(z=Object(j.a)(["\n color: ",";\n"])),gn),Ie=f.a.span(V||(V=Object(j.a)(["\n background: ",";\n border: solid 1px ",";\n border-radius: 0.5rem;\n padding: 0.025rem 0.2rem;\n color: #fff;\n"])),Tn,"#967e75"),Ne=f.a.span(D||(D=Object(j.a)(["\n color: ",";\n margin-left: 0.25rem;\n"])),Tn),Ae=function(n){var e=n.breakpoints,t=n.setBreakpoints,r=n.setActiveTabIndex,c=n.setSelectedLine,a=function(n,r){var c=e.filter((function(e){return e.line!==r||e.sourceId!==n}));t(c)},i=e.map((function(n,e){var t=n.sourceId,i=n.fileName,o=n.line,s=n.astId;return Object(En.jsxs)(we,{children:[Object(En.jsx)(Se,{className:"fas fa-dot-circle",onClick:function(){return a(t,o)}}),Object(En.jsxs)(Te,{onClick:function(){return function(n,e){r(n),c(e)}(s,o)},children:[i,Object(En.jsx)(Ie,{children:o+1})]}),Object(En.jsx)(Ne,{className:"fas fa-times-circle",onClick:function(){return a(t,o)}})]},"tray-breakpoint-".concat(e))}));return Object(En.jsx)(ke,{children:i.length>0?i:"Add a breakpoint by clicking to the left of the line"})},Ce="25px",Ee=f.a.i(H||(H=Object(j.a)(["\n width: ",";\n height: ",";\n display: inline-flex;\n justify-content: center;\n align-items: center;\n border-radius: 4px;\n"])),Ce,Ce),Be=Object(f.b)(G||(G=Object(j.a)(["\n from {\n transform: rotate(0deg);\n }\n\n to {\n transform: rotate(360deg);\n }\n"]))),Fe=Object(f.a)(Ee)(J||(J=Object(j.a)(["\n animation: "," 2s linear infinite;\n"])),Be),Le=function(n){var e=n.className,t=void 0===e?"":e;return Object(En.jsx)(Fe,{className:"fal fa-spinner ".concat(t)})},Ue="25px",Re=f.a.i(K||(K=Object(j.a)(["\n width: ",";\n height: ",";\n display: inline-flex;\n justify-content: center;\n align-items: center;\n border-radius: 4px;\n"])),Ue,Ue),Pe=Object(f.a)(Re)(W||(W=Object(j.a)(["\n color: ",";\n"])),"#00A311"),_e=Object(f.a)(Re)(q||(q=Object(j.a)(["\n color: ",";\n"])),gn),Me=function(n){var e=n.status;return Object(En.jsx)(En.Fragment,{children:null===e?Object(En.jsx)(Le,{}):e?Object(En.jsx)(Pe,{className:"fas fa-check-circle",title:"Transaction Succeeded"}):Object(En.jsx)(_e,{className:"fas fa-times-circle",title:"Transaction Failed"})})},ze="0.5rem",Ve=(f.a.div(X||(X=Object(j.a)(["\n background: ",";\n padding: ",";\n border-radius: ",";\n"])),wn,"1.5rem",ze),f.a.div(Q||(Q=Object(j.a)(["\n grid-template-columns: 3.5fr 1.5fr;\n display: grid;\n"])))),De=f.a.div(Y||(Y=Object(j.a)(["\n background: ",";\n border: solid 1px ",";\n color: ",";\n padding: 1rem 1rem;\n margin-top: 1rem;\n border-radius: ",';\n font-family: "Ubuntu Mono", monospace;\n font-size: 1rem;\n\n > * {\n &:not(:last-child) {\n margin: 0 0.2rem 0 0;\n }\n }\n'])),"#fbe9e9",Sn,Sn,ze),He=function(n){var e,t,r=n.returnValue;if((null===r||void 0===r?void 0:r.length)>0)switch(r[0].kind){case"revert":e="VM Exception while processing transaction",t="".concat(r[0].kind," -- ").concat(r[0].arguments[0].value.value.asString);break;case"selfdestruct":case"return":default:return Object(En.jsx)(En.Fragment,{})}return Object(En.jsx)(En.Fragment,{children:r?Object(En.jsx)(Ve,{children:Object(En.jsx)(De,{children:"".concat(e,": ").concat(t)})}):null})},Ge="0.3125rem",Je="".concat("0.125rem"," ").concat("solid"," ").concat("#5e464d"),Ke="\n border-top: ".concat(Je,";\n border-bottom: ").concat(Je,";\n border-left: ").concat(Je,";\n border-right: 0px;\n padding: 0.5rem 1.5rem;\n text-decoration: none;\n &:first-child {\n border-radius: ").concat(Ge," 0 0 ").concat(Ge,";\n }\n &:last-child {\n border-radius: 0 ").concat(Ge," ").concat(Ge," 0;\n border-right: ").concat(Je,";\n }\n &:only-child {\n border-radius: ").concat(Ge,';\n }\n cursor: pointer;\n text-transform: uppercase;\n font-size: 1rem;\n font-family: "Fira Sans", sans-serif;\n'),We=(f.a.button(Z||(Z=Object(j.a)(["\n ","\n background: transparent;\n color: ",";\n"])),Ke,p),f.a.div($||($=Object(j.a)(["\n ","\n /* To make sure padding works in tag */\n display: inline-block;\n background: ",";\n color: ",";\n"])),Ke,(function(n){return n.selected?p:"transparent"}),(function(n){return n.selected?"white":p}))),qe=Object(f.a)(We)(nn||(nn=Object(j.a)(["\n background: ",";\n border-color: "," !important;\n color: inherit;\n text-transform: none;\n\n &:hover {\n background: ",";\n color: ",";\n * {\n color: ",";\n }\n }\n\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n flex-basis: auto;\n position: relative;\n"])),(function(n){var e=n.activeTabIndex,t=n.index;return"".concat(e===t?"#CAF0E5":yn)}),vn,vn,yn,yn),Xe=f.a.div(en||(en=Object(j.a)(["\n color: ",";\n font-size: 0.6em;\n vertical-align: middle;\n position: absolute;\n right: 0.6rem;\n top: 0.9rem;\n"])),"#dc9e5b"),Qe=function(n){var e=n.index,t=n.tabName,r=n.activeTabIndex,c=n.setActiveTabIndex,a=n.tabIsRunning;return Object(En.jsx)(En.Fragment,{children:Object(En.jsxs)(qe,{onClick:function(){return c(e)},selected:r===e,activeTabIndex:r,index:e,children:[t," ",a?Object(En.jsx)(Xe,{className:"fas fa-dot-circle"}):null]})})},Ye=f.a.div(tn||(tn=Object(j.a)(["\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n"]))),Ze=function(n){var e=n.sources,t=n.setActiveTabIndex,r=n.activeTabIndex,c=n.runningTabIndex,a=e.map((function(n){var e=n.sourcePath.replace(/^.*[\\/]/,""),a=n.ast.id;return Object(En.jsx)(Qe,{index:a,tabName:e,setActiveTabIndex:t,activeTabIndex:r,tabIsRunning:a===c},"contract-".concat(a))}));return Object(En.jsx)(Ye,{children:a})},$e=("".concat("#636363"),function(n){n.title;var e=n.children;return Object(En.jsx)(En.Fragment,{children:e})}),nt=t(803),et=function(n){var e=n.executeAction,t=n.start,r={STEP_OVER:function(){e("over")},STEP_INTO:function(){e("into")},STEP_OUT:function(){e("out")},CONTINUE_UNTIL:function(){e("continueUntil")},RESTART:function(){t()}};return Object(En.jsx)(nt.GlobalHotKeys,{keyMap:{STEP_OVER:["o","f10"],STEP_INTO:["i","f11"],STEP_OUT:["u","shift+f11"],CONTINUE_UNTIL:["c","f8"],RESTART:["r"]},handlers:r,allowChanges:!0})},tt=f.a.div(rn||(rn=Object(j.a)(["\n > * {\n &:not(:last-child) {\n margin-bottom: ",";\n }\n }\n"])),(function(n){var e=n.marginBottom;return void 0===e?"1rem":e})),rt=t(804),ct=t.n(rt),at=f.a.div(cn||(cn=Object(j.a)(["\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n"]))),it=function(n){return Object(En.jsx)(at,Object(Yn.a)(Object(Yn.a)({},n),{},{children:Object(En.jsx)(ct.a,{color:O})}))},ot=t(144),st=t.n(ot),lt=t(807),ut=t(808),dt=t(809),bt=t.n(dt),jt=t(38),ft=Object(f.a)(tt)(an||(an=Object(j.a)(["\n height: 90vh;\n display: grid;\n grid-template-rows: auto auto auto 1fr;\n grid-template-columns: 1fr;\n padding: 1rem 2rem;\n"]))),pt=Object(f.a)(An)(on||(on=Object(j.a)(["\n margin: 0 0 2.5rem;\n grid-row: 1;\n"]))),Ot=f.a.div(sn||(sn=Object(j.a)(["\n grid-row: 2;\n"]))),mt=f.a.div(ln||(ln=Object(j.a)(["\n grid-row: 3;\n display: grid;\n grid-template-columns: minmax(36rem, 3.5fr) 1.5fr;\n grid-column-gap: 1.25rem;\n"]))),ht=f.a.div(un||(un=Object(j.a)(["\n overflow-y: overlay;\n grid-row: 4;\n display: grid;\n grid-template-columns: minmax(36rem, 3.5fr) 1.5fr;\n grid-column-gap: 1.25rem;\n"]))),xt=f.a.div(dn||(dn=Object(j.a)(["\n * {\n align-self: flex-end;\n }\n"]))),gt=Object(f.a)(An)(bn||(bn=Object(j.a)(["\n align-self: flex-end;\n"]))),vt=Object(f.a)(An)(jn||(jn=Object(j.a)(["\n margin-bottom: 1rem;\n"]))),yt=f.a.span(fn||(fn=Object(j.a)(["\n font-weight: lighter;\n"]))),kt=Object(f.a)(ne)(pn||(pn=Object(j.a)(["\n width: 4rem;\n margin: 0 0.5rem 1rem 0;\n"]))),wt=Object(f.a)(kt)(On||(On=Object(j.a)(["\n .fa-sync-alt {\n max-height: 0.5rem;\n overflow: hidden;\n position: relative;\n top: -0.25rem;\n left: 0.2rem;\n }\n\n .fa-circle {\n position: relative;\n top: 0.05rem;\n left: -0.48rem;\n font-size: 0.35rem;\n }\n"]))),Tt=f.a.div(mn||(mn=Object(j.a)(["\n grid-column: 1;\n display: grid;\n overflow-x: auto;\n overflow-y: auto;\n background: ",";\n border-radius: 1rem;\n"])),wn),St=f.a.div(hn||(hn=Object(j.a)(["\n grid-column: 2;\n display: grid;\n grid-template-rows: minmax(30%, 60%) 3rem auto;\n"]))),It=Object(f.a)(it)(xn||(xn=Object(j.a)(["\n min-height: 18rem;\n"]))),Nt=function(n){Object(Wn.a)(n);var e=Object(c.useState)(null),t=Object(s.a)(e,2),r=t[0],a=t[1],i=Object(c.useState)(null),o=Object(s.a)(i,2),l=o[0],d=o[1],j=Object(c.useState)(null),f=Object(s.a)(j,2),p=f[0],O=f[1],m=Object(c.useState)(null),h=Object(s.a)(m,2),x=h[0],g=h[1],v=Object(c.useState)([]),y=Object(s.a)(v,2),k=y[0],w=y[1],T=Object(c.useState)(null),S=Object(s.a)(T,2),I=S[0],N=S[1],A=Object(c.useState)(0),C=Object(s.a)(A,2),E=C[0],B=C[1],F=Object(c.useState)(0),L=Object(s.a)(F,2),U=L[0],R=L[1],P=Object(c.useState)(0),_=Object(s.a)(P,2),M=_[0],z=_[1],V=Object(c.useState)(0),D=Object(s.a)(V,2),H=D[0],G=D[1],J=Object(jt.f)(),K=J.txHash,W=J.port,q="http://127.0.0.1:".concat(W),X={hash:K},Q=bt.a.create({url:q}),Y=function(){var n=Object(b.a)(u.a.mark((function n(){var e,t,r,c,i,o,s,l,b,j;return u.a.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return d(null),a(null),O(null),w([]),n.next=6,$n.a.get("http://127.0.0.1:54321/artifacts");case 6:return e=n.sent,t=e.data,(r={compilations:[]}).compilations=lt.Compilations.Utils.shimArtifacts(t),n.next=12,st.a.forTx(X.hash,Object(Yn.a)({provider:Q},r));case 12:return c=n.sent,i=c.connect(),n.next=16,i.ready();case 16:return n.next=18,Object(ut.getTransactionSourcesBeforeStarting)(c);case 18:return o=n.sent,s=o.map((function(n){return parseInt(n.id,10)})),l=r.compilations[0].sources.filter((function(n,e){return s.includes(e)})),g(l),a(i),n.t0=d,n.next=26,i.variables();case 26:return n.t1=n.sent,(0,n.t0)(n.t1),n.t2=O,n.next=31,i.returnValue();case 31:return n.t3=n.sent,(0,n.t2)(n.t3),n.t4=N,n.next=36,i.state.evm.transaction.status;case 36:return n.t5=n.sent,(0,n.t4)(n.t5),n.next=40,i.view(st.a.selectors.solidity.current.source);case 40:b=n.sent,G(b.ast.id),z(b.ast.id),j=i.view(st.a.selectors.solidity.current.sourceRange),R(j.lines.start.line),B(j.lines.start.line);case 46:case"end":return n.stop()}}),n)})));return function(){return n.apply(this,arguments)}}(),Z=function(){var n=Object(b.a)(u.a.mark((function n(e){var t,c;return u.a.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:if(!r){n.next=40;break}n.t0=e,n.next="continueUntil"===n.t0?4:"over"===n.t0?10:"into"===n.t0?13:"out"===n.t0?16:19;break;case 4:return n.next=6,r.removeAllBreakpoints();case 6:return k.forEach(function(){var n=Object(b.a)(u.a.mark((function n(e){return u.a.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,r.addBreakpoint(e);case 2:return n.abrupt("return",n.sent);case 3:case"end":return n.stop()}}),n)})));return function(e){return n.apply(this,arguments)}}()),n.next=9,r.continueUntilBreakpoint();case 9:return n.abrupt("break",20);case 10:return n.next=12,r.stepOver();case 12:return n.abrupt("break",20);case 13:return n.next=15,r.stepInto();case 15:return n.abrupt("break",20);case 16:return n.next=18,r.stepOut();case 18:case 19:return n.abrupt("break",20);case 20:return n.t1=d,n.next=23,r.variables();case 23:return n.t2=n.sent,(0,n.t1)(n.t2),n.t3=O,n.next=28,r.returnValue();case 28:return n.t4=n.sent,(0,n.t3)(n.t4),n.next=32,r.view(st.a.selectors.solidity.current.source);case 32:return t=n.sent,G(t.ast.id),z(t.ast.id),n.next=37,r.view(st.a.selectors.solidity.current.sourceRange);case 37:c=n.sent,R(c.lines.start.line),B(c.lines.start.line);case 40:case"end":return n.stop()}}),n)})));return function(e){return n.apply(this,arguments)}}();return Object(c.useEffect)((function(){Y()}),[]),Object(En.jsxs)(ft,{children:[Object(En.jsx)(et,{executeAction:Z,start:Y}),Object(En.jsxs)(pt,{children:[Object(En.jsx)(Me,{status:I})," ",Object(En.jsxs)(yt,{children:["TX"," ",X.hash||"..."]}),Object(En.jsx)(He,{returnValue:p})]}),Object(En.jsxs)(Ot,{children:[Object(En.jsx)($e,{title:"Continue (F8 or c)",children:Object(En.jsx)(kt,{disabled:!l,onClick:function(){return Z("continueUntil")},children:Object(En.jsx)("i",{className:"fas fa-play"})})}),Object(En.jsx)($e,{title:"Step Over (F10 or o)",children:Object(En.jsxs)(wt,{onClick:function(){return Z("over")},disabled:!l,children:[Object(En.jsx)("i",{className:"fa fa-sync-alt"}),Object(En.jsx)("i",{className:"fa fa-circle"})]})}),Object(En.jsx)($e,{title:"Step Into (F11 or i)",children:Object(En.jsx)(kt,{onClick:function(){return Z("into")},disabled:!l,children:Object(En.jsx)("i",{className:"fas fa-arrow-to-bottom"})})}),Object(En.jsx)($e,{title:"Step Out (Shift+F10 or u)",children:Object(En.jsx)(kt,{onClick:function(){return Z("out")},disabled:!l,children:Object(En.jsx)("i",{className:"fas fa-arrow-to-top"})})}),Object(En.jsx)($e,{title:"Restart (r)",children:Object(En.jsx)(kt,{onClick:Y,children:Object(En.jsx)("i",{className:"fas fa-redo-alt"})})})]}),l?Object(En.jsxs)(En.Fragment,{children:[Object(En.jsxs)(mt,{children:[Object(En.jsx)(xt,{children:Object(En.jsx)(Ze,{sources:x,setActiveTabIndex:z,activeTabIndex:M,runningTabIndex:H})}),Object(En.jsx)(gt,{children:"Variables"})]}),Object(En.jsxs)(ht,{children:[Object(En.jsx)(Tt,{children:Object(En.jsx)(Oe,{sources:x,activeTabIndex:M,activeLine:U,selectedLine:E,breakpoints:k,setBreakpoints:w,runningTabIndex:H})}),Object(En.jsxs)(St,{children:[Object(En.jsx)(ye,{variables:l}),Object(En.jsx)(vt,{children:"Breakpoints"}),Object(En.jsx)(Ae,{breakpoints:k,setBreakpoints:w,setActiveTabIndex:z,setSelectedLine:B})]})]})]}):Object(En.jsx)(It,{})]})};var At=function(){var n=Object(c.useState)(7545),e=Object(s.a)(n,2),t=e[0],r=e[1],a=Object(c.useState)("localhost"),i=Object(s.a)(a,2),o=i[0],l=i[1];return Object(En.jsx)(Cn.a,{basename:"/debug",children:Object(En.jsxs)(jt.c,{children:[Object(En.jsx)(jt.a,{path:"/",exact:!0,children:Object(En.jsx)("div",{className:"App",children:Object(En.jsxs)("div",{className:"App-body",children:[Object(En.jsx)(Qn,{}),Object(En.jsx)(Mn,{port:t})]})})}),Object(En.jsx)(jt.a,{path:"/accounts",exact:!0,children:Object(En.jsx)("div",{className:"App",children:Object(En.jsxs)("div",{className:"App-body",children:[Object(En.jsx)(Qn,{}),Object(En.jsx)(Kn,{port:t})]})})}),Object(En.jsx)(jt.a,{path:"/settings",exact:!0,children:Object(En.jsx)("div",{className:"App",children:Object(En.jsxs)("div",{className:"App-body",children:[Object(En.jsx)(Qn,{}),Object(En.jsx)(Dn,{port:t,setPort:r,rpc:o,setRpc:l})]})})}),Object(En.jsx)(jt.a,{path:"/:txHash/:port",children:Object(En.jsx)("div",{className:"App",children:Object(En.jsxs)("div",{className:"App-body",children:[Object(En.jsx)(Qn,{}),Object(En.jsx)(Nt,{})]})})})]})})},Ct=function(n){n&&n instanceof Function&&t.e(3).then(t.bind(null,1577)).then((function(e){var t=e.getCLS,r=e.getFID,c=e.getFCP,a=e.getLCP,i=e.getTTFB;t(n),r(n),c(n),a(n),i(n)}))};o.a.render(Object(En.jsx)(a.a.StrictMode,{children:Object(En.jsx)(At,{})}),document.getElementById("root")),Ct()},817:function(n,e,t){},818:function(n,e,t){},832:function(n,e){},838:function(n,e){},858:function(n,e){},860:function(n,e){},899:function(n,e){},916:function(n,e){},918:function(n,e){},950:function(n,e){},952:function(n,e){},953:function(n,e){},958:function(n,e){},960:function(n,e){},967:function(n,e){},969:function(n,e){},987:function(n,e){},989:function(n,e){}},[[1569,1,2]]]); 2 | //# sourceMappingURL=main.16c0b3de.chunk.js.map -------------------------------------------------------------------------------- /ui/build/static/js/main.16c0b3de.chunk.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../node_modules/web3-eth-accounts/src sync","styles/colors.ts","styles/H3.tsx","components/Transaction.tsx","utils/getWeb3.ts","components/Home.tsx","components/Settings.tsx","components/Accounts.tsx","components/Navigation.tsx","styles/PrimaryButton.tsx","components/SyntaxStyle.tsx","components/Line.tsx","components/Source.tsx","components/Sources.tsx","utils/getDecodedValue.ts","components/Variables.tsx","components/Tray.tsx","styles/Icon.tsx","styles/LoadingSmall.tsx","styles/IconBase.tsx","components/StatusIcon.tsx","styles/MetaWrapper.tsx","components/StatusMessage.tsx","styles/TabButton.tsx","styles/Tab.tsx","components/Tab.tsx","components/Tabs.tsx","components/DebugTooltip.tsx","components/KeyboardShortcuts.tsx","styles/List.tsx","styles/Loading.tsx","components/Debugger.tsx","App.tsx","reportWebVitals.ts","index.tsx"],"names":["webpackEmptyContext","req","e","Error","code","keys","resolve","module","exports","id","Mode","MILK_CHOCOLATE","DARK_CHOCOLATE","rgba","r","g","b","a","CI_RED","TEAL_1","WHITE","GRAY_300","CHOCOLATE_200","CHOCOLATE_400","RED_600","MINT_400","H3","styled","h3","Colors","TransactionWrapper","div","Transaction","transaction","port","to","hash","blockNumber","getWeb3","provider","Web3","providers","WebsocketProvider","headers","Origin","web3","HomeContainer","TransactionsBox","Home","useState","transactions","setTransactions","getPendingTransactions","subscription","eth","subscribe","error","result","console","log","on","txHash","getTransaction","txn","Date","now","prev","unsubscribe","useEffect","length","filter","v","i","SettingsContainer","SettingsForm","form","Settings","setPort","rpc","setRpc","newPort","setNewPort","newRpc","setNewRpc","onSubmit","preventDefault","type","value","onChange","target","AccountsContainer","AccountsBox","Account","Accounts","accounts","setAccounts","getAccounts","list","map","NavBarContainer","NavBar","ul","Navigation","className","style","color","button","SyntaxStyle","backgroundInherit","Row","isCurrent","LineContainer","span","LineNumber","Breakpoint","isBreakpoint","Line","lineNumber","lineContents","breakpoints","setBreakpoints","lineRef","sourceId","fileName","astId","lineNumberIndentLength","updateBreakpoint","toggleBreakpoint","filteredBreakpoints","breakpoint","line","compilationId","ref","onClick","repeat","dangerouslySetInnerHTML","__html","SourceWrapper","Source","selectedLineRef","activeLine","selectedLine","contractSource","visible","sourceIsActive","output","scrollTop","setScrollTop","sourceRef","useRef","lineDigitLength","toString","forEach","createRef","push","current","scrollIntoView","behavior","block","useLayoutEffect","scrollTo","top","left","onScroll","Sources","sources","activeTabIndex","runningTabIndex","sourcesWithMarkup","setSourcesWithMarkup","sourceComponents","source","index","ast","sourcePath","replace","highlightedSource","low","registerLanguage","definer","tree","highlight","unified","use","stringify","children","split","lineMarkup","prevState","getDecodedValue","inputObj","typeClass","variable","address","asBN","asBoolean","asString","asHex","asAddress","name","reduce","acc","curr","Object","assign","VariablesWrapper","Variables","variables","state","src","displayDataTypes","collapseStringsAfterLength","collapsed","TrayWrapper","Icon","Badge","Remove","Tray","setActiveTabIndex","setSelectedLine","removeBreakpoint","jumptoLine","size","rotate","keyframes","StyledIcon","TxSuccess","IconBase","TxFail","StatusIcon","status","LoadingSmall","title","radius","Wrapper","StatusContainer","StatusMessage","statusDescription","statusMessage","returnValue","kind","arguments","borderRadius","border","Tab","TabButtonStyle","selected","TabButton","StyledTab","ActiveIcon","tabName","tabIsRunning","TabsWrapper","Tabs","tabs","DebugTooltip","KeyboardShortcuts","executeAction","start","handlers","STEP_OVER","STEP_INTO","STEP_OUT","CONTINUE_UNTIL","RESTART","keyMap","allowChanges","List","marginBottom","Loading","props","DebuggerWrapper","Header","ButtonsWrapper","TopRowWrapper","SourceRowWrapper","VariablesTitle","BreakpointsTitle","TxHash","DebugButton","PrimaryButton","DebugButtonOver","RightColumnWrapper","LoadingWrapper","Debugger","session","setSession","setVariables","setReturnValue","setSources","setStatus","setActiveLine","setRunningTabIndex","useParams","providerUrl","Provider","create","url","axios","get","res","artifacts","data","input","compilations","Codec","Utils","shimArtifacts","TruffleDebugger","forTx","bugger","initializedSession","connect","ready","getTransactionSourcesBeforeStarting","sourcesInvolvedInTransaction","sourceIndicesInvolvedInTransaction","parseInt","_","includes","evm","view","selectors","solidity","currentSource","init","sourceRange","lines","debugAction","removeAllBreakpoints","addBreakpoint","continueUntilBreakpoint","stepOver","stepInto","stepOut","disabled","App","basename","path","exact","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","ReactDOM","render","StrictMode","document","getElementById"],"mappings":"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","file":"static/js/main.16c0b3de.chunk.js","sourcesContent":["function webpackEmptyContext(req) {\n\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\te.code = 'MODULE_NOT_FOUND';\n\tthrow e;\n}\nwebpackEmptyContext.keys = function() { return []; };\nwebpackEmptyContext.resolve = webpackEmptyContext;\nmodule.exports = webpackEmptyContext;\nwebpackEmptyContext.id = 1012;","// Neutrals\nexport const DARK_CREAM = \"#e0dad7\";\nexport const MILK_CHOCOLATE = \"#5e464d\";\nexport const DARK_CHOCOLATE = \"#33262a\";\n\n// Brand Primaries\nexport const PURPLE_1 = \"#8731e8\";\n\n// Utilities\nexport const rgba = (r: number, g: number, b: number) => (a: number): string =>\n `rgba(${r},${g},${b},${a})`;\n\nexport enum Mode {\n LIGHT = \"light\",\n DARK = \"dark\",\n}\n\nexport const CI_GREEN = \"#00A311\";\nexport const CI_YELLOW = \"#f2e941\";\nexport const CI_RED = \"#d60000\";\n\nexport const BLUE_LINK = \"#25a9e0\";\nexport const BLUE_LINK_ON_LIGHT_CREAM = \"#0070a3\";\nexport const BLUE_LINK_ON_DARK_CREAM = \"#005279\";\n\nexport const GREY = \"rgba(0, 0, 0, 0.5)\";\n\nexport const LIGHT_YELLOW = \"#f5f3c5\";\n\nexport const TAG_BORDER_YELLOW = \"rgb(242, 233, 65)\";\nexport const TAG_BORDER_BEIGE = \"rgb(224, 218, 215)\";\n\nexport const TEAL_1 = \"#47BAA7\";\nexport const TEAL_2 = \"#CAF0E5\";\n\nexport const ALTO = \"#DCDCDC\";\nexport const RGBA_ALTO = rgba(0xdc, 0xdc, 0xdc);\n\nexport const DANUBE = \"#6c88d1\";\nexport const RGBA_DANUBE = rgba(0x6c, 0x88, 0xd1);\n\nexport const GUARDSMANRED = \"#d10000\";\nexport const RGBA_GUARDSMANRED = rgba(0xd1, 0, 0);\n\nexport const SPRINGWOOD = \"#f8f5f0\";\nexport const RGBA_SPRINGWOOD = rgba(0xf8, 0xf5, 0xf0);\n\n/*\nDESIGN SYSTEM COLORS\n*/\n\n/*\n * NEUTRALS\n */\n\n// GRAY\nexport const WHITE = \"#ffffff\";\nexport const GRAY_100 = \"#f4f4f4\";\nexport const GRAY_200 = \"#e5e5e5\";\nexport const GRAY_300 = \"#c8c8c8\";\nexport const GRAY_400 = \"#a9a9a9\";\nexport const GRAY_500 = \"#858585\";\nexport const GRAY_600 = \"#636363\";\nexport const GRAY_700 = \"#4a4a4a\";\nexport const GRAY_800 = \"#363636\";\nexport const GRAY_900 = \"#292929\";\nexport const BLACK = \"#000000\";\n\n// Chocolate\nexport const CHOCOLATE_100 = \"#f8f5f0\";\nexport const CHOCOLATE_200 = \"#efe5dc\";\nexport const CHOCOLATE_300 = \"#d6c4ba\";\nexport const CHOCOLATE_400 = \"#bca296\";\nexport const CHOCOLATE_500 = \"#967e75\";\nexport const CHOCOLATE_600 = \"#725b54\";\nexport const CHOCOLATE_700 = \"#56443f\";\nexport const CHOCOLATE_800 = \"#3f302d\";\nexport const CHOCOLATE_900 = \"#2f2323\";\n\n/*\n * COLORS\n */\n\n// WATERMELON\nexport const WATERMELON_100 = \"#ffeff4\";\nexport const WATERMELON_200 = \"#ffd9e5\";\nexport const WATERMELON_300 = \"#ffadc8\";\nexport const WATERMELON_400 = \"#ff7ea9\";\nexport const WATERMELON_500 = \"#dc5985\";\nexport const WATERMELON_600 = \"#b3004f\";\nexport const WATERMELON_700 = \"#87003e\";\nexport const WATERMELON_800 = \"#690030\";\nexport const WATERMELON_900 = \"#540026\";\n\n// PINK\nexport const PINK_100 = \"#fdeaf9\";\nexport const PINK_200 = \"#fbcef2\";\nexport const PINK_300 = \"#f698e3\";\nexport const PINK_400 = \"#f05ed2\";\nexport const PINK_500 = \"#ea1bc0\";\nexport const PINK_600 = \"#b50d93\";\nexport const PINK_700 = \"#870a6e\";\nexport const PINK_800 = \"#630750\";\nexport const PINK_900 = \"#4b053d\";\n\n// RED\nexport const RED_100 = \"#fbe9e9\";\nexport const RED_200 = \"#f7cbcb\";\nexport const RED_300 = \"#ed9191\";\nexport const RED_400 = \"#e35353\";\nexport const RED_500 = \"#d80b0b\";\nexport const RED_600 = \"#a60000\";\nexport const RED_700 = \"#7c0000\";\nexport const RED_800 = \"#5b0000\";\nexport const RED_900 = \"#450000\";\n\n// ORANGE\nexport const ORANGE_100 = \"#fff3e4\";\nexport const ORANGE_200 = \"#ffe0be\";\nexport const ORANGE_300 = \"#fbbd7a\";\nexport const ORANGE_400 = \"#dc9e5b\";\nexport const ORANGE_500 = \"#b87a37\";\nexport const ORANGE_600 = \"#965815\";\nexport const ORANGE_700 = \"#7a4101\";\nexport const ORANGE_800 = \"#592f01\";\nexport const ORANGE_900 = \"#442401\";\n\n// PORSCHE\nexport const PORSCHE_1 = \"#e4a663\";\n\n// YELLOW\nexport const YELLOW_100 = \"#fffdde\";\nexport const YELLOW_200 = \"#fffbbc\";\nexport const YELLOW_300 = \"#e9e26f\";\nexport const YELLOW_400 = \"#d1cb57\";\nexport const YELLOW_500 = \"#b6b03c\";\nexport const YELLOW_600 = \"#7b7619\";\nexport const YELLOW_700 = \"#69651a\";\nexport const YELLOW_800 = \"#3f3b01\";\nexport const YELLOW_900 = \"#302d01\";\n\n// BRUSH\nexport const BRUSH_100 = \"#f9ffe2\";\nexport const BRUSH_200 = \"#eef6cc\";\nexport const BRUSH_300 = \"#c6d38e\";\nexport const BRUSH_400 = \"#a7b46f\";\nexport const BRUSH_500 = \"#83904b\";\nexport const BRUSH_600 = \"#616e29\";\nexport const BRUSH_700 = \"#485510\";\nexport const BRUSH_800 = \"#354001\";\nexport const BRUSH_900 = \"#293101\";\n\n// GREEN\nexport const GREEN_100 = \"#effcf0\";\nexport const GREEN_200 = \"#e3f8e6\";\nexport const GREEN_300 = \"#b5edba\";\nexport const GREEN_400 = \"#81e28c\";\nexport const GREEN_500 = \"#2ed047\";\nexport const GREEN_600 = \"#00850f\";\nexport const GREEN_700 = \"#005507\";\nexport const GREEN_800 = \"#003b06\";\nexport const GREEN_900 = \"#002b04\";\n\n// MINT\nexport const MINT_100 = \"#ddfff9\";\nexport const MINT_200 = \"#c8fbf2\";\nexport const MINT_300 = \"#90f4e3\";\nexport const MINT_400 = \"#3fe0c5\";\nexport const MINT_500 = \"#17b89d\";\nexport const MINT_600 = \"#007d65\";\nexport const MINT_700 = \"#005a49\";\nexport const MINT_800 = \"#004135\";\nexport const MINT_900 = \"#003127\";\n\n// BLUE\nexport const BLUE_100 = \"#edfaff\";\nexport const BLUE_200 = \"#daf4fc\";\nexport const BLUE_300 = \"#a0e4f8\";\nexport const BLUE_400 = \"#64d2f4\";\nexport const BLUE_500 = \"#39b0de\";\nexport const BLUE_600 = \"#0070a3\";\nexport const BLUE_700 = \"#005279\";\nexport const BLUE_800 = \"#003b56\";\nexport const BLUE_900 = \"#002c40\";\n\n// PERIWINKLE\nexport const PERIWINKLE_100 = \"#f0f5ff\";\nexport const PERIWINKLE_200 = \"#d9e6ff\";\nexport const PERIWINKLE_300 = \"#adcbff\";\nexport const PERIWINKLE_400 = \"#8eace0\";\nexport const PERIWINKLE_500 = \"#6a88bc\";\nexport const PERIWINKLE_600 = \"#48669a\";\nexport const PERIWINKLE_700 = \"#2f4d81\";\nexport const PERIWINKLE_800 = \"#1b396d\";\nexport const PERIWINKLE_900 = \"#0e2c60\";\n\n// PURPLE\nexport const PURPLE_100 = \"#f5edfd\";\nexport const PURPLE_200 = \"#e7d5fa\";\nexport const PURPLE_300 = \"#cba6f5\";\nexport const PURPLE_400 = \"#ae74ef\";\nexport const PURPLE_500 = \"#8c3ae9\";\nexport const PURPLE_600 = \"#6926b4\";\nexport const PURPLE_700 = \"#4e1c87\";\nexport const PURPLE_800 = \"#391562\";\nexport const PURPLE_900 = \"#2b104b\";\n","import styled from \"styled-components\";\nimport * as Colors from \"./colors\";\n\nconst H3 = styled.h3`\n font-family: \"Oswald\", sans-serif;\n font-size: 1.75rem;\n color: ${Colors.DARK_CHOCOLATE};\n margin: 0;\n`;\nexport default H3;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { CHOCOLATE_200, CHOCOLATE_800 } from \"../styles/colors\";\n\nimport {\n Link\n} from \"react-router-dom\";\n\nconst TransactionWrapper = styled.div`\n background: ${CHOCOLATE_200};\n padding: 1rem;\n border-radius: 1rem;\n font-family: \"Ubuntu Mono\", monospace;\n margin-bottom: 1.25rem;\n font-size: 1em;\n overflow-x: scroll;\n overflow-y: scroll;\n a {\n text-decoration: none;\n color: ${CHOCOLATE_800};\n }\n`;\n\nconst Transaction = ({ transaction, port }: any) => {\n\n return (\n \n \n {`Block ${transaction.blockNumber}: `}\n {transaction.hash}\n \n \n );\n};\n\nexport default Transaction;\n","import Web3 from \"web3\";\n\nconst getWeb3 = async (port: any) => {\n\n const provider = new Web3.providers.WebsocketProvider(\n `ws://127.0.0.1:${port}`,\n {\n headers: {\n Origin: \"some_meaningful_name\"\n }\n }\n );\n const web3 = await new Web3(provider);\n return web3;\n}\n\nexport default getWeb3;\n","import React, { useEffect, useState } from \"react\";\nimport styled from \"styled-components\";\nimport * as Colors from \"../styles/colors\";\nimport H3 from \"../styles/H3\";\nimport Transaction from \"./Transaction\";\nimport getWeb3 from \"../utils/getWeb3\";\n\nconst HomeContainer = styled.div`\n padding: 1rem 2rem;\n`;\n\nconst TransactionsBox = styled.div`\n background: ${Colors.CHOCOLATE_200};\n padding: 1rem;\n border-radius: 1rem;\n font-family: \"Ubuntu Mono\", monospace;\n margin-bottom: 1.25rem;\n font-size: 1em;\n`;\n\nconst Home = ({port}: any) => {\n const [transactions, setTransactions] = useState([]);\n\n const getPendingTransactions = async () => {\n\n const web3 = await getWeb3(port);\n const subscription = web3.eth.subscribe('pendingTransactions');\n\n subscription.subscribe((error: any, result: any) => {\n if (error) console.log(error)\n })\n .on('data', async (txHash: any) => {\n\n try {\n const txn = await web3.eth.getTransaction(txHash)\n\n const transaction: any = (\n \n );\n \n await setTransactions((prev: any) => {\n return [...prev, transaction];\n });\n\n return function cleanup() {\n subscription.unsubscribe();\n };\n }\n catch (error) {\n console.log(error)\n }\n })\n }\n\n useEffect(() => {\n getPendingTransactions();\n }, []);\n\n return (\n \n

Transactions

\n

Transactions will be listed below as they are created.

\n {transactions.length ? \n transactions.filter((v,i) => {\n if (i%2) {\n return v; // uber hack to only display even (given the subscription is returning dupes)\n }\n }) \n : (Waiting for transactions) }\n
\n );\n};\n\nexport default Home;\n","import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport * as Colors from \"../styles/colors\";\nimport H3 from \"../styles/H3\";\n\nimport {\n Link,\n} from \"react-router-dom\";\n\nconst SettingsContainer = styled.div`\n padding: 1rem 2rem;\n`;\n\nconst SettingsForm = styled.form`\n label {\n margin: 0.4rem 0;\n display: block;\n\n }\n label input {\n display: ;\n margin: 0.4rem ;\n }\n input[type=submit] {\n display: block;\n }\n`;\n\nconst Settings = ({port, setPort, rpc, setRpc}: any) => {\n const [newPort, setNewPort] = useState(port);\n const [newRpc, setNewRpc] = useState(rpc);\n\n const save: any = (e:any) => {\n e.preventDefault();\n setPort(newPort);\n setRpc(newRpc);\n // TODO display toast \n };\n\n return (\n \n

Settings

\n \n \n \n \n \n
\n );\n};\n\nexport default Settings;\n","import React, { useEffect, useState } from \"react\";\nimport styled from \"styled-components\";\nimport * as Colors from \"../styles/colors\";\nimport H3 from \"../styles/H3\";\nimport Transaction from \"./Transaction\";\nimport getWeb3 from \"../utils/getWeb3\";\n\nconst AccountsContainer = styled.div`\n padding: 1rem 2rem;\n`;\n\nconst AccountsBox = styled.div`\n background: ${Colors.CHOCOLATE_200};\n padding: 1rem;\n border-radius: 1rem;\n font-family: \"Ubuntu Mono\", monospace;\n margin-bottom: 1.25rem;\n font-size: 1em;\n`;\n\nconst Account = styled.div`\n padding: 0.2rem 0.2rem;\n`;\n\nconst Accounts = ({port}: any) => {\n const [accounts, setAccounts] = useState([]);\n\n const getAccounts = async () => {\n\n const web3 = await getWeb3(port);\n const list = (await web3.eth.getAccounts()).map((a: any, i: any) => {\n return ({`[${i}] ${a}`})\n })\n\n setAccounts(list);\n }\n\n useEffect(() => {\n getAccounts();\n }, []);\n\n return (\n \n

Accounts

\n

The following accounts are currently available.

\n \n {accounts.length ? \n accounts\n : (

No accounts available

) }\n
\n
\n );\n};\n\nexport default Accounts;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport * as Colors from \"../styles/colors\";\n\nimport {\n Link\n} from \"react-router-dom\";\n\nconst NavBarContainer = styled.div`\n width: 100%;\n background-color: #EFE5DC;\n`;\n\nconst NavBar = styled.ul`\n list-style-type: none;\n margin: 0;\n padding: 0.8rem 0;\n border-bottom: solid 1px ${Colors.GRAY_300};\n li {\n display: inline;\n padding: 1rem;\n }\n a {\n font-weight: 500;\n text-decoration: none;\n color: ${Colors.DARK_CHOCOLATE};\n }\n`;\n\nconst Navigation = ({}) => {\n return (\n \n \n
  • \n
  • Transactions
  • \n
  • Accounts
  • \n
  • Settings
  • \n
    \n
    \n );\n};\n\nexport default Navigation;\n","import styled from \"styled-components\";\nimport * as Colors from \"./colors\";\n\nexport default styled.button`\n background: ${Colors.MINT_400};\n border: none;\n border-radius: 0.25rem;\n padding: 0.5rem 1rem;\n cursor: pointer;\n text-transform: uppercase;\n font-size: 1rem;\n font-family: \"Fira Sans Condensed\", sans-serif;\n`;\n","import styled from \"styled-components\";\nimport * as Colors from \"../styles/colors\";\n\nconst SyntaxStyle = styled.div`\n .hljs-comment,\n .hljs-quote {\n color: ${Colors.GREY};\n font-style: italic;\n }\n\n .hljs-keyword,\n .hljs-selector-tag,\n .hljs-subst {\n color: ${Colors.PINK_500};\n font-weight: bold;\n }\n\n .hljs-number,\n .hljs-literal,\n .hljs-variable,\n .hljs-template-variable,\n .hljs-tag .hljs-attr {\n color: ${Colors.WATERMELON_600};\n }\n\n .hljs-string,\n .hljs-doctag {\n color: ${Colors.PORSCHE_1};\n }\n\n .hljs-title,\n .hljs-section,\n .hljs-selector-id {\n color: ${Colors.TEAL_1};\n font-weight: bold;\n }\n\n .hljs-subst {\n font-weight: normal;\n }\n\n .hljs-type,\n .hljs-class .hljs-title {\n color: ${Colors.TEAL_1};\n font-weight: bold;\n }\n\n .hljs-tag,\n .hljs-name,\n .hljs-attribute {\n color: ${Colors.TEAL_1};\n font-weight: normal;\n }\n\n .hljs-built_in,\n .hljs-builtin-name {\n color: ${Colors.TEAL_1};\n }\n`;\n\nexport default SyntaxStyle;\n","import React, { useState, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport * as Colors from \"../styles/colors\";\n\nexport const backgroundInherit = Colors.CHOCOLATE_200;\nexport const backgroundHighlight = Colors.YELLOW_200;\nexport const borderHighlight = Colors.ORANGE_300;\n\ninterface IHighlightProps {\n isCurrent: boolean;\n}\n\nconst Row = styled.div`\n background: ${({ isCurrent }: IHighlightProps) =>\n isCurrent ? `${backgroundHighlight}` : `${backgroundInherit}`};\n border-color: ${({ isCurrent }: IHighlightProps) =>\n isCurrent ? `${borderHighlight}` : `${backgroundInherit}`};\n border-width: 1px;\n border-style: solid;\n border-radius: 0.4rem;\n width: fit-content;\n min-width: 100%;\n\n &:hover .fas.fa-dot-circle.faded {\n color: ${Colors.CI_RED};\n opacity: 0.5;\n }\n`;\n\nconst LineContainer = styled.span`\n font-family: \"Ubuntu Mono\", monospace;\n white-space: pre;\n padding-left: 0.2rem;\n cursor: text;\n`;\n\nconst LineNumber = styled.span`\n color: ${Colors.GRAY_300};\n padding-left: 0.2rem;\n cursor: pointer;\n`;\n\ninterface IBreakpoint {\n isBreakpoint: boolean;\n}\n\nconst Breakpoint = styled.i`\n text-align: center;\n display: inline-block;\n color: ${({ isBreakpoint }: IBreakpoint) =>\n isBreakpoint ? Colors.CI_RED : Colors.CHOCOLATE_200};\n cursor: pointer;\n padding-left: 0.2rem;\n width: 1.1rem;\n height: 1rem;\n`;\n\nexport interface IProps {\n lineNumber: number;\n lineContents: string;\n isCurrent: boolean;\n breakpoints: any[];\n setBreakpoints: any;\n lineRef: any;\n sourceId: string;\n fileName: string;\n astId: number;\n lineNumberIndentLength: number;\n}\n\nconst Line = ({\n lineNumber,\n lineContents,\n isCurrent,\n breakpoints,\n setBreakpoints,\n lineRef,\n sourceId,\n fileName,\n astId,\n lineNumberIndentLength,\n}: IProps) => {\n const [isBreakpoint, updateBreakpoint] = useState(false);\n\n const start = () => {\n updateBreakpoint(\n breakpoints.filter(breakpoint => {\n return (\n breakpoint.line === lineNumber && breakpoint.sourceId === sourceId\n );\n }).length > 0\n );\n };\n\n const toggleBreakpoint = () => {\n updateBreakpoint(!isBreakpoint);\n\n if (isBreakpoint) {\n const filteredBreakpoints = breakpoints.filter(\n breakpoint =>\n breakpoint.line !== lineNumber || breakpoint.sourceId !== sourceId\n );\n setBreakpoints(filteredBreakpoints);\n } else {\n const breakpoint: any = {\n line: lineNumber,\n sourceId,\n compilationId: \"shimmedcompilation\",\n fileName,\n astId,\n };\n setBreakpoints((prev: any) => {\n return [...prev, breakpoint];\n });\n }\n };\n\n useEffect(() => {\n start();\n }, [breakpoints]);\n\n return (\n \n \n \n \n {` `.repeat(lineNumberIndentLength)}\n {lineNumber + 1}.{` `}\n \n \n \n \n );\n};\n\nexport default Line;\n","import React, {\n createRef,\n useRef,\n useEffect,\n useState,\n useLayoutEffect,\n} from \"react\";\nimport styled from \"styled-components\";\nimport SyntaxStyle from \"./SyntaxStyle\";\nimport Line from \"./Line\";\n\nconst SourceWrapper = styled.div`\n padding: 1rem 0.5rem;\n overflow-x: scroll;\n overflow-y: scroll;\n white-space: nowrap;\n`;\n\ninterface IProps {\n activeLine: number;\n selectedLine: number;\n contractSource: string[];\n breakpoints: any[];\n setBreakpoints: any;\n visible: boolean;\n sourceIsActive: boolean;\n sourceId: string;\n fileName: string;\n astId: number;\n}\n\nconst Source = ({\n activeLine,\n selectedLine,\n contractSource,\n breakpoints,\n setBreakpoints,\n visible,\n sourceIsActive,\n sourceId,\n fileName,\n astId,\n}: IProps) => {\n const output: React.ReactNode[] = [];\n const [scrollTop, setScrollTop] = useState(0);\n const sourceRef = useRef(null);\n const lineDigitLength = contractSource.length.toString().length;\n\n let selectedLineRef: any;\n\n contractSource.forEach((line: string) => {\n const lineRef = createRef();\n if (output.length === selectedLine) {\n selectedLineRef = lineRef;\n }\n output.push(\n \n );\n });\n\n useEffect(() => {\n if (selectedLineRef) {\n if (selectedLineRef.current) {\n selectedLineRef.current.scrollIntoView({\n behavior: \"auto\",\n block: \"center\",\n });\n }\n }\n }, [selectedLine]);\n\n useLayoutEffect(() => {\n if (visible) {\n if (sourceRef.current !== null) {\n sourceRef.current.scrollTo({\n top: scrollTop,\n left: 0,\n behavior: \"auto\",\n });\n }\n }\n }, [visible]);\n\n const updateLine = (e: any) => {\n setScrollTop(e.target.scrollTop);\n };\n\n return (\n <>\n {visible ? (\n \n {output}\n \n ) : null}\n \n );\n};\n\nexport default Source;\n","import React, { useState } from \"react\";\nimport Source from \"./Source\";\nimport unified from \"unified\";\nimport stringify from \"rehype-dom-stringify\";\nimport low from \"lowlight\";\nimport { definer } from \"highlightjs-solidity\";\n\ninterface IProps {\n sources: any;\n activeTabIndex: number;\n breakpoints: any[];\n setBreakpoints: any;\n activeLine: number;\n selectedLine: number;\n runningTabIndex: number;\n}\n\ninterface IPropsRenderer {\n rows: any;\n stylesheet: any;\n useInlineStyles: any;\n}\n\nconst Sources = ({\n sources,\n activeTabIndex,\n breakpoints,\n setBreakpoints,\n activeLine,\n selectedLine,\n runningTabIndex,\n}: IProps) => {\n const [sourcesWithMarkup, setSourcesWithMarkup] = useState([]);\n\n const sourceComponents = sources.map((source: any, index: number) => {\n const astId = source.ast.id;\n const fileName = source.sourcePath.replace(/^.*[\\\\/]/, \"\");\n const highlightedSource: string[] = [];\n\n if (sourcesWithMarkup.length === 0) {\n low.registerLanguage(\"solidity\", definer);\n const tree: any = low.highlight(\"solidity\", source.source).value;\n const processor: any = unified().use(stringify);\n const highlightedMarkup: any = processor\n .stringify({ type: \"root\", children: tree })\n .toString();\n\n highlightedMarkup.split(\"\\n\").forEach((lineMarkup: string) => {\n highlightedSource.push(lineMarkup);\n });\n\n setSourcesWithMarkup(prevState => [...prevState, highlightedSource]);\n }\n\n return (\n 0\n ? highlightedSource\n : sourcesWithMarkup[index]\n }\n activeLine={activeLine}\n selectedLine={selectedLine}\n breakpoints={breakpoints}\n setBreakpoints={setBreakpoints}\n sourceIsActive={astId === runningTabIndex}\n sourceId={source.id}\n astId={astId}\n fileName={fileName}\n />\n );\n });\n\n return <>{sourceComponents};\n};\n\nexport default Sources;\n","const getDecodedValue = (inputObj: any) => {\n const typeClass = inputObj.type.typeClass;\n\n if (inputObj.error) {\n return \"NA\";\n }\n\n if (typeClass === \"magic\") {\n const variable: string = inputObj.type.variable;\n if (\n variable === \"block\" ||\n variable === \"message\" ||\n variable === \"transaction\"\n ) {\n return inputObj.value;\n }\n }\n\n if (typeClass === \"contract\") {\n return inputObj.value.address;\n }\n\n if (typeClass === \"int\" || typeClass === \"uint\") {\n return inputObj.value.asBN.toString(); // temporarily converting to string to handle big numbers\n }\n\n if (typeClass === \"bool\") {\n return inputObj.value.asBoolean;\n }\n\n if (typeClass === \"string\") {\n return inputObj.value.asString;\n }\n\n if (typeClass === \"bytes\") {\n return inputObj.value.asHex;\n }\n\n if (typeClass === \"address\") {\n return inputObj.value.asAddress;\n }\n\n if (typeClass === \"struct\") {\n const data = inputObj.value;\n const arrayOfObjects = data.map(({ name, value }: any) => ({\n [name]: getDecodedValue(value),\n }));\n const mergedObject = arrayOfObjects.reduce(\n (acc: any, curr: any) => Object.assign(acc, curr),\n {}\n );\n return mergedObject;\n }\n\n if (typeClass === \"array\") {\n const array = inputObj.value;\n const strArray = array.map(getDecodedValue);\n return strArray;\n }\n\n return `${typeClass} is currently not supported`;\n};\n\nexport default getDecodedValue;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport getDecodedValue from \"../utils/getDecodedValue\";\nimport ReactJson from \"react-json-view\";\n// import { VARIABLES_OUTPUT as variablesTheme } from \"../../styles/components\";\nimport { CHOCOLATE_200 } from \"../styles/colors\";\n\nconst VariablesWrapper = styled.div`\n background: ${CHOCOLATE_200};\n padding: 1rem;\n border-radius: 1rem;\n font-family: \"Ubuntu Mono\", monospace;\n margin-bottom: 1.25rem;\n font-size: 1em;\n * {\n background-color: inherit !important;\n font-family: \"Ubuntu Mono\", monospace;\n }\n ul,\n ul li {\n margin-top: 0em !important;\n paddding-top: 0em !important;\n }\n overflow-x: scroll;\n overflow-y: scroll;\n`;\n\nexport interface IProps {\n variables: any;\n}\n\nconst Variables = ({ variables }: IProps) => {\n const state: any = {};\n\n if (variables) {\n const variableKeys = Object.keys(variables);\n variableKeys.forEach(variable => {\n const value = getDecodedValue(variables[variable]);\n state[variable] = value;\n });\n }\n\n return (\n \n \n \n );\n};\n\nexport default Variables;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport * as Colors from \"../styles/colors\";\n\nconst TrayWrapper = styled.div`\n background: ${Colors.CHOCOLATE_200};\n padding: 1rem;\n border-radius: 1rem;\n font-size: 1em;\n overflow-x: scroll;\n overflow-y: scroll;\n`;\n\nconst Row = styled.div`\n margin: 0.1rem 0;\n cursor: pointer;\n padding: 0.25rem 0.1rem;\n border-width: 0.1rem;\n border-radius: 0.5rem;\n\n &:hover {\n background-color: ${Colors.GRAY_100};\n }\n`;\n\nconst Breakpoint = styled.span`\n margin-left: 0.4rem;\n`;\n\nconst Icon = styled.span`\n color: ${Colors.CI_RED};\n`;\n\nconst Badge = styled.span`\n background: ${Colors.CHOCOLATE_400};\n border: solid 1px ${Colors.CHOCOLATE_500};\n border-radius: 0.5rem;\n padding: 0.025rem 0.2rem;\n color: #fff;\n`;\n\nconst Remove = styled.span`\n color: ${Colors.CHOCOLATE_400};\n margin-left: 0.25rem;\n`;\n\nexport interface IProps {\n breakpoints: any;\n setBreakpoints: any;\n setActiveTabIndex: any;\n setSelectedLine: any;\n}\n\nconst Tray = ({\n breakpoints,\n setBreakpoints,\n setActiveTabIndex,\n setSelectedLine,\n}: IProps) => {\n const removeBreakpoint = (sourceId: number, lineNumber: number) => {\n const filteredBreakpoints = breakpoints.filter((breakpoint: any) => {\n return breakpoint.line !== lineNumber || breakpoint.sourceId !== sourceId;\n });\n setBreakpoints(filteredBreakpoints);\n };\n\n const jumptoLine = (astId: number, lineNumber: number) => {\n setActiveTabIndex(astId);\n setSelectedLine(lineNumber);\n };\n\n const list = breakpoints.map((breakpoint: any, index: number) => {\n const sourceId = breakpoint.sourceId;\n const fileName = breakpoint.fileName;\n const lineNumber = breakpoint.line;\n const astId = breakpoint.astId;\n return (\n \n removeBreakpoint(sourceId, lineNumber)}\n />\n jumptoLine(astId, lineNumber)}>\n {fileName}\n {lineNumber + 1}\n \n removeBreakpoint(sourceId, lineNumber)}\n />\n \n );\n });\n\n return (\n \n {list.length > 0\n ? list\n : `Add a breakpoint by clicking to the left of the line`}\n \n );\n};\n\nexport default Tray;\n","import styled from \"styled-components\";\n\nexport const size = \"25px\";\nexport default styled.i`\n width: ${size};\n height: ${size};\n display: inline-flex;\n justify-content: center;\n align-items: center;\n border-radius: 4px;\n`;\n","import React from \"react\";\nimport styled, { keyframes } from \"styled-components\";\nimport Icon from \"./Icon\";\n\ninterface IProps {\n className?: string;\n}\n\nconst rotate = keyframes`\n from {\n transform: rotate(0deg);\n }\n\n to {\n transform: rotate(360deg);\n }\n`;\n\nconst StyledIcon = styled(Icon)`\n animation: ${rotate} 2s linear infinite;\n`;\n\nexport default ({ className = \"\" }: IProps) => (\n \n);\n","import styled from \"styled-components\";\n\nexport const size = \"25px\";\nexport default styled.i`\n width: ${size};\n height: ${size};\n display: inline-flex;\n justify-content: center;\n align-items: center;\n border-radius: 4px;\n`;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport LoadingSmall from \"../styles/LoadingSmall\";\nimport IconBase from \"../styles/IconBase\";\nimport * as Colors from \"../styles/colors\";\n\nconst TxSuccess = styled(IconBase)`\n color: ${Colors.CI_GREEN};\n`;\n\nconst TxFail = styled(IconBase)`\n color: ${Colors.CI_RED};\n`;\n\ninterface IProps {\n status?: any;\n}\n\nconst StatusIcon = ({ status }: IProps) => {\n return (\n <>\n {status === null ? (\n \n ) : status ? (\n \n ) : (\n \n )}\n \n );\n};\n\nexport default StatusIcon;\n","import styled from \"styled-components\";\nimport * as Colors from \"./colors\";\n\nexport const padding = \"1.5rem\";\nexport const radius = \"0.5rem\";\n\nexport default styled.div`\n background: ${Colors.CHOCOLATE_200};\n padding: ${padding};\n border-radius: ${radius};\n`;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { radius } from \"../styles/MetaWrapper\";\nimport * as Colors from \"../styles/colors\";\n\nconst Wrapper = styled.div`\n grid-template-columns: 3.5fr 1.5fr;\n display: grid;\n`;\n\nconst StatusContainer = styled.div`\n background: ${Colors.RED_100};\n border: solid 1px ${Colors.RED_600};\n color: ${Colors.RED_600};\n padding: 1rem 1rem;\n margin-top: 1rem;\n border-radius: ${radius};\n font-family: \"Ubuntu Mono\", monospace;\n font-size: 1rem;\n\n > * {\n &:not(:last-child) {\n margin: 0 0.2rem 0 0;\n }\n }\n`;\n\ninterface IProps {\n returnValue: any;\n}\n\nconst StatusMessage = ({ returnValue }: IProps) => {\n let statusDescription: any | null;\n let statusMessage: any | null;\n\n if (returnValue?.length > 0) {\n switch (returnValue[0].kind) {\n case \"revert\":\n statusDescription = `VM Exception while processing transaction`;\n statusMessage = `${returnValue[0].kind} -- ${returnValue[0].arguments[0].value.value.asString}`;\n break;\n case \"selfdestruct\":\n case \"return\":\n default:\n return <>;\n break;\n }\n }\n\n return (\n <>\n {returnValue ? (\n \n \n {`${statusDescription}: ${statusMessage}`}\n \n \n ) : null}\n \n );\n};\n\nexport default StatusMessage;\n","import styled from \"styled-components\";\nimport * as Colors from \"./colors\";\n\nconst borderRadius = \"0.3125rem\";\nconst borderWidth = \"0.125rem\";\nconst borderStyle = \"solid\";\nconst borderColor = Colors.MILK_CHOCOLATE;\nconst border = `${borderWidth} ${borderStyle} ${borderColor}`;\nexport const style = `\n border-top: ${border};\n border-bottom: ${border};\n border-left: ${border};\n border-right: 0px;\n padding: 0.5rem 1.5rem;\n text-decoration: none;\n &:first-child {\n border-radius: ${borderRadius} 0 0 ${borderRadius};\n }\n &:last-child {\n border-radius: 0 ${borderRadius} ${borderRadius} 0;\n border-right: ${border};\n }\n &:only-child {\n border-radius: ${borderRadius};\n }\n cursor: pointer;\n text-transform: uppercase;\n font-size: 1rem;\n font-family: \"Fira Sans\", sans-serif;\n`;\n\nconst TabButton = styled.button`\n ${style}\n background: transparent;\n color: ${Colors.MILK_CHOCOLATE};\n`;\nexport default TabButton;\n","import styled from \"styled-components\";\nimport { style as TabButtonStyle } from \"./TabButton\";\nimport * as Colors from \"./colors\";\n\nexport interface IProps {\n selected?: boolean;\n}\n\nconst Tab = styled.div`\n ${TabButtonStyle}\n /* To make sure padding works in
    tag */\n display: inline-block;\n background: ${({ selected }: IProps) =>\n selected ? Colors.MILK_CHOCOLATE : \"transparent\"};\n color: ${({ selected }: IProps) =>\n selected ? \"white\" : Colors.MILK_CHOCOLATE};\n`;\n\nexport default Tab;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport StyledTab from \"../styles/Tab\";\nimport Tooltip from \"../styles/Tooltip\";\nimport * as Colors from \"../styles/colors\";\n\ninterface IIndexProps {\n activeTabIndex: number;\n index: number;\n}\n\nconst TabButton = styled(StyledTab)`\n background: ${({ activeTabIndex, index }: IIndexProps) =>\n activeTabIndex === index ? `${Colors.TEAL_2}` : `${Colors.WHITE}`};\n border-color: ${Colors.TEAL_1} !important;\n color: inherit;\n text-transform: none;\n\n &:hover {\n background: ${Colors.TEAL_1};\n color: ${Colors.WHITE};\n * {\n color: ${Colors.WHITE};\n }\n }\n\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n flex-basis: auto;\n position: relative;\n`;\n\nconst ActiveIcon = styled.div`\n color: ${Colors.ORANGE_400};\n font-size: 0.6em;\n vertical-align: middle;\n position: absolute;\n right: 0.6rem;\n top: 0.9rem;\n`;\n\ninterface IProps {\n index: number;\n tabName: string;\n activeTabIndex: number;\n setActiveTabIndex: any;\n tabIsRunning: boolean;\n}\n\nconst Tab = ({\n index,\n tabName,\n activeTabIndex,\n setActiveTabIndex,\n tabIsRunning,\n}: IProps) => {\n return (\n // {tabName}}>\n <>\n setActiveTabIndex(index)}\n selected={activeTabIndex === index}\n activeTabIndex={activeTabIndex}\n index={index}\n >\n {tabName}{\" \"}\n {tabIsRunning ? : null}\n \n \n // \n );\n};\n\nexport default Tab;\n","import React from \"react\";\nimport Tab from \"./Tab\";\nimport styled from \"styled-components\";\n\ninterface IProps {\n sources: any;\n setActiveTabIndex: any;\n activeTabIndex: number;\n runningTabIndex: number;\n}\n\nconst TabsWrapper = styled.div`\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n`;\n\nconst Tabs = ({\n sources,\n setActiveTabIndex,\n activeTabIndex,\n runningTabIndex,\n}: IProps) => {\n const tabs = sources.map((source: any) => {\n const fileName = source.sourcePath.replace(/^.*[\\\\/]/, \"\");\n const astId = source.ast.id;\n return (\n \n );\n });\n\n return {tabs};\n};\n\nexport default Tabs;\n","import React from \"react\";\nimport Tooltip from \"../styles/Tooltip\";\nimport * as Colors from \"../styles/colors\";\n\ninterface IProps {\n title: string;\n children?: React.ReactElement;\n}\n\nconst overlayStyle = {\n padding: \"0.5rem 1rem\",\n borderRadius: \"0.5rem\",\n background: `${Colors.GRAY_600}`,\n opacity: 1,\n maxHeight: \"15rem\",\n overflow: \"auto\",\n};\n\nconst DebugTooltip = ({ title, children }: IProps) => {\n return (\n // {title}} trigger={[\"hover\"]} overlayStyle={overlayStyle}>\n <>\n {children}\n \n // \n );\n};\n\nexport default DebugTooltip;\n","import React from \"react\";\nimport { GlobalHotKeys } from \"react-hotkeys\";\n\ninterface IProps {\n executeAction: (debugAction: string) => Promise;\n start: () => Promise;\n}\n\nconst KeyboardShortcuts = ({ executeAction, start }: IProps) => {\n const keyMap = {\n STEP_OVER: [\"o\", \"f10\"],\n STEP_INTO: [\"i\", \"f11\"],\n STEP_OUT: [\"u\", \"shift+f11\"],\n CONTINUE_UNTIL: [\"c\", \"f8\"],\n RESTART: [\"r\"],\n };\n\n const over = () => {\n executeAction(\"over\");\n };\n\n const into = () => {\n executeAction(\"into\");\n };\n\n const out = () => {\n executeAction(\"out\");\n };\n\n const continueUntil = () => {\n executeAction(\"continueUntil\");\n };\n\n const restart = () => {\n start();\n };\n\n const handlers = {\n STEP_OVER: over,\n STEP_INTO: into,\n STEP_OUT: out,\n CONTINUE_UNTIL: continueUntil,\n RESTART: restart,\n };\n\n return (\n \n );\n};\n\nexport default KeyboardShortcuts;\n","import styled from \"styled-components\";\n\nexport interface IProps {\n marginBottom?: string;\n}\n\nconst List = styled.div`\n > * {\n &:not(:last-child) {\n margin-bottom: ${({ marginBottom = \"1rem\" }: IProps) => marginBottom};\n }\n }\n`;\nexport default List;\n","import React from \"react\";\nimport RingLoader from \"react-spinners/RingLoader\";\nimport styled from \"styled-components\";\nimport * as Colors from \"./colors\";\n\nconst Wrapper = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n`;\n\nconst Loading = (props: any) => (\n \n \n \n);\nexport default Loading;\n","import React, { useEffect, useState } from 'react';\n\nimport axios from \"axios\";\nimport styled from \"styled-components\";\n\nimport H3 from \"../styles/H3\";\nimport PrimaryButton from \"../styles/PrimaryButton\";\nimport Sources from \"./Sources\";\nimport Variables from \"./Variables\";\nimport Tray from \"./Tray\";\nimport StatusIcon from \"./StatusIcon\";\nimport StatusMessage from \"./StatusMessage\";\nimport Tabs from \"./Tabs\";\nimport DebugTooltip from \"./DebugTooltip\";\nimport KeyboardShortcuts from \"./KeyboardShortcuts\";\nimport List from \"../styles/List\";\nimport * as Colors from \"../styles/colors\";\nimport Loading from \"../styles/Loading\";\n\nimport TruffleDebugger from \"@truffle/debugger\";\nimport * as Codec from \"@truffle/codec\";\nimport { getTransactionSourcesBeforeStarting } from \"@truffle/debug-utils\";\nimport Provider from \"@truffle/provider\";\n\nimport {\n useParams\n} from \"react-router-dom\";\n\nconst DebuggerWrapper = styled(List)`\n height: 90vh;\n display: grid;\n grid-template-rows: auto auto auto 1fr;\n grid-template-columns: 1fr;\n padding: 1rem 2rem;\n`;\n\nconst Header = styled(H3)`\n margin: 0 0 2.5rem;\n grid-row: 1;\n`;\n\nconst ButtonsWrapper = styled.div`\n grid-row: 2;\n`;\n\nconst TopRowWrapper = styled.div`\n grid-row: 3;\n display: grid;\n grid-template-columns: minmax(36rem, 3.5fr) 1.5fr;\n grid-column-gap: 1.25rem;\n`;\n\nconst SourceRowWrapper = styled.div`\n overflow-y: overlay;\n grid-row: 4;\n display: grid;\n grid-template-columns: minmax(36rem, 3.5fr) 1.5fr;\n grid-column-gap: 1.25rem;\n`;\n\nconst TabsWrapper = styled.div`\n * {\n align-self: flex-end;\n }\n`;\n\nconst VariablesTitle = styled(H3)`\n align-self: flex-end;\n`;\n\nconst BreakpointsTitle = styled(H3)`\n margin-bottom: 1rem;\n`;\n\nconst TxHash = styled.span`\n font-weight: lighter;\n`;\n\nconst DebugButton = styled(PrimaryButton)`\n width: 4rem;\n margin: 0 0.5rem 1rem 0;\n`;\n\nconst DebugButtonOver = styled(DebugButton)`\n .fa-sync-alt {\n max-height: 0.5rem;\n overflow: hidden;\n position: relative;\n top: -0.25rem;\n left: 0.2rem;\n }\n\n .fa-circle {\n position: relative;\n top: 0.05rem;\n left: -0.48rem;\n font-size: 0.35rem;\n }\n`;\n\nconst SourceWrapper = styled.div`\n grid-column: 1;\n display: grid;\n overflow-x: auto;\n overflow-y: auto;\n background: ${Colors.CHOCOLATE_200};\n border-radius: 1rem;\n`;\n\nconst RightColumnWrapper = styled.div`\n grid-column: 2;\n display: grid;\n grid-template-rows: minmax(30%, 60%) 3rem auto;\n`;\n\nconst LoadingWrapper = styled(Loading)`\n min-height: 18rem;\n`;\n\nconst Debugger = ({}) => {\n const [session, setSession] = useState(null);\n const [variables, setVariables] = useState(null);\n const [returnValue, setReturnValue] = useState(null);\n const [sources, setSources] = useState(null);\n const [breakpoints, setBreakpoints] = useState([]);\n const [status, setStatus] = useState(null);\n const [selectedLine, setSelectedLine] = useState(0);\n const [activeLine, setActiveLine] = useState(0);\n const [activeTabIndex, setActiveTabIndex] = useState(0);\n const [runningTabIndex, setRunningTabIndex] = useState(0);\n\n let { txHash, port } = useParams();\n\n const providerUrl = `http://127.0.0.1:${port}`;\n const transaction: any = {\n hash: txHash\n };\n\n const provider = Provider.create({\n url: providerUrl,\n });\n\n const start = async () => {\n setVariables(null);\n setSession(null);\n setReturnValue(null);\n setBreakpoints([]);\n\n const res:any = await axios.get(\"http://127.0.0.1:54321/artifacts\")\n const artifacts: any = res.data;\n\n const input: {\n compilations: Codec.Compilations.Compilation[];\n } = {\n compilations: [],\n };\n\n input.compilations = Codec.Compilations.Utils.shimArtifacts(\n artifacts\n );\n\n const bugger = await TruffleDebugger.forTx(transaction.hash, {\n provider,\n ...input\n });\n\n const initializedSession = bugger.connect();\n await initializedSession.ready();\n\n const sourcesInvolvedInTransaction = await getTransactionSourcesBeforeStarting(\n bugger\n );\n\n const sourceIndicesInvolvedInTransaction = sourcesInvolvedInTransaction.map(\n (source:any) => {\n return parseInt(source.id, 10)\n }\n );\n\n const sources = input.compilations[0].sources.filter((_: any, index: any) => {\n return sourceIndicesInvolvedInTransaction.includes(index)\n })\n\n setSources(\n sources\n );\n\n setSession(initializedSession);\n setVariables(await initializedSession.variables());\n setReturnValue(await initializedSession.returnValue());\n setStatus(await initializedSession.state.evm.transaction.status);\n\n const currentSource = await initializedSession.view(\n TruffleDebugger.selectors.solidity.current.source\n );\n setRunningTabIndex(currentSource.ast.id);\n setActiveTabIndex(currentSource.ast.id);\n\n const init = initializedSession.view(\n TruffleDebugger.selectors.solidity.current.sourceRange\n );\n\n setActiveLine(init.lines.start.line);\n setSelectedLine(init.lines.start.line);\n };\n\n const executeAction = async (debugAction: string) => {\n\n if (session) {\n switch (debugAction) {\n case \"continueUntil\": {\n await session.removeAllBreakpoints();\n breakpoints.forEach(\n async breakpoint => await session.addBreakpoint(breakpoint)\n );\n await session.continueUntilBreakpoint();\n break;\n }\n case \"over\":\n await session.stepOver();\n break;\n case \"into\":\n await session.stepInto();\n break;\n case \"out\":\n await session.stepOut();\n break;\n default:\n break;\n }\n\n setVariables(await session.variables());\n setReturnValue(await session.returnValue());\n\n const source = await session.view(\n TruffleDebugger.selectors.solidity.current.source\n );\n setRunningTabIndex(source.ast.id);\n setActiveTabIndex(source.ast.id);\n\n const sourceRange = await session.view(\n TruffleDebugger.selectors.solidity.current.sourceRange\n );\n setActiveLine(sourceRange.lines.start.line);\n setSelectedLine(sourceRange.lines.start.line);\n }\n };\n\n useEffect(() => {\n start();\n }, []);\n\n return (\n \n \n
    \n \n {` `}\n \n TX{` `}\n {transaction.hash || `...`}\n \n \n
    \n \n \n executeAction(\"continueUntil\")}\n >\n \n \n \n \n executeAction(\"over\")}\n disabled={!variables}\n >\n \n \n \n \n \n executeAction(\"into\")}\n disabled={!variables}\n >\n \n \n \n \n executeAction(\"out\")}\n disabled={!variables}\n >\n \n \n \n \n \n \n \n \n \n {variables ? (\n <>\n \n \n \n \n Variables\n \n \n \n \n \n \n \n Breakpoints\n \n \n \n \n ) : (\n \n )}\n
    \n );\n};\n\nexport default Debugger;\n","import React from 'react';\nimport './App.css';\nimport Home from './components/Home';\nimport Settings from './components/Settings';\nimport Accounts from './components/Accounts';\nimport Navigation from './components/Navigation';\nimport Debugger from './components/Debugger';\n\nimport { useState } from 'react';\n\nimport {\n BrowserRouter,\n Switch,\n Route,\n} from \"react-router-dom\";\n\nfunction App() {\n const [port, setPort] = useState(7545);\n const [rpc, setRpc] = useState('localhost');\n\n return (\n \n \n \n
    \n
    \n \n \n
    \n
    \n
    \n \n
    \n
    \n \n \n
    \n
    \n
    \n \n
    \n
    \n \n \n
    \n
    \n
    \n \n
    \n
    \n \n \n
    \n
    \n
    \n
    \n
    \n );\n}\n\nexport default App;\n","import { ReportHandler } from 'web-vitals';\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\n\nReactDOM.render(\n \n \n \n ,\n document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /ui/build/static/js/runtime-main.776f02b0.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(r){for(var n,i,a=r[0],c=r[1],l=r[2],s=0,p=[];s0.2%", 53 | "not dead", 54 | "not op_mini all" 55 | ], 56 | "development": [ 57 | "last 1 chrome version", 58 | "last 1 firefox version", 59 | "last 1 safari version" 60 | ] 61 | }, 62 | "devDependencies": { 63 | "@types/styled-components": "^5.1.9" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ui/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/ui/public/favicon.ico -------------------------------------------------------------------------------- /ui/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 18 | 19 | 28 | Truffle Visual Debbuger 29 | 30 | 31 | 32 |
    33 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /ui/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/ui/public/logo192.png -------------------------------------------------------------------------------- /ui/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trufflesuite/truffle-plugin-debugger/59a197dfce94b3a045064c491725f29e311b6478/ui/public/logo512.png -------------------------------------------------------------------------------- /ui/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /ui/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /ui/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #F8F5F0; 3 | } 4 | 5 | .App-body { 6 | background-color: #F8F5F0; 7 | display: flex; 8 | flex-direction: column; 9 | font-size: 1.2rem; 10 | } -------------------------------------------------------------------------------- /ui/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | render(); 7 | const linkElement = screen.getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /ui/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import Home from './components/Home'; 4 | import Settings from './components/Settings'; 5 | import Accounts from './components/Accounts'; 6 | import Navigation from './components/Navigation'; 7 | import Debugger from './components/Debugger'; 8 | 9 | import { useState } from 'react'; 10 | 11 | import { 12 | BrowserRouter, 13 | Switch, 14 | Route, 15 | } from "react-router-dom"; 16 | 17 | function App() { 18 | const [port, setPort] = useState(7545); 19 | const [rpc, setRpc] = useState('localhost'); 20 | 21 | return ( 22 | 23 | 24 | 25 |
    26 |
    27 | 28 | 29 |
    30 |
    31 |
    32 | 33 |
    34 |
    35 | 36 | 37 |
    38 |
    39 |
    40 | 41 |
    42 |
    43 | 44 | 45 |
    46 |
    47 |
    48 | 49 |
    50 |
    51 | 52 | 53 |
    54 |
    55 |
    56 |
    57 |
    58 | ); 59 | } 60 | 61 | export default App; 62 | -------------------------------------------------------------------------------- /ui/src/components/Accounts.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import styled from "styled-components"; 3 | import * as Colors from "../styles/colors"; 4 | import H3 from "../styles/H3"; 5 | import Transaction from "./Transaction"; 6 | import getWeb3 from "../utils/getWeb3"; 7 | 8 | const AccountsContainer = styled.div` 9 | padding: 1rem 2rem; 10 | `; 11 | 12 | const AccountsBox = styled.div` 13 | background: ${Colors.CHOCOLATE_200}; 14 | padding: 1rem; 15 | border-radius: 1rem; 16 | font-family: "Ubuntu Mono", monospace; 17 | margin-bottom: 1.25rem; 18 | font-size: 1em; 19 | `; 20 | 21 | const Account = styled.div` 22 | padding: 0.2rem 0.2rem; 23 | `; 24 | 25 | const Accounts = ({port}: any) => { 26 | const [accounts, setAccounts] = useState([]); 27 | 28 | const getAccounts = async () => { 29 | 30 | const web3 = await getWeb3(port); 31 | const list = (await web3.eth.getAccounts()).map((a: any, i: any) => { 32 | return ({`[${i}] ${a}`}) 33 | }) 34 | 35 | setAccounts(list); 36 | } 37 | 38 | useEffect(() => { 39 | getAccounts(); 40 | }, []); 41 | 42 | return ( 43 | 44 |

    Accounts

    45 |

    The following accounts are currently available.

    46 | 47 | {accounts.length ? 48 | accounts 49 | : (

    No accounts available

    ) } 50 |
    51 |
    52 | ); 53 | }; 54 | 55 | export default Accounts; 56 | -------------------------------------------------------------------------------- /ui/src/components/DebugTooltip.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Tooltip from "../styles/Tooltip"; 3 | import * as Colors from "../styles/colors"; 4 | 5 | interface IProps { 6 | title: string; 7 | children?: React.ReactElement; 8 | } 9 | 10 | const overlayStyle = { 11 | padding: "0.5rem 1rem", 12 | borderRadius: "0.5rem", 13 | background: `${Colors.GRAY_600}`, 14 | opacity: 1, 15 | maxHeight: "15rem", 16 | overflow: "auto", 17 | }; 18 | 19 | const DebugTooltip = ({ title, children }: IProps) => { 20 | return ( 21 | // {title}} trigger={["hover"]} overlayStyle={overlayStyle}> 22 | <> 23 | {children} 24 | 25 | // 26 | ); 27 | }; 28 | 29 | export default DebugTooltip; 30 | -------------------------------------------------------------------------------- /ui/src/components/Debugger.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | 3 | import axios from "axios"; 4 | import styled from "styled-components"; 5 | 6 | import H3 from "../styles/H3"; 7 | import PrimaryButton from "../styles/PrimaryButton"; 8 | import Sources from "./Sources"; 9 | import Variables from "./Variables"; 10 | import Tray from "./Tray"; 11 | import StatusIcon from "./StatusIcon"; 12 | import StatusMessage from "./StatusMessage"; 13 | import Tabs from "./Tabs"; 14 | import DebugTooltip from "./DebugTooltip"; 15 | import KeyboardShortcuts from "./KeyboardShortcuts"; 16 | import List from "../styles/List"; 17 | import * as Colors from "../styles/colors"; 18 | import Loading from "../styles/Loading"; 19 | 20 | import TruffleDebugger from "@truffle/debugger"; 21 | import * as Codec from "@truffle/codec"; 22 | import { getTransactionSourcesBeforeStarting } from "@truffle/debug-utils"; 23 | import Provider from "@truffle/provider"; 24 | 25 | import { 26 | useParams 27 | } from "react-router-dom"; 28 | 29 | const DebuggerWrapper = styled(List)` 30 | height: 90vh; 31 | display: grid; 32 | grid-template-rows: auto auto auto 1fr; 33 | grid-template-columns: 1fr; 34 | padding: 1rem 2rem; 35 | `; 36 | 37 | const Header = styled(H3)` 38 | margin: 0 0 2.5rem; 39 | grid-row: 1; 40 | `; 41 | 42 | const ButtonsWrapper = styled.div` 43 | grid-row: 2; 44 | `; 45 | 46 | const TopRowWrapper = styled.div` 47 | grid-row: 3; 48 | display: grid; 49 | grid-template-columns: minmax(36rem, 3.5fr) 1.5fr; 50 | grid-column-gap: 1.25rem; 51 | `; 52 | 53 | const SourceRowWrapper = styled.div` 54 | overflow-y: overlay; 55 | grid-row: 4; 56 | display: grid; 57 | grid-template-columns: minmax(36rem, 3.5fr) 1.5fr; 58 | grid-column-gap: 1.25rem; 59 | `; 60 | 61 | const TabsWrapper = styled.div` 62 | * { 63 | align-self: flex-end; 64 | } 65 | `; 66 | 67 | const VariablesTitle = styled(H3)` 68 | align-self: flex-end; 69 | `; 70 | 71 | const BreakpointsTitle = styled(H3)` 72 | margin-bottom: 1rem; 73 | `; 74 | 75 | const TxHash = styled.span` 76 | font-weight: lighter; 77 | `; 78 | 79 | const DebugButton = styled(PrimaryButton)` 80 | width: 4rem; 81 | margin: 0 0.5rem 1rem 0; 82 | `; 83 | 84 | const DebugButtonOver = styled(DebugButton)` 85 | .fa-sync-alt { 86 | max-height: 0.5rem; 87 | overflow: hidden; 88 | position: relative; 89 | top: -0.25rem; 90 | left: 0.2rem; 91 | } 92 | 93 | .fa-circle { 94 | position: relative; 95 | top: 0.05rem; 96 | left: -0.48rem; 97 | font-size: 0.35rem; 98 | } 99 | `; 100 | 101 | const SourceWrapper = styled.div` 102 | grid-column: 1; 103 | display: grid; 104 | overflow-x: auto; 105 | overflow-y: auto; 106 | background: ${Colors.CHOCOLATE_200}; 107 | border-radius: 1rem; 108 | `; 109 | 110 | const RightColumnWrapper = styled.div` 111 | grid-column: 2; 112 | display: grid; 113 | grid-template-rows: minmax(30%, 60%) 3rem auto; 114 | `; 115 | 116 | const LoadingWrapper = styled(Loading)` 117 | min-height: 18rem; 118 | `; 119 | 120 | const Debugger = ({}) => { 121 | const [session, setSession] = useState(null); 122 | const [variables, setVariables] = useState(null); 123 | const [returnValue, setReturnValue] = useState(null); 124 | const [sources, setSources] = useState(null); 125 | const [breakpoints, setBreakpoints] = useState([]); 126 | const [status, setStatus] = useState(null); 127 | const [selectedLine, setSelectedLine] = useState(0); 128 | const [activeLine, setActiveLine] = useState(0); 129 | const [activeTabIndex, setActiveTabIndex] = useState(0); 130 | const [runningTabIndex, setRunningTabIndex] = useState(0); 131 | 132 | let { txHash, port } = useParams(); 133 | 134 | const providerUrl = `http://127.0.0.1:${port}`; 135 | const transaction: any = { 136 | hash: txHash 137 | }; 138 | 139 | const provider = Provider.create({ 140 | url: providerUrl, 141 | }); 142 | 143 | const start = async () => { 144 | setVariables(null); 145 | setSession(null); 146 | setReturnValue(null); 147 | setBreakpoints([]); 148 | 149 | const res:any = await axios.get("http://127.0.0.1:54321/artifacts") 150 | const artifacts: any = res.data; 151 | 152 | const input: { 153 | compilations: Codec.Compilations.Compilation[]; 154 | } = { 155 | compilations: [], 156 | }; 157 | 158 | input.compilations = Codec.Compilations.Utils.shimArtifacts( 159 | artifacts 160 | ); 161 | 162 | const bugger = await TruffleDebugger.forTx(transaction.hash, { 163 | provider, 164 | ...input 165 | }); 166 | 167 | const initializedSession = bugger.connect(); 168 | await initializedSession.ready(); 169 | 170 | const sourcesInvolvedInTransaction = await getTransactionSourcesBeforeStarting( 171 | bugger 172 | ); 173 | 174 | const sourceIndicesInvolvedInTransaction = sourcesInvolvedInTransaction.map( 175 | (source:any) => { 176 | return parseInt(source.id, 10) 177 | } 178 | ); 179 | 180 | const sources = input.compilations[0].sources.filter((_: any, index: any) => { 181 | return sourceIndicesInvolvedInTransaction.includes(index) 182 | }) 183 | 184 | setSources( 185 | sources 186 | ); 187 | 188 | setSession(initializedSession); 189 | setVariables(await initializedSession.variables()); 190 | setReturnValue(await initializedSession.returnValue()); 191 | setStatus(await initializedSession.state.evm.transaction.status); 192 | 193 | const currentSource = await initializedSession.view( 194 | TruffleDebugger.selectors.solidity.current.source 195 | ); 196 | setRunningTabIndex(currentSource.ast.id); 197 | setActiveTabIndex(currentSource.ast.id); 198 | 199 | const init = initializedSession.view( 200 | TruffleDebugger.selectors.solidity.current.sourceRange 201 | ); 202 | 203 | setActiveLine(init.lines.start.line); 204 | setSelectedLine(init.lines.start.line); 205 | }; 206 | 207 | const executeAction = async (debugAction: string) => { 208 | 209 | if (session) { 210 | switch (debugAction) { 211 | case "continueUntil": { 212 | await session.removeAllBreakpoints(); 213 | breakpoints.forEach( 214 | async breakpoint => await session.addBreakpoint(breakpoint) 215 | ); 216 | await session.continueUntilBreakpoint(); 217 | break; 218 | } 219 | case "over": 220 | await session.stepOver(); 221 | break; 222 | case "into": 223 | await session.stepInto(); 224 | break; 225 | case "out": 226 | await session.stepOut(); 227 | break; 228 | default: 229 | break; 230 | } 231 | 232 | setVariables(await session.variables()); 233 | setReturnValue(await session.returnValue()); 234 | 235 | const source = await session.view( 236 | TruffleDebugger.selectors.solidity.current.source 237 | ); 238 | setRunningTabIndex(source.ast.id); 239 | setActiveTabIndex(source.ast.id); 240 | 241 | const sourceRange = await session.view( 242 | TruffleDebugger.selectors.solidity.current.sourceRange 243 | ); 244 | setActiveLine(sourceRange.lines.start.line); 245 | setSelectedLine(sourceRange.lines.start.line); 246 | } 247 | }; 248 | 249 | useEffect(() => { 250 | start(); 251 | }, []); 252 | 253 | return ( 254 | 255 | 256 |
    257 | 258 | {` `} 259 | 260 | TX{` `} 261 | {transaction.hash || `...`} 262 | 263 | 264 |
    265 | 266 | 267 | executeAction("continueUntil")} 270 | > 271 | 272 | 273 | 274 | 275 | executeAction("over")} 277 | disabled={!variables} 278 | > 279 | 280 | 281 | 282 | 283 | 284 | executeAction("into")} 286 | disabled={!variables} 287 | > 288 | 289 | 290 | 291 | 292 | executeAction("out")} 294 | disabled={!variables} 295 | > 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | {variables ? ( 306 | <> 307 | 308 | 309 | 315 | 316 | Variables 317 | 318 | 319 | 320 | 329 | 330 | 331 | 332 | Breakpoints 333 | 339 | 340 | 341 | 342 | ) : ( 343 | 344 | )} 345 |
    346 | ); 347 | }; 348 | 349 | export default Debugger; 350 | -------------------------------------------------------------------------------- /ui/src/components/Home.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import styled from "styled-components"; 3 | import * as Colors from "../styles/colors"; 4 | import H3 from "../styles/H3"; 5 | import Transaction from "./Transaction"; 6 | import getWeb3 from "../utils/getWeb3"; 7 | 8 | const HomeContainer = styled.div` 9 | padding: 1rem 2rem; 10 | `; 11 | 12 | const TransactionsBox = styled.div` 13 | background: ${Colors.CHOCOLATE_200}; 14 | padding: 1rem; 15 | border-radius: 1rem; 16 | font-family: "Ubuntu Mono", monospace; 17 | margin-bottom: 1.25rem; 18 | font-size: 1em; 19 | `; 20 | 21 | const Home = ({port}: any) => { 22 | const [transactions, setTransactions] = useState([]); 23 | 24 | const getPendingTransactions = async () => { 25 | 26 | const web3 = await getWeb3(port); 27 | const subscription = web3.eth.subscribe('pendingTransactions'); 28 | 29 | subscription.subscribe((error: any, result: any) => { 30 | if (error) console.log(error) 31 | }) 32 | .on('data', async (txHash: any) => { 33 | 34 | try { 35 | const txn = await web3.eth.getTransaction(txHash) 36 | 37 | const transaction: any = ( 38 | 39 | ); 40 | 41 | await setTransactions((prev: any) => { 42 | return [...prev, transaction]; 43 | }); 44 | 45 | return function cleanup() { 46 | subscription.unsubscribe(); 47 | }; 48 | } 49 | catch (error) { 50 | console.log(error) 51 | } 52 | }) 53 | } 54 | 55 | useEffect(() => { 56 | getPendingTransactions(); 57 | }, []); 58 | 59 | return ( 60 | 61 |

    Transactions

    62 |

    Transactions will be listed below as they are created.

    63 | {transactions.length ? 64 | transactions.filter((v,i) => { 65 | if (i%2) { 66 | return v; // uber hack to only display even (given the subscription is returning dupes) 67 | } 68 | }) 69 | : (Waiting for transactions) } 70 |
    71 | ); 72 | }; 73 | 74 | export default Home; 75 | -------------------------------------------------------------------------------- /ui/src/components/KeyboardShortcuts.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { GlobalHotKeys } from "react-hotkeys"; 3 | 4 | interface IProps { 5 | executeAction: (debugAction: string) => Promise; 6 | start: () => Promise; 7 | } 8 | 9 | const KeyboardShortcuts = ({ executeAction, start }: IProps) => { 10 | const keyMap = { 11 | STEP_OVER: ["o", "f10"], 12 | STEP_INTO: ["i", "f11"], 13 | STEP_OUT: ["u", "shift+f11"], 14 | CONTINUE_UNTIL: ["c", "f8"], 15 | RESTART: ["r"], 16 | }; 17 | 18 | const over = () => { 19 | executeAction("over"); 20 | }; 21 | 22 | const into = () => { 23 | executeAction("into"); 24 | }; 25 | 26 | const out = () => { 27 | executeAction("out"); 28 | }; 29 | 30 | const continueUntil = () => { 31 | executeAction("continueUntil"); 32 | }; 33 | 34 | const restart = () => { 35 | start(); 36 | }; 37 | 38 | const handlers = { 39 | STEP_OVER: over, 40 | STEP_INTO: into, 41 | STEP_OUT: out, 42 | CONTINUE_UNTIL: continueUntil, 43 | RESTART: restart, 44 | }; 45 | 46 | return ( 47 | 48 | ); 49 | }; 50 | 51 | export default KeyboardShortcuts; 52 | -------------------------------------------------------------------------------- /ui/src/components/Line.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import styled from "styled-components"; 3 | import * as Colors from "../styles/colors"; 4 | 5 | export const backgroundInherit = Colors.CHOCOLATE_200; 6 | export const backgroundHighlight = Colors.YELLOW_200; 7 | export const borderHighlight = Colors.ORANGE_300; 8 | 9 | interface IHighlightProps { 10 | isCurrent: boolean; 11 | } 12 | 13 | const Row = styled.div` 14 | background: ${({ isCurrent }: IHighlightProps) => 15 | isCurrent ? `${backgroundHighlight}` : `${backgroundInherit}`}; 16 | border-color: ${({ isCurrent }: IHighlightProps) => 17 | isCurrent ? `${borderHighlight}` : `${backgroundInherit}`}; 18 | border-width: 1px; 19 | border-style: solid; 20 | border-radius: 0.4rem; 21 | width: fit-content; 22 | min-width: 100%; 23 | 24 | &:hover .fas.fa-dot-circle.faded { 25 | color: ${Colors.CI_RED}; 26 | opacity: 0.5; 27 | } 28 | `; 29 | 30 | const LineContainer = styled.span` 31 | font-family: "Ubuntu Mono", monospace; 32 | white-space: pre; 33 | padding-left: 0.2rem; 34 | cursor: text; 35 | `; 36 | 37 | const LineNumber = styled.span` 38 | color: ${Colors.GRAY_300}; 39 | padding-left: 0.2rem; 40 | cursor: pointer; 41 | `; 42 | 43 | interface IBreakpoint { 44 | isBreakpoint: boolean; 45 | } 46 | 47 | const Breakpoint = styled.i` 48 | text-align: center; 49 | display: inline-block; 50 | color: ${({ isBreakpoint }: IBreakpoint) => 51 | isBreakpoint ? Colors.CI_RED : Colors.CHOCOLATE_200}; 52 | cursor: pointer; 53 | padding-left: 0.2rem; 54 | width: 1.1rem; 55 | height: 1rem; 56 | `; 57 | 58 | export interface IProps { 59 | lineNumber: number; 60 | lineContents: string; 61 | isCurrent: boolean; 62 | breakpoints: any[]; 63 | setBreakpoints: any; 64 | lineRef: any; 65 | sourceId: string; 66 | fileName: string; 67 | astId: number; 68 | lineNumberIndentLength: number; 69 | } 70 | 71 | const Line = ({ 72 | lineNumber, 73 | lineContents, 74 | isCurrent, 75 | breakpoints, 76 | setBreakpoints, 77 | lineRef, 78 | sourceId, 79 | fileName, 80 | astId, 81 | lineNumberIndentLength, 82 | }: IProps) => { 83 | const [isBreakpoint, updateBreakpoint] = useState(false); 84 | 85 | const start = () => { 86 | updateBreakpoint( 87 | breakpoints.filter(breakpoint => { 88 | return ( 89 | breakpoint.line === lineNumber && breakpoint.sourceId === sourceId 90 | ); 91 | }).length > 0 92 | ); 93 | }; 94 | 95 | const toggleBreakpoint = () => { 96 | updateBreakpoint(!isBreakpoint); 97 | 98 | if (isBreakpoint) { 99 | const filteredBreakpoints = breakpoints.filter( 100 | breakpoint => 101 | breakpoint.line !== lineNumber || breakpoint.sourceId !== sourceId 102 | ); 103 | setBreakpoints(filteredBreakpoints); 104 | } else { 105 | const breakpoint: any = { 106 | line: lineNumber, 107 | sourceId, 108 | compilationId: "shimmedcompilation", 109 | fileName, 110 | astId, 111 | }; 112 | setBreakpoints((prev: any) => { 113 | return [...prev, breakpoint]; 114 | }); 115 | } 116 | }; 117 | 118 | useEffect(() => { 119 | start(); 120 | }, [breakpoints]); 121 | 122 | return ( 123 | 128 | 135 | 136 | 137 | {` `.repeat(lineNumberIndentLength)} 138 | {lineNumber + 1}.{` `} 139 | 140 | 141 | 142 | 143 | ); 144 | }; 145 | 146 | export default Line; 147 | -------------------------------------------------------------------------------- /ui/src/components/Navigation.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import * as Colors from "../styles/colors"; 4 | 5 | import { 6 | Link 7 | } from "react-router-dom"; 8 | 9 | const NavBarContainer = styled.div` 10 | width: 100%; 11 | background-color: #EFE5DC; 12 | `; 13 | 14 | const NavBar = styled.ul` 15 | list-style-type: none; 16 | margin: 0; 17 | padding: 0.8rem 0; 18 | border-bottom: solid 1px ${Colors.GRAY_300}; 19 | li { 20 | display: inline; 21 | padding: 1rem; 22 | } 23 | a { 24 | font-weight: 500; 25 | text-decoration: none; 26 | color: ${Colors.DARK_CHOCOLATE}; 27 | } 28 | `; 29 | 30 | const Navigation = ({}) => { 31 | return ( 32 | 33 | 34 |
  • 35 |
  • Transactions
  • 36 |
  • Accounts
  • 37 |
  • Settings
  • 38 |
    39 |
    40 | ); 41 | }; 42 | 43 | export default Navigation; 44 | -------------------------------------------------------------------------------- /ui/src/components/Settings.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import styled from "styled-components"; 3 | import * as Colors from "../styles/colors"; 4 | import H3 from "../styles/H3"; 5 | 6 | import { 7 | Link, 8 | } from "react-router-dom"; 9 | 10 | const SettingsContainer = styled.div` 11 | padding: 1rem 2rem; 12 | `; 13 | 14 | const SettingsForm = styled.form` 15 | label { 16 | margin: 0.4rem 0; 17 | display: block; 18 | 19 | } 20 | label input { 21 | display: ; 22 | margin: 0.4rem ; 23 | } 24 | input[type=submit] { 25 | display: block; 26 | } 27 | `; 28 | 29 | const Settings = ({port, setPort, rpc, setRpc}: any) => { 30 | const [newPort, setNewPort] = useState(port); 31 | const [newRpc, setNewRpc] = useState(rpc); 32 | 33 | const save: any = (e:any) => { 34 | e.preventDefault(); 35 | setPort(newPort); 36 | setRpc(newRpc); 37 | // TODO display toast 38 | }; 39 | 40 | return ( 41 | 42 |

    Settings

    43 | 44 | 48 | 52 | 53 | 54 |
    55 | ); 56 | }; 57 | 58 | export default Settings; 59 | -------------------------------------------------------------------------------- /ui/src/components/Source.tsx: -------------------------------------------------------------------------------- 1 | import React, { 2 | createRef, 3 | useRef, 4 | useEffect, 5 | useState, 6 | useLayoutEffect, 7 | } from "react"; 8 | import styled from "styled-components"; 9 | import SyntaxStyle from "./SyntaxStyle"; 10 | import Line from "./Line"; 11 | 12 | const SourceWrapper = styled.div` 13 | padding: 1rem 0.5rem; 14 | overflow-x: scroll; 15 | overflow-y: scroll; 16 | white-space: nowrap; 17 | `; 18 | 19 | interface IProps { 20 | activeLine: number; 21 | selectedLine: number; 22 | contractSource: string[]; 23 | breakpoints: any[]; 24 | setBreakpoints: any; 25 | visible: boolean; 26 | sourceIsActive: boolean; 27 | sourceId: string; 28 | fileName: string; 29 | astId: number; 30 | } 31 | 32 | const Source = ({ 33 | activeLine, 34 | selectedLine, 35 | contractSource, 36 | breakpoints, 37 | setBreakpoints, 38 | visible, 39 | sourceIsActive, 40 | sourceId, 41 | fileName, 42 | astId, 43 | }: IProps) => { 44 | const output: React.ReactNode[] = []; 45 | const [scrollTop, setScrollTop] = useState(0); 46 | const sourceRef = useRef(null); 47 | const lineDigitLength = contractSource.length.toString().length; 48 | 49 | let selectedLineRef: any; 50 | 51 | contractSource.forEach((line: string) => { 52 | const lineRef = createRef(); 53 | if (output.length === selectedLine) { 54 | selectedLineRef = lineRef; 55 | } 56 | output.push( 57 | 72 | ); 73 | }); 74 | 75 | useEffect(() => { 76 | if (selectedLineRef) { 77 | if (selectedLineRef.current) { 78 | selectedLineRef.current.scrollIntoView({ 79 | behavior: "auto", 80 | block: "center", 81 | }); 82 | } 83 | } 84 | }, [selectedLine]); 85 | 86 | useLayoutEffect(() => { 87 | if (visible) { 88 | if (sourceRef.current !== null) { 89 | sourceRef.current.scrollTo({ 90 | top: scrollTop, 91 | left: 0, 92 | behavior: "auto", 93 | }); 94 | } 95 | } 96 | }, [visible]); 97 | 98 | const updateLine = (e: any) => { 99 | setScrollTop(e.target.scrollTop); 100 | }; 101 | 102 | return ( 103 | <> 104 | {visible ? ( 105 | 106 | {output} 107 | 108 | ) : null} 109 | 110 | ); 111 | }; 112 | 113 | export default Source; 114 | -------------------------------------------------------------------------------- /ui/src/components/Sources.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import Source from "./Source"; 3 | import unified from "unified"; 4 | import stringify from "rehype-dom-stringify"; 5 | import low from "lowlight"; 6 | import { definer } from "highlightjs-solidity"; 7 | 8 | interface IProps { 9 | sources: any; 10 | activeTabIndex: number; 11 | breakpoints: any[]; 12 | setBreakpoints: any; 13 | activeLine: number; 14 | selectedLine: number; 15 | runningTabIndex: number; 16 | } 17 | 18 | interface IPropsRenderer { 19 | rows: any; 20 | stylesheet: any; 21 | useInlineStyles: any; 22 | } 23 | 24 | const Sources = ({ 25 | sources, 26 | activeTabIndex, 27 | breakpoints, 28 | setBreakpoints, 29 | activeLine, 30 | selectedLine, 31 | runningTabIndex, 32 | }: IProps) => { 33 | const [sourcesWithMarkup, setSourcesWithMarkup] = useState([]); 34 | 35 | const sourceComponents = sources.map((source: any, index: number) => { 36 | const astId = source.ast.id; 37 | const fileName = source.sourcePath.replace(/^.*[\\/]/, ""); 38 | const highlightedSource: string[] = []; 39 | 40 | if (sourcesWithMarkup.length === 0) { 41 | low.registerLanguage("solidity", definer); 42 | const tree: any = low.highlight("solidity", source.source).value; 43 | const processor: any = unified().use(stringify); 44 | const highlightedMarkup: any = processor 45 | .stringify({ type: "root", children: tree }) 46 | .toString(); 47 | 48 | highlightedMarkup.split("\n").forEach((lineMarkup: string) => { 49 | highlightedSource.push(lineMarkup); 50 | }); 51 | 52 | setSourcesWithMarkup(prevState => [...prevState, highlightedSource]); 53 | } 54 | 55 | return ( 56 | 0 61 | ? highlightedSource 62 | : sourcesWithMarkup[index] 63 | } 64 | activeLine={activeLine} 65 | selectedLine={selectedLine} 66 | breakpoints={breakpoints} 67 | setBreakpoints={setBreakpoints} 68 | sourceIsActive={astId === runningTabIndex} 69 | sourceId={source.id} 70 | astId={astId} 71 | fileName={fileName} 72 | /> 73 | ); 74 | }); 75 | 76 | return <>{sourceComponents}; 77 | }; 78 | 79 | export default Sources; 80 | -------------------------------------------------------------------------------- /ui/src/components/StatusIcon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import LoadingSmall from "../styles/LoadingSmall"; 4 | import IconBase from "../styles/IconBase"; 5 | import * as Colors from "../styles/colors"; 6 | 7 | const TxSuccess = styled(IconBase)` 8 | color: ${Colors.CI_GREEN}; 9 | `; 10 | 11 | const TxFail = styled(IconBase)` 12 | color: ${Colors.CI_RED}; 13 | `; 14 | 15 | interface IProps { 16 | status?: any; 17 | } 18 | 19 | const StatusIcon = ({ status }: IProps) => { 20 | return ( 21 | <> 22 | {status === null ? ( 23 | 24 | ) : status ? ( 25 | 29 | ) : ( 30 | 31 | )} 32 | 33 | ); 34 | }; 35 | 36 | export default StatusIcon; 37 | -------------------------------------------------------------------------------- /ui/src/components/StatusMessage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { radius } from "../styles/MetaWrapper"; 4 | import * as Colors from "../styles/colors"; 5 | 6 | const Wrapper = styled.div` 7 | grid-template-columns: 3.5fr 1.5fr; 8 | display: grid; 9 | `; 10 | 11 | const StatusContainer = styled.div` 12 | background: ${Colors.RED_100}; 13 | border: solid 1px ${Colors.RED_600}; 14 | color: ${Colors.RED_600}; 15 | padding: 1rem 1rem; 16 | margin-top: 1rem; 17 | border-radius: ${radius}; 18 | font-family: "Ubuntu Mono", monospace; 19 | font-size: 1rem; 20 | 21 | > * { 22 | &:not(:last-child) { 23 | margin: 0 0.2rem 0 0; 24 | } 25 | } 26 | `; 27 | 28 | interface IProps { 29 | returnValue: any; 30 | } 31 | 32 | const StatusMessage = ({ returnValue }: IProps) => { 33 | let statusDescription: any | null; 34 | let statusMessage: any | null; 35 | 36 | if (returnValue?.length > 0) { 37 | switch (returnValue[0].kind) { 38 | case "revert": 39 | statusDescription = `VM Exception while processing transaction`; 40 | statusMessage = `${returnValue[0].kind} -- ${returnValue[0].arguments[0].value.value.asString}`; 41 | break; 42 | case "selfdestruct": 43 | case "return": 44 | default: 45 | return <>; 46 | break; 47 | } 48 | } 49 | 50 | return ( 51 | <> 52 | {returnValue ? ( 53 | 54 | 55 | {`${statusDescription}: ${statusMessage}`} 56 | 57 | 58 | ) : null} 59 | 60 | ); 61 | }; 62 | 63 | export default StatusMessage; 64 | -------------------------------------------------------------------------------- /ui/src/components/SyntaxStyle.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import * as Colors from "../styles/colors"; 3 | 4 | const SyntaxStyle = styled.div` 5 | .hljs-comment, 6 | .hljs-quote { 7 | color: ${Colors.GREY}; 8 | font-style: italic; 9 | } 10 | 11 | .hljs-keyword, 12 | .hljs-selector-tag, 13 | .hljs-subst { 14 | color: ${Colors.PINK_500}; 15 | font-weight: bold; 16 | } 17 | 18 | .hljs-number, 19 | .hljs-literal, 20 | .hljs-variable, 21 | .hljs-template-variable, 22 | .hljs-tag .hljs-attr { 23 | color: ${Colors.WATERMELON_600}; 24 | } 25 | 26 | .hljs-string, 27 | .hljs-doctag { 28 | color: ${Colors.PORSCHE_1}; 29 | } 30 | 31 | .hljs-title, 32 | .hljs-section, 33 | .hljs-selector-id { 34 | color: ${Colors.TEAL_1}; 35 | font-weight: bold; 36 | } 37 | 38 | .hljs-subst { 39 | font-weight: normal; 40 | } 41 | 42 | .hljs-type, 43 | .hljs-class .hljs-title { 44 | color: ${Colors.TEAL_1}; 45 | font-weight: bold; 46 | } 47 | 48 | .hljs-tag, 49 | .hljs-name, 50 | .hljs-attribute { 51 | color: ${Colors.TEAL_1}; 52 | font-weight: normal; 53 | } 54 | 55 | .hljs-built_in, 56 | .hljs-builtin-name { 57 | color: ${Colors.TEAL_1}; 58 | } 59 | `; 60 | 61 | export default SyntaxStyle; 62 | -------------------------------------------------------------------------------- /ui/src/components/Tab.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import StyledTab from "../styles/Tab"; 4 | import Tooltip from "../styles/Tooltip"; 5 | import * as Colors from "../styles/colors"; 6 | 7 | interface IIndexProps { 8 | activeTabIndex: number; 9 | index: number; 10 | } 11 | 12 | const TabButton = styled(StyledTab)` 13 | background: ${({ activeTabIndex, index }: IIndexProps) => 14 | activeTabIndex === index ? `${Colors.TEAL_2}` : `${Colors.WHITE}`}; 15 | border-color: ${Colors.TEAL_1} !important; 16 | color: inherit; 17 | text-transform: none; 18 | 19 | &:hover { 20 | background: ${Colors.TEAL_1}; 21 | color: ${Colors.WHITE}; 22 | * { 23 | color: ${Colors.WHITE}; 24 | } 25 | } 26 | 27 | text-overflow: ellipsis; 28 | overflow: hidden; 29 | white-space: nowrap; 30 | flex-basis: auto; 31 | position: relative; 32 | `; 33 | 34 | const ActiveIcon = styled.div` 35 | color: ${Colors.ORANGE_400}; 36 | font-size: 0.6em; 37 | vertical-align: middle; 38 | position: absolute; 39 | right: 0.6rem; 40 | top: 0.9rem; 41 | `; 42 | 43 | interface IProps { 44 | index: number; 45 | tabName: string; 46 | activeTabIndex: number; 47 | setActiveTabIndex: any; 48 | tabIsRunning: boolean; 49 | } 50 | 51 | const Tab = ({ 52 | index, 53 | tabName, 54 | activeTabIndex, 55 | setActiveTabIndex, 56 | tabIsRunning, 57 | }: IProps) => { 58 | return ( 59 | // {tabName}}> 60 | <> 61 | setActiveTabIndex(index)} 63 | selected={activeTabIndex === index} 64 | activeTabIndex={activeTabIndex} 65 | index={index} 66 | > 67 | {tabName}{" "} 68 | {tabIsRunning ? : null} 69 | 70 | 71 | // 72 | ); 73 | }; 74 | 75 | export default Tab; 76 | -------------------------------------------------------------------------------- /ui/src/components/Tabs.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Tab from "./Tab"; 3 | import styled from "styled-components"; 4 | 5 | interface IProps { 6 | sources: any; 7 | setActiveTabIndex: any; 8 | activeTabIndex: number; 9 | runningTabIndex: number; 10 | } 11 | 12 | const TabsWrapper = styled.div` 13 | display: flex; 14 | flex-direction: row; 15 | flex-wrap: nowrap; 16 | `; 17 | 18 | const Tabs = ({ 19 | sources, 20 | setActiveTabIndex, 21 | activeTabIndex, 22 | runningTabIndex, 23 | }: IProps) => { 24 | const tabs = sources.map((source: any) => { 25 | const fileName = source.sourcePath.replace(/^.*[\\/]/, ""); 26 | const astId = source.ast.id; 27 | return ( 28 | 36 | ); 37 | }); 38 | 39 | return {tabs}; 40 | }; 41 | 42 | export default Tabs; 43 | -------------------------------------------------------------------------------- /ui/src/components/Transaction.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { CHOCOLATE_200, CHOCOLATE_800 } from "../styles/colors"; 4 | 5 | import { 6 | Link 7 | } from "react-router-dom"; 8 | 9 | const TransactionWrapper = styled.div` 10 | background: ${CHOCOLATE_200}; 11 | padding: 1rem; 12 | border-radius: 1rem; 13 | font-family: "Ubuntu Mono", monospace; 14 | margin-bottom: 1.25rem; 15 | font-size: 1em; 16 | overflow-x: scroll; 17 | overflow-y: scroll; 18 | a { 19 | text-decoration: none; 20 | color: ${CHOCOLATE_800}; 21 | } 22 | `; 23 | 24 | const Transaction = ({ transaction, port }: any) => { 25 | 26 | return ( 27 | 28 | 29 | {`Block ${transaction.blockNumber}: `} 30 | {transaction.hash} 31 | 32 | 33 | ); 34 | }; 35 | 36 | export default Transaction; 37 | -------------------------------------------------------------------------------- /ui/src/components/Tray.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import * as Colors from "../styles/colors"; 4 | 5 | const TrayWrapper = styled.div` 6 | background: ${Colors.CHOCOLATE_200}; 7 | padding: 1rem; 8 | border-radius: 1rem; 9 | font-size: 1em; 10 | overflow-x: scroll; 11 | overflow-y: scroll; 12 | `; 13 | 14 | const Row = styled.div` 15 | margin: 0.1rem 0; 16 | cursor: pointer; 17 | padding: 0.25rem 0.1rem; 18 | border-width: 0.1rem; 19 | border-radius: 0.5rem; 20 | 21 | &:hover { 22 | background-color: ${Colors.GRAY_100}; 23 | } 24 | `; 25 | 26 | const Breakpoint = styled.span` 27 | margin-left: 0.4rem; 28 | `; 29 | 30 | const Icon = styled.span` 31 | color: ${Colors.CI_RED}; 32 | `; 33 | 34 | const Badge = styled.span` 35 | background: ${Colors.CHOCOLATE_400}; 36 | border: solid 1px ${Colors.CHOCOLATE_500}; 37 | border-radius: 0.5rem; 38 | padding: 0.025rem 0.2rem; 39 | color: #fff; 40 | `; 41 | 42 | const Remove = styled.span` 43 | color: ${Colors.CHOCOLATE_400}; 44 | margin-left: 0.25rem; 45 | `; 46 | 47 | export interface IProps { 48 | breakpoints: any; 49 | setBreakpoints: any; 50 | setActiveTabIndex: any; 51 | setSelectedLine: any; 52 | } 53 | 54 | const Tray = ({ 55 | breakpoints, 56 | setBreakpoints, 57 | setActiveTabIndex, 58 | setSelectedLine, 59 | }: IProps) => { 60 | const removeBreakpoint = (sourceId: number, lineNumber: number) => { 61 | const filteredBreakpoints = breakpoints.filter((breakpoint: any) => { 62 | return breakpoint.line !== lineNumber || breakpoint.sourceId !== sourceId; 63 | }); 64 | setBreakpoints(filteredBreakpoints); 65 | }; 66 | 67 | const jumptoLine = (astId: number, lineNumber: number) => { 68 | setActiveTabIndex(astId); 69 | setSelectedLine(lineNumber); 70 | }; 71 | 72 | const list = breakpoints.map((breakpoint: any, index: number) => { 73 | const sourceId = breakpoint.sourceId; 74 | const fileName = breakpoint.fileName; 75 | const lineNumber = breakpoint.line; 76 | const astId = breakpoint.astId; 77 | return ( 78 | 79 | removeBreakpoint(sourceId, lineNumber)} 82 | /> 83 | jumptoLine(astId, lineNumber)}> 84 | {fileName} 85 | {lineNumber + 1} 86 | 87 | removeBreakpoint(sourceId, lineNumber)} 90 | /> 91 | 92 | ); 93 | }); 94 | 95 | return ( 96 | 97 | {list.length > 0 98 | ? list 99 | : `Add a breakpoint by clicking to the left of the line`} 100 | 101 | ); 102 | }; 103 | 104 | export default Tray; 105 | -------------------------------------------------------------------------------- /ui/src/components/Variables.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import getDecodedValue from "../utils/getDecodedValue"; 4 | import ReactJson from "react-json-view"; 5 | // import { VARIABLES_OUTPUT as variablesTheme } from "../../styles/components"; 6 | import { CHOCOLATE_200 } from "../styles/colors"; 7 | 8 | const VariablesWrapper = styled.div` 9 | background: ${CHOCOLATE_200}; 10 | padding: 1rem; 11 | border-radius: 1rem; 12 | font-family: "Ubuntu Mono", monospace; 13 | margin-bottom: 1.25rem; 14 | font-size: 1em; 15 | * { 16 | background-color: inherit !important; 17 | font-family: "Ubuntu Mono", monospace; 18 | } 19 | ul, 20 | ul li { 21 | margin-top: 0em !important; 22 | paddding-top: 0em !important; 23 | } 24 | overflow-x: scroll; 25 | overflow-y: scroll; 26 | `; 27 | 28 | export interface IProps { 29 | variables: any; 30 | } 31 | 32 | const Variables = ({ variables }: IProps) => { 33 | const state: any = {}; 34 | 35 | if (variables) { 36 | const variableKeys = Object.keys(variables); 37 | variableKeys.forEach(variable => { 38 | const value = getDecodedValue(variables[variable]); 39 | state[variable] = value; 40 | }); 41 | } 42 | 43 | return ( 44 | 45 | 53 | 54 | ); 55 | }; 56 | 57 | export default Variables; 58 | -------------------------------------------------------------------------------- /ui/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /ui/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | 11 | , 12 | document.getElementById('root') 13 | ); 14 | 15 | // If you want to start measuring performance in your app, pass a function 16 | // to log results (for example: reportWebVitals(console.log)) 17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /ui/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /ui/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /ui/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /ui/src/styles/H3.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import * as Colors from "./colors"; 3 | 4 | const H3 = styled.h3` 5 | font-family: "Oswald", sans-serif; 6 | font-size: 1.75rem; 7 | color: ${Colors.DARK_CHOCOLATE}; 8 | margin: 0; 9 | `; 10 | export default H3; 11 | -------------------------------------------------------------------------------- /ui/src/styles/Icon.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const size = "25px"; 4 | export default styled.i` 5 | width: ${size}; 6 | height: ${size}; 7 | display: inline-flex; 8 | justify-content: center; 9 | align-items: center; 10 | border-radius: 4px; 11 | `; 12 | -------------------------------------------------------------------------------- /ui/src/styles/IconBase.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const size = "25px"; 4 | export default styled.i` 5 | width: ${size}; 6 | height: ${size}; 7 | display: inline-flex; 8 | justify-content: center; 9 | align-items: center; 10 | border-radius: 4px; 11 | `; 12 | -------------------------------------------------------------------------------- /ui/src/styles/List.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export interface IProps { 4 | marginBottom?: string; 5 | } 6 | 7 | const List = styled.div` 8 | > * { 9 | &:not(:last-child) { 10 | margin-bottom: ${({ marginBottom = "1rem" }: IProps) => marginBottom}; 11 | } 12 | } 13 | `; 14 | export default List; 15 | -------------------------------------------------------------------------------- /ui/src/styles/Loading.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import RingLoader from "react-spinners/RingLoader"; 3 | import styled from "styled-components"; 4 | import * as Colors from "./colors"; 5 | 6 | const Wrapper = styled.div` 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | height: 100%; 11 | `; 12 | 13 | const Loading = (props: any) => ( 14 | 15 | 16 | 17 | ); 18 | export default Loading; 19 | -------------------------------------------------------------------------------- /ui/src/styles/LoadingSmall.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled, { keyframes } from "styled-components"; 3 | import Icon from "./Icon"; 4 | 5 | interface IProps { 6 | className?: string; 7 | } 8 | 9 | const rotate = keyframes` 10 | from { 11 | transform: rotate(0deg); 12 | } 13 | 14 | to { 15 | transform: rotate(360deg); 16 | } 17 | `; 18 | 19 | const StyledIcon = styled(Icon)` 20 | animation: ${rotate} 2s linear infinite; 21 | `; 22 | 23 | export default ({ className = "" }: IProps) => ( 24 | 25 | ); 26 | -------------------------------------------------------------------------------- /ui/src/styles/MetaWrapper.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import * as Colors from "./colors"; 3 | 4 | export const padding = "1.5rem"; 5 | export const radius = "0.5rem"; 6 | 7 | export default styled.div` 8 | background: ${Colors.CHOCOLATE_200}; 9 | padding: ${padding}; 10 | border-radius: ${radius}; 11 | `; 12 | -------------------------------------------------------------------------------- /ui/src/styles/PrimaryButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import * as Colors from "./colors"; 3 | 4 | export default styled.button` 5 | background: ${Colors.MINT_400}; 6 | border: none; 7 | border-radius: 0.25rem; 8 | padding: 0.5rem 1rem; 9 | cursor: pointer; 10 | text-transform: uppercase; 11 | font-size: 1rem; 12 | font-family: "Fira Sans Condensed", sans-serif; 13 | `; 14 | -------------------------------------------------------------------------------- /ui/src/styles/Tab.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { style as TabButtonStyle } from "./TabButton"; 3 | import * as Colors from "./colors"; 4 | 5 | export interface IProps { 6 | selected?: boolean; 7 | } 8 | 9 | const Tab = styled.div` 10 | ${TabButtonStyle} 11 | /* To make sure padding works in
    tag */ 12 | display: inline-block; 13 | background: ${({ selected }: IProps) => 14 | selected ? Colors.MILK_CHOCOLATE : "transparent"}; 15 | color: ${({ selected }: IProps) => 16 | selected ? "white" : Colors.MILK_CHOCOLATE}; 17 | `; 18 | 19 | export default Tab; 20 | -------------------------------------------------------------------------------- /ui/src/styles/TabButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import * as Colors from "./colors"; 3 | 4 | const borderRadius = "0.3125rem"; 5 | const borderWidth = "0.125rem"; 6 | const borderStyle = "solid"; 7 | const borderColor = Colors.MILK_CHOCOLATE; 8 | const border = `${borderWidth} ${borderStyle} ${borderColor}`; 9 | export const style = ` 10 | border-top: ${border}; 11 | border-bottom: ${border}; 12 | border-left: ${border}; 13 | border-right: 0px; 14 | padding: 0.5rem 1.5rem; 15 | text-decoration: none; 16 | &:first-child { 17 | border-radius: ${borderRadius} 0 0 ${borderRadius}; 18 | } 19 | &:last-child { 20 | border-radius: 0 ${borderRadius} ${borderRadius} 0; 21 | border-right: ${border}; 22 | } 23 | &:only-child { 24 | border-radius: ${borderRadius}; 25 | } 26 | cursor: pointer; 27 | text-transform: uppercase; 28 | font-size: 1rem; 29 | font-family: "Fira Sans", sans-serif; 30 | `; 31 | 32 | const TabButton = styled.button` 33 | ${style} 34 | background: transparent; 35 | color: ${Colors.MILK_CHOCOLATE}; 36 | `; 37 | export default TabButton; 38 | -------------------------------------------------------------------------------- /ui/src/styles/Tooltip.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import TooltipBase, { RCTooltip } from "rc-tooltip"; 3 | import { createGlobalStyle } from "styled-components"; 4 | 5 | // Access rc-tooltip's global classes to adjust tooltip styles 6 | const TooltipStyleFix = createGlobalStyle` 7 | .rc-tooltip-inner { 8 | min-height: 0; 9 | } 10 | `; 11 | 12 | // interface IProps extends RCTooltip.Props { 13 | // children: React.ReactNode; 14 | // } 15 | 16 | const Tooltip = ({ children, ...rest }: any) => ( 17 | <> 18 | 19 | {children} 20 | 21 | ); 22 | 23 | export default Tooltip; 24 | -------------------------------------------------------------------------------- /ui/src/styles/colors.ts: -------------------------------------------------------------------------------- 1 | // Neutrals 2 | export const DARK_CREAM = "#e0dad7"; 3 | export const MILK_CHOCOLATE = "#5e464d"; 4 | export const DARK_CHOCOLATE = "#33262a"; 5 | 6 | // Brand Primaries 7 | export const PURPLE_1 = "#8731e8"; 8 | 9 | // Utilities 10 | export const rgba = (r: number, g: number, b: number) => (a: number): string => 11 | `rgba(${r},${g},${b},${a})`; 12 | 13 | export enum Mode { 14 | LIGHT = "light", 15 | DARK = "dark", 16 | } 17 | 18 | export const CI_GREEN = "#00A311"; 19 | export const CI_YELLOW = "#f2e941"; 20 | export const CI_RED = "#d60000"; 21 | 22 | export const BLUE_LINK = "#25a9e0"; 23 | export const BLUE_LINK_ON_LIGHT_CREAM = "#0070a3"; 24 | export const BLUE_LINK_ON_DARK_CREAM = "#005279"; 25 | 26 | export const GREY = "rgba(0, 0, 0, 0.5)"; 27 | 28 | export const LIGHT_YELLOW = "#f5f3c5"; 29 | 30 | export const TAG_BORDER_YELLOW = "rgb(242, 233, 65)"; 31 | export const TAG_BORDER_BEIGE = "rgb(224, 218, 215)"; 32 | 33 | export const TEAL_1 = "#47BAA7"; 34 | export const TEAL_2 = "#CAF0E5"; 35 | 36 | export const ALTO = "#DCDCDC"; 37 | export const RGBA_ALTO = rgba(0xdc, 0xdc, 0xdc); 38 | 39 | export const DANUBE = "#6c88d1"; 40 | export const RGBA_DANUBE = rgba(0x6c, 0x88, 0xd1); 41 | 42 | export const GUARDSMANRED = "#d10000"; 43 | export const RGBA_GUARDSMANRED = rgba(0xd1, 0, 0); 44 | 45 | export const SPRINGWOOD = "#f8f5f0"; 46 | export const RGBA_SPRINGWOOD = rgba(0xf8, 0xf5, 0xf0); 47 | 48 | /* 49 | DESIGN SYSTEM COLORS 50 | */ 51 | 52 | /* 53 | * NEUTRALS 54 | */ 55 | 56 | // GRAY 57 | export const WHITE = "#ffffff"; 58 | export const GRAY_100 = "#f4f4f4"; 59 | export const GRAY_200 = "#e5e5e5"; 60 | export const GRAY_300 = "#c8c8c8"; 61 | export const GRAY_400 = "#a9a9a9"; 62 | export const GRAY_500 = "#858585"; 63 | export const GRAY_600 = "#636363"; 64 | export const GRAY_700 = "#4a4a4a"; 65 | export const GRAY_800 = "#363636"; 66 | export const GRAY_900 = "#292929"; 67 | export const BLACK = "#000000"; 68 | 69 | // Chocolate 70 | export const CHOCOLATE_100 = "#f8f5f0"; 71 | export const CHOCOLATE_200 = "#efe5dc"; 72 | export const CHOCOLATE_300 = "#d6c4ba"; 73 | export const CHOCOLATE_400 = "#bca296"; 74 | export const CHOCOLATE_500 = "#967e75"; 75 | export const CHOCOLATE_600 = "#725b54"; 76 | export const CHOCOLATE_700 = "#56443f"; 77 | export const CHOCOLATE_800 = "#3f302d"; 78 | export const CHOCOLATE_900 = "#2f2323"; 79 | 80 | /* 81 | * COLORS 82 | */ 83 | 84 | // WATERMELON 85 | export const WATERMELON_100 = "#ffeff4"; 86 | export const WATERMELON_200 = "#ffd9e5"; 87 | export const WATERMELON_300 = "#ffadc8"; 88 | export const WATERMELON_400 = "#ff7ea9"; 89 | export const WATERMELON_500 = "#dc5985"; 90 | export const WATERMELON_600 = "#b3004f"; 91 | export const WATERMELON_700 = "#87003e"; 92 | export const WATERMELON_800 = "#690030"; 93 | export const WATERMELON_900 = "#540026"; 94 | 95 | // PINK 96 | export const PINK_100 = "#fdeaf9"; 97 | export const PINK_200 = "#fbcef2"; 98 | export const PINK_300 = "#f698e3"; 99 | export const PINK_400 = "#f05ed2"; 100 | export const PINK_500 = "#ea1bc0"; 101 | export const PINK_600 = "#b50d93"; 102 | export const PINK_700 = "#870a6e"; 103 | export const PINK_800 = "#630750"; 104 | export const PINK_900 = "#4b053d"; 105 | 106 | // RED 107 | export const RED_100 = "#fbe9e9"; 108 | export const RED_200 = "#f7cbcb"; 109 | export const RED_300 = "#ed9191"; 110 | export const RED_400 = "#e35353"; 111 | export const RED_500 = "#d80b0b"; 112 | export const RED_600 = "#a60000"; 113 | export const RED_700 = "#7c0000"; 114 | export const RED_800 = "#5b0000"; 115 | export const RED_900 = "#450000"; 116 | 117 | // ORANGE 118 | export const ORANGE_100 = "#fff3e4"; 119 | export const ORANGE_200 = "#ffe0be"; 120 | export const ORANGE_300 = "#fbbd7a"; 121 | export const ORANGE_400 = "#dc9e5b"; 122 | export const ORANGE_500 = "#b87a37"; 123 | export const ORANGE_600 = "#965815"; 124 | export const ORANGE_700 = "#7a4101"; 125 | export const ORANGE_800 = "#592f01"; 126 | export const ORANGE_900 = "#442401"; 127 | 128 | // PORSCHE 129 | export const PORSCHE_1 = "#e4a663"; 130 | 131 | // YELLOW 132 | export const YELLOW_100 = "#fffdde"; 133 | export const YELLOW_200 = "#fffbbc"; 134 | export const YELLOW_300 = "#e9e26f"; 135 | export const YELLOW_400 = "#d1cb57"; 136 | export const YELLOW_500 = "#b6b03c"; 137 | export const YELLOW_600 = "#7b7619"; 138 | export const YELLOW_700 = "#69651a"; 139 | export const YELLOW_800 = "#3f3b01"; 140 | export const YELLOW_900 = "#302d01"; 141 | 142 | // BRUSH 143 | export const BRUSH_100 = "#f9ffe2"; 144 | export const BRUSH_200 = "#eef6cc"; 145 | export const BRUSH_300 = "#c6d38e"; 146 | export const BRUSH_400 = "#a7b46f"; 147 | export const BRUSH_500 = "#83904b"; 148 | export const BRUSH_600 = "#616e29"; 149 | export const BRUSH_700 = "#485510"; 150 | export const BRUSH_800 = "#354001"; 151 | export const BRUSH_900 = "#293101"; 152 | 153 | // GREEN 154 | export const GREEN_100 = "#effcf0"; 155 | export const GREEN_200 = "#e3f8e6"; 156 | export const GREEN_300 = "#b5edba"; 157 | export const GREEN_400 = "#81e28c"; 158 | export const GREEN_500 = "#2ed047"; 159 | export const GREEN_600 = "#00850f"; 160 | export const GREEN_700 = "#005507"; 161 | export const GREEN_800 = "#003b06"; 162 | export const GREEN_900 = "#002b04"; 163 | 164 | // MINT 165 | export const MINT_100 = "#ddfff9"; 166 | export const MINT_200 = "#c8fbf2"; 167 | export const MINT_300 = "#90f4e3"; 168 | export const MINT_400 = "#3fe0c5"; 169 | export const MINT_500 = "#17b89d"; 170 | export const MINT_600 = "#007d65"; 171 | export const MINT_700 = "#005a49"; 172 | export const MINT_800 = "#004135"; 173 | export const MINT_900 = "#003127"; 174 | 175 | // BLUE 176 | export const BLUE_100 = "#edfaff"; 177 | export const BLUE_200 = "#daf4fc"; 178 | export const BLUE_300 = "#a0e4f8"; 179 | export const BLUE_400 = "#64d2f4"; 180 | export const BLUE_500 = "#39b0de"; 181 | export const BLUE_600 = "#0070a3"; 182 | export const BLUE_700 = "#005279"; 183 | export const BLUE_800 = "#003b56"; 184 | export const BLUE_900 = "#002c40"; 185 | 186 | // PERIWINKLE 187 | export const PERIWINKLE_100 = "#f0f5ff"; 188 | export const PERIWINKLE_200 = "#d9e6ff"; 189 | export const PERIWINKLE_300 = "#adcbff"; 190 | export const PERIWINKLE_400 = "#8eace0"; 191 | export const PERIWINKLE_500 = "#6a88bc"; 192 | export const PERIWINKLE_600 = "#48669a"; 193 | export const PERIWINKLE_700 = "#2f4d81"; 194 | export const PERIWINKLE_800 = "#1b396d"; 195 | export const PERIWINKLE_900 = "#0e2c60"; 196 | 197 | // PURPLE 198 | export const PURPLE_100 = "#f5edfd"; 199 | export const PURPLE_200 = "#e7d5fa"; 200 | export const PURPLE_300 = "#cba6f5"; 201 | export const PURPLE_400 = "#ae74ef"; 202 | export const PURPLE_500 = "#8c3ae9"; 203 | export const PURPLE_600 = "#6926b4"; 204 | export const PURPLE_700 = "#4e1c87"; 205 | export const PURPLE_800 = "#391562"; 206 | export const PURPLE_900 = "#2b104b"; 207 | -------------------------------------------------------------------------------- /ui/src/types/truffle.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@truffle/debugger'; 2 | declare module '@truffle/provider'; 3 | declare module 'rehype-dom-stringify'; 4 | declare module 'highlightjs-solidity'; 5 | declare module '@truffle/debug-utils'; 6 | declare module 'rc-tooltip'; 7 | declare module "react-spinners/RingLoader"; 8 | declare module 'react-router-dom'; 9 | declare module 'web3'; 10 | declare module '@truffle/compile-common'; 11 | -------------------------------------------------------------------------------- /ui/src/utils/getDecodedValue.ts: -------------------------------------------------------------------------------- 1 | const getDecodedValue = (inputObj: any) => { 2 | const typeClass = inputObj.type.typeClass; 3 | 4 | if (inputObj.error) { 5 | return "NA"; 6 | } 7 | 8 | if (typeClass === "magic") { 9 | const variable: string = inputObj.type.variable; 10 | if ( 11 | variable === "block" || 12 | variable === "message" || 13 | variable === "transaction" 14 | ) { 15 | return inputObj.value; 16 | } 17 | } 18 | 19 | if (typeClass === "contract") { 20 | return inputObj.value.address; 21 | } 22 | 23 | if (typeClass === "int" || typeClass === "uint") { 24 | return inputObj.value.asBN.toString(); // temporarily converting to string to handle big numbers 25 | } 26 | 27 | if (typeClass === "bool") { 28 | return inputObj.value.asBoolean; 29 | } 30 | 31 | if (typeClass === "string") { 32 | return inputObj.value.asString; 33 | } 34 | 35 | if (typeClass === "bytes") { 36 | return inputObj.value.asHex; 37 | } 38 | 39 | if (typeClass === "address") { 40 | return inputObj.value.asAddress; 41 | } 42 | 43 | if (typeClass === "struct") { 44 | const data = inputObj.value; 45 | const arrayOfObjects = data.map(({ name, value }: any) => ({ 46 | [name]: getDecodedValue(value), 47 | })); 48 | const mergedObject = arrayOfObjects.reduce( 49 | (acc: any, curr: any) => Object.assign(acc, curr), 50 | {} 51 | ); 52 | return mergedObject; 53 | } 54 | 55 | if (typeClass === "array") { 56 | const array = inputObj.value; 57 | const strArray = array.map(getDecodedValue); 58 | return strArray; 59 | } 60 | 61 | return `${typeClass} is currently not supported`; 62 | }; 63 | 64 | export default getDecodedValue; 65 | -------------------------------------------------------------------------------- /ui/src/utils/getWeb3.ts: -------------------------------------------------------------------------------- 1 | import Web3 from "web3"; 2 | 3 | const getWeb3 = async (port: any) => { 4 | 5 | const provider = new Web3.providers.WebsocketProvider( 6 | `ws://127.0.0.1:${port}`, 7 | { 8 | headers: { 9 | Origin: "some_meaningful_name" 10 | } 11 | } 12 | ); 13 | const web3 = await new Web3(provider); 14 | return web3; 15 | } 16 | 17 | export default getWeb3; 18 | -------------------------------------------------------------------------------- /ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | --------------------------------------------------------------------------------