Wallet Decrypt Redesign (#677)
* Reorganize files to better match other components. * Initial UI for wallet buttons. * Fix leftover rebase conflict. * Wallet selection, styling, mobile handling. * Initial work on animations. * Adjusted animations. * Adjust wallet unlock forms to be more uniform. Fix view address saying 'unlock' * Adjust tooltips. * Fix embedded decrypt components. * Cover whole sign msg form with decrypt. * Give deploy contract a better unlock treatment like sign msg. * Reset decrypt component on hide / show * Unused var * Fix tooltip hover. * Fix hover lift. * Make spacing better on mobile. * Back button mobile handling. * Redesign mobile button icons. Prevent clicking through when clicking on icons. * TSCheck fixes. * Attempt to unlock MetaMask onClick, and provide existing flow with notification when unlock fails. * Get rid of outline. * Remove decrypt min height. Make view only textarea. * Add change wallet buttons to deploy contract and sign msg. * Standardize
This commit is contained in:
parent
4fdc821695
commit
371e6e327c
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="180px" height="246px" viewBox="0 0 180 246" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 48.1 (47250) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>digital-bitbox</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="digital-bitbox">
|
||||
<polygon id="Path-3" fill="#000000" points="90 0 126 17 126 107 180 132 180 206 90 246 0 206 0 132 54 107 54 17"></polygon>
|
||||
<polygon id="Path-4" fill="#FFFFFF" points="170 136 89.7558594 171.179688 10 136 25 130 90 158 155 130"></polygon>
|
||||
<polygon id="Path-5" fill="#FFFFFF" points="97 170 97 236 170 202"></polygon>
|
||||
<polygon id="Path-5" fill="#FFFFFF" transform="translate(46.500000, 203.000000) scale(-1, 1) translate(-46.500000, -203.000000) " points="10 170 10 236 83 202"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="155px" height="155px" viewBox="0 0 155 155" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 48.1 (47250) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>ledger</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ledger">
|
||||
<image opacity="0.139605978" x="0" y="0" width="154" height="155" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJoAAACbCAYAAACao4KyAAAABGdBTUEAA1teXP8meAAAB+FJREFUeAHtnM9y00YcgHdXSqBMO/VACldz64EZzJ/CDBecIeVaeALCExSeIPAEkCcgPEHTc2EwFw4tUGXaA7f6XALjzrQ0xZZUrYiMldhBiqzJrvfzRZG0u/r9vt83K3ltR4oaX81mq/H5wkKrzCX8wbteEDwLyvQp0vbrVrvp+36zSFsX2/y9uRl0u0Gvrtz9aQysi3hYibbw5i7HUdT0fK+933HD+LNO0ndxv/0n9Ts87y8rqVYmnXf9+NETx8XRE1dTDOEg7EiluiLsP92KROdV0OlW5bNv0fRs1TixsCwieUMp+XHWUl7VmOh/wASGE4WaXz6SxNL65tsgkW6197a3vt9Zr7RoqWDHF26JWHyvhGoIdcBUuHztBNKJRM0/aHy1cK91fGm19+fm/bLCldKkdXHpVnKxP/QtSKlEMl5OEdA117XXDmgXyiRfaEbTz2CHPO9BMoO1mcHK4J3NttuTzL3T565899ebN9eLzG6fnNFOnV9qH57zfx3et2eTHVntg4B2Ip3dWpc+PqNPGGdP0Vpn28vznnrCbXICPQ6L1I25I0+0K3vhmCia7qjm5h/s1ZlzENAE0me3xJW9ZBsrmr5dIhkSlSbg+fdaE26ju0RLV9Cl+KH0RejgPIHsNqqXwHbC2CVa+u6SpYudnNgvSEDL9uWxY7smqpxoem2Ed5cFidJsIgHt0M7ntaFo6XQXCT4LnIiPE6UIJM9ro7fQoWiN5GOl9B5bajQaQ2A8Ae2Sdio7m4qWmpd8dpkdZAuBqRBInMpmtVQ0/S0MZrOpoGWQEQLprHa0cU0f+nDrTL7qM3KePyEwNQKx9FK3lF43y32fbGqXYCAICKHfgerbp0q/GQsRCNRI4ItjjbbSX7+u8RoMDQHhSf+y0t/xhwUE6iQQx3FL8UlAnYgZWxOQyW9Khgu2IIFAXQT0Mgei1UWXcXMEEC2Hg526CCBaXWQZN0cA0XI42KmLAKLVRZZxcwQQLYeDnboIIFpdZBk3RwDRcjjYqYsAotVFlnFzBBAth4OdugggWl1kGTdHANFyONipiwCi1UWWcXMEfP3/SnNHDnhHShkccAhcvgYC/saLx1P/x8Q1xMmQlhPg1ml5AW0JH9FsqZTlcSKa5QW0JXxEs6VSlseJaJYX0JbwEc2WSlkeJ6JZXkBbwkc0WypleZyIZnkBbQkf0WyplOVxIprlBbQlfESzpVKWx4lolhfQlvARzZZKWR4nolleQFvCRzRbKmV5nIhmeQFtCR/RbKmU5XEimuUFtCV8RLOlUpbH6bcuLN0xKofBoBu87KwZFRPBVCbgK6lWKo8yxQFC6XWS4damOCRDGUCAW6cBRXAhBERzocoG5IhoBhTBhRAQzYUqG5AjohlQBBdCQDQXqmxAjohmQBFcCAHRXKiyATkimgFFcCEERHOhygbkiGgGFMGFEBDNhSobkCOiGVAEF0JANBeqbECOiGZAEVwIAdFcqLIBOSKaAUVwIQREc6HKBuSIaAYUwYUQEM2FKhuQI6IZUAQXQkA0F6psQI6IZkARXAgB0VyosgE5IpoBRXAhBERzocoG5IhoBhTBhRAQzYUqG5AjohlQBBdCQDQXqmxAjohmQBFcCAHRXKiyATkimgFFcCEERHOhygbkiGgGFMGFEPz3YbRoUqJ++G+vjni23g/WfN/v1DE2Y0IAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAjUSkGcvXo1rHL/00OEg7Gy8eDz1X2a1LizdUVKtlA6oxg5RHN0Nfn50Z9qXOH3uyhPP99rTHrfKePyuswo9+hYmgGiFUdGwCgFEq0KPvoUJIFphVDSsQgDRqtCjb2ECiFYYFQ2rEEC0KvToW5gAohVGRcMqBBCtCj36FiaAaIVR0bAKAUSrQo++hQkgWmFUNKxCANGq0KNvYQKIVhgVDasQUFEU1fLPiasERd/ZIhD1w66KoziYrbTIxjQCsRRdJaVENNMqM2PxSE8+VSIabMxYXqRjGIEwHASq97a3blhchDNjBH570VlX3W7Qi8IBss1YcU1JJ3Prw/JGFP1oSmDEMVsEwjh6qDNKRQtedtZY5pitApuQjV7W0LfNoWhpUFKsmhAcMcwSgfBuls3wkwH9+0JtYHaCLQSqENAu6TtlNsZQNH0glOHt7ARbCFQhMFDy5mj/nGj6fpq9SxhtxN8QKEMgCqP7vz9/1BntkxNNn+htvr0Z8bHUKCP+LkFAu9Pb3Bw+m2Vdd4mm19VE/59ENj5szyCxLUZAO7PV719PHdrRZZdo+nwQPAtE/90isu2gxe5EAqkriTOvgk53XKOxoumGyDYOF8fGEcgkS50Z1yA5NlE03V533OoPzvDMNoEeh0X6TPZ68+RekmlMe4qmG+ipsPf69aJ+J6H3eUEgI6CdCH756cy4Z7KsTbb9pGi6oR4oeP7o9vswWmRRN0Pn7lbPYtoF7URRCn7Rhrrd9trIydbZ9rIQ3oqa85r6OC83CKSPUGF/dXTFv2jmpUTLBt2+0Nqp80ttX8obQsTXlFKN7Dzb2SHwYeVBrg/i+OHORdgyWe5LtOwC2xfuJPs3W61LLXHoSFtE8nQcRU0ZiyYzXkbKjq1+LNLf75dKdYWKN8R/7zqfesgvmtn/iX/FXd1m5AIAAAAASUVORK5CYII="></image>
|
||||
<path d="M37,0 L37,37 L6.07153217e-16,37 L6.07153217e-16,21.9078947 C-0.100260417,17.3640351 2.48307292,12.5767544 7.75,7.54605263 C13.0169271,2.51535088 17.9335938,0 22.5,0 L37,0 Z" id="Path" fill="#000000"></path>
|
||||
<path d="M155,1.42108547e-14 L155,96 L59.0072885,96 L59,27 C59.2044271,21.3216146 61.7555339,15.4020182 66.6533203,9.24121094 C71.5511068,3.08040365 78,4.73695157e-15 86,1.42108547e-14 L155,1.42108547e-14 Z" id="Path" fill="#000000" transform="translate(107.000000, 48.000000) scale(-1, 1) translate(-107.000000, -48.000000) "></path>
|
||||
<path d="M37.0028093,118 L37.0028093,155 L0.00280933482,155 L0.00280933482,139.907895 C-0.0974510818,135.364035 2.48588225,130.576754 7.75280933,125.546053 C13.0197364,120.515351 17.9364031,118 22.5028093,118 L37.0028093,118 Z" id="Path" fill="#000000" transform="translate(18.501405, 136.500000) scale(1, -1) translate(-18.501405, -136.500000) "></path>
|
||||
<path d="M155.002809,118 L155.002809,155 L118.002809,155 L118.002809,139.907895 C117.902549,135.364035 120.485882,130.576754 125.752809,125.546053 C131.019736,120.515351 135.936403,118 140.502809,118 L155.002809,118 Z" id="Path" fill="#000000" transform="translate(136.501405, 136.500000) scale(-1, -1) translate(-136.501405, -136.500000) "></path>
|
||||
<polygon id="Path-2" fill="#000000" points="0 59 37 59 37 96 0 96"></polygon>
|
||||
<polygon id="Path-2" fill="#000000" points="59 118 96 118 96 155 59 155"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="317px" height="331px" viewBox="0 0 317 331" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 48.1 (47250) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>metamask</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="metamask" fill-rule="nonzero">
|
||||
<g id="Shape">
|
||||
<polygon stroke="#BBBBBB" fill="#BBBBBB" points="300 229 280.763485 294 243 283.678788"></polygon>
|
||||
<polygon stroke="#BBBBBB" fill="#BBBBBB" points="243 284 279.423237 233.834294 300 229"></polygon>
|
||||
<path d="M272,179.716489 L300,229.151839 L279.643454,234 L272,179.716489 Z M272,179.716489 L290.016713,167 L300,229.151839 L272,179.716489 Z" fill="#DDDDDD"></path>
|
||||
<path d="M249,142.560976 L301,121 L298.415663,132.810976 L249,142.560976 Z M296.771084,147 L249,142.560976 L298.415663,132.810976 L296.771084,147 Z" stroke="#000000" fill="#000000"></path>
|
||||
<path d="M296.851563,146.862549 L290.689098,167 L249,142.498282 L296.851563,146.862549 Z M306.893674,125.979381 L298,132.776632 L300.620458,121 L306.893674,125.979381 Z M296,147.147766 L297.667564,133 L304.734859,138.848797 L296,147.147766 Z" stroke="#000000" fill="#000000"></path>
|
||||
<path d="M290.501771,167 L296.750885,146.521729 L303,151.670968 L290.501771,167 Z M290.992432,167.10791 L235.792725,148.983398 L248.977783,141.554199 L290.992432,167.10791 Z" stroke="#000000" fill="#000000"></path>
|
||||
<polygon stroke="#000000" fill="#000000" points="261.963379 80.3129883 249 142.452436 236 149"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="301 121.351733 248.367188 143.222168 261.624512 80.5117188"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="262 81.2691652 317 75 300.998047 121.375"></polygon>
|
||||
<polygon fill="#DDDDDD" points="290.681641 166.88501 271.895501 180 235.297607 148.680664"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="313.882812 31.1132812 317 75.1660156 261.748047 81.559082"></polygon>
|
||||
<polygon stroke="#BBBBBB" fill="#BBBBBB" points="314 31 204.526123 111.583008 203 56.7398213"></polygon>
|
||||
<polygon fill="#DDDDDD" points="122 50 203.574427 56.4313725 205.114014 110.804199"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="236.105263 149 205 109.87239 262 81"></polygon>
|
||||
<polygon stroke="#BBBBBB" fill="#BBBBBB" points="235.673406 149 272.702148 180.192871 220.705078 185.546875"></polygon>
|
||||
<polygon stroke="#BBBBBB" fill="#BBBBBB" points="220.5 186.560059 205 110 236 148.993711"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="261.821661 81.9235353 205 111 314 31"></polygon>
|
||||
<polygon fill="#C0AD9E" points="122.280899 283.05679 148 310 113 278"></polygon>
|
||||
<polygon stroke="#999999" fill="#999999" points="243 284 255.077922 237.475513 279.552002 234.016846"></polygon>
|
||||
<polygon fill="#E2761B" points="18 153 63 106 23.8038869 147.391597"></polygon>
|
||||
<path d="M279.638916,234.052734 L254.892334,237.791992 L272.25025,180.452211 L279.638916,234.052734 Z M204.874875,110.555789 L161.302302,109.130947 L122,50 L204.874875,110.555789 Z" fill="#DDDDDD"></path>
|
||||
<polygon stroke="#AAAAAA" fill="#AAAAAA" points="272.860352 178.466309 255.035889 238.403076 253.430664 209.201538"></polygon>
|
||||
<polygon stroke="#999999" fill="#999999" points="221 185.534946 272 180 254.07465 209"></polygon>
|
||||
<polygon fill="#DDDDDD" points="161 109 205.040527 109.762451 221 186"></polygon>
|
||||
<path d="M162.666504,110.812012 L43.8779297,0 L122.686523,49.7369804 L162.666504,110.812012 Z M122.605469,298.883789 L20.4082031,331 L0,252.227539 L122.605469,298.883789 Z" stroke="#BBBBBB" fill="#BBBBBB"></path>
|
||||
<polygon stroke="#000000" fill="#000000" points="33 172 71.6265329 142 104 149.441253"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="104 150 72 142.487487 89.1344743 71"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="24 147.169713 72 142 33.4102142 172"></polygon>
|
||||
<polygon stroke="#999999" fill="#999999" points="254 209 234.057554 198.873754 221 185"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="24.0253906 147.559082 19.7363281 127.630127 72.6230469 142.035156"></polygon>
|
||||
<polygon fill="#000000" points="229.504639 222.02832 233.890869 198.618896 254.018799 208.942871"></polygon>
|
||||
<polygon fill="#DDDDDD" points="255 237 230 221.540845 253.676012 209"></polygon>
|
||||
<path d="M72.0783081,142.372253 L20.1834513,129.755756 L16,114.651652 L72.0783081,142.372253 Z M89.4462891,70.630127 L72.0721436,142.393555 L16,114.651652 L89.4462891,70.630127 Z M89,71 L161,109.037037 L103.773544,150 L89,71 Z" stroke="#000000" fill="#000000"></path>
|
||||
<path d="M102.939453,149.790527 L161.446777,108.118652 L187,187 L102.939453,149.790527 Z M187,187 L107.214355,184.98877 L103.306152,149.833008 L187,187 Z" stroke="#BBBBBB" fill="#BBBBBB"></path>
|
||||
<path d="M32.0712891,171.77832 L103.916504,149.303223 L107.426532,185.340426 L32.0712891,171.77832 Z M221,185.81459 L186.509656,187 L161.016793,109 L221,185.81459 Z" fill="#DDDDDD"></path>
|
||||
<polygon stroke="#999999" fill="#999999" points="234 198.617391 229.90303 221 221 185"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="44 0 161 109 88.697998 71.2009277"></polygon>
|
||||
<polygon stroke="#BBBBBB" fill="#BBBBBB" points="0 252.468262 98.902832 247.6875 122.921875 299.431641"></polygon>
|
||||
<polygon stroke="#999999" fill="#999999" points="122.545455 299 99 248.383808 148 246"></polygon>
|
||||
<path d="M230.672711,221.514124 L256.022229,237.016949 L265.330322,267.536621 L230.672711,221.514124 Z M108.110559,184.655367 L0,252.59887 L33.6414156,172 L108.110559,184.655367 Z M99.0289558,248.485876 L0,252.59887 L108.110559,184.655367 L99.0289558,248.485876 Z M221.749049,185.129944 L228.329102,209.351562 L196.20166,211.189697 L221.749049,185.129944 Z M196.142822,211.310303 L187.238959,186.316384 L221.749049,185.129944 L196.142822,211.310303 Z" stroke="#BBBBBB" fill="#BBBBBB"></path>
|
||||
<polygon fill="#FBFBFB" points="148.453925 309.720812 122 299 214 315"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="33.5405273 171.776367 18 152.599369 24.121582 146.518799"></polygon>
|
||||
<polygon fill="#FFFFFF" points="225.334473 302.741699 214.44873 315.716797 122 299"></polygon>
|
||||
<polygon stroke="#BBBBBB" fill="#BBBBBB" points="230.497559 275.182129 122 299 147.263158 246"></polygon>
|
||||
<polygon fill="#FFFFFF" points="122 299.011173 224.425587 276.239335 230 275 225.026316 303"></polygon>
|
||||
<path d="M16.5367115,114.898062 L13.1118164,53.6879883 L89.7861328,70.8154297 L16.5367115,114.898062 Z M24.1728516,147.156738 L13.6287487,137.309183 L20.7021717,130.023589 L24.1728516,147.156738 Z" stroke="#000000" fill="#000000"></path>
|
||||
<polygon stroke="#999999" fill="#999999" points="169 202.545455 186.879395 185.943848 184.428571 225"></polygon>
|
||||
<polygon stroke="#999999" fill="#999999" points="186 187 169.392822 203.094971 143 216"></polygon>
|
||||
<path d="M264.222892,266.476346 L230,222 L264.222892,266.476346 Z" stroke="#BBBBBB" fill="#BBBBBB"></path>
|
||||
<polygon stroke="#999999" fill="#999999" points="143.636727 216 108 185 187 186.677835"></polygon>
|
||||
<polygon stroke="#AAAAAA" fill="#AAAAAA" points="184 225 186.960205 185.625732 196.302979 211.109863"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="10 119.968586 16.6492537 114 21 129"></polygon>
|
||||
<polygon fill="#000000" points="185.06543 225.883789 142.477783 216.035645 168.803089 202"></polygon>
|
||||
<polygon stroke="#000000" fill="#000000" points="89 71 13 53.7854749 44.0444674 0"></polygon>
|
||||
<polygon fill="#FBFBFB" points="214.661621 314.608398 219.323242 326.847656 148.149902 309.338379"></polygon>
|
||||
<polygon fill="#DDDDDD" points="146.878378 247 143 216 184 225.323907"></polygon>
|
||||
<polygon stroke="#AAAAAA" fill="#AAAAAA" points="108 185 144.087824 215.460746 147.286621 246.429199"></polygon>
|
||||
<path d="M196.127808,211.066406 L228.076046,209.108317 L265,267 L196.127808,211.066406 Z M108.073194,185 L147.60076,246.618956 L98.7451172,248.597656 L108.073194,185 Z" fill="#DDDDDD"></path>
|
||||
<polygon stroke="#AAAAAA" fill="#AAAAAA" points="196.217929 211 235 270 183.407227 225.09375"></polygon>
|
||||
<polygon stroke="#BBBBBB" fill="#BBBBBB" points="183.709229 224.863281 235.486816 270.005859 228.958496 275.549316"></polygon>
|
||||
<path d="M229.403226,275 L147,246.555556 L183.877016,225.064198 L229.403226,275 Z M265.065247,267.038452 L235.010742,270.378784 L195.155273,209.339355 L265.065247,267.038452 Z" fill="#DDDDDD"></path>
|
||||
<path d="M272.00824,294.410675 L259.356948,320.362963 L218.346049,327 L272.00824,294.410675 Z M219.55719,327.282715 L214,315.148148 L225.11438,302.943848 L219.55719,327.282715 Z" fill="#FBFBFB"></path>
|
||||
<path d="M225.051514,302.968872 L232.809204,299.898437 L219,327 L225.051514,302.968872 Z M219,327 L232.710693,299.850464 L272.031677,294.415588 L219,327 Z" fill="#FBFBFB"></path>
|
||||
<polygon fill="#000000" points="265.13369 267 274.98291 272.750488 245 276"></polygon>
|
||||
<path d="M244.534709,276.545455 L235,270.340909 L265.137085,267.049438 L244.534709,276.545455 Z M241.146341,281.238636 L277,276.863636 L272.036133,294.474121 L241.146341,281.238636 Z" fill="#000000"></path>
|
||||
<path d="M272.066265,294.415274 L232.674699,299.928401 L241.36747,280.789976 L272.066265,294.415274 Z M232.858643,299.856323 L225,303 L229.64389,274.996735 L232.858643,299.856323 Z M229.646622,274.991623 L235.259036,270 L244.73494,276.143198 L229.646622,274.991623 Z M274.82019,272.612183 L277.009399,276.895203 L240.491821,281.35498 L274.82019,272.612183 Z" fill="#000000"></path>
|
||||
<path d="M241.280029,281.16687 L244.26709,275.812866 L274.876221,272.649902 L241.280029,281.16687 Z M229.641754,274.986938 L241.410302,281.092219 L232.735346,300 L229.641754,274.986938 Z" fill="#000000"></path>
|
||||
<polygon fill="#000000" points="244.553223 276.001831 241.346558 281.346558 229.65329 274.99649"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="260px" height="260px" viewBox="0 0 260 260" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 48.1 (47250) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>mist</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="mist">
|
||||
<circle id="Oval-3" fill="#000000" cx="130" cy="130" r="130"></circle>
|
||||
<g id="ether" transform="translate(66.000000, 26.000000)">
|
||||
<polygon id="Path-4" fill="#DDDDDD" points="0 106 63.9893369 0 64 77.1016184"></polygon>
|
||||
<polygon id="Path-5" fill="#AAAAAA" points="128 106 64.0106631 0 64 77.1016184"></polygon>
|
||||
<polygon id="Path-6" fill="#AAAAAA" points="64 77 0 105.714286 64 144"></polygon>
|
||||
<polygon id="Path-6" fill="#999999" points="64 77 128 105.714286 64 144"></polygon>
|
||||
<polygon id="Path-7" fill="#888888" points="128 117 64.0106631 208 64 155.541176"></polygon>
|
||||
<polygon id="Path-7" fill="#DDDDDD" points="0 117 63.9893369 208 64 155.541176"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="156px" height="258px" viewBox="0 0 156 258" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 48.1 (47250) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>trezor</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="trezor" fill="#000000" fill-rule="nonzero">
|
||||
<g id="path7">
|
||||
<path d="M78.1255028,0 C47.0321802,0 21.8688656,28.6428571 21.8688656,64.0357143 L21.8688656,88.0357143 C10.9501207,90.2857143 0,93.2857143 0,97.1785714 L0,222.428571 C0,222.428571 0,225.892857 3.41995173,227.535714 C15.8133548,233.25 64.5711987,252.892857 75.772325,257.392857 C77.2156074,258 77.6234916,258 78,258 C78.533387,258 78.7843926,258 80.227675,257.392857 C91.4288013,252.892857 140.312148,233.25 152.705551,227.535714 C155.874497,226.035714 156,222.571429 156,222.571429 L156,97.1785714 C156,93.2857143 145.206758,90.1428571 134.256637,88.0357143 L134.256637,64.0357143 C134.413516,28.6428571 109.093323,0 78.1255028,0 Z M78.1255028,30.6071429 C96.4489139,30.6071429 107.524537,43.2142857 107.524537,64.0714286 L107.524537,84.9285714 C86.9734513,83.2857143 69.4344328,83.2857143 48.7578439,84.9285714 L48.7578439,64.0714286 C48.7578439,43.1785714 59.8334674,30.6071429 78.1255028,30.6071429 Z M78,115.642857 C103.571199,115.642857 125.03218,117.892857 125.03218,121.928571 L125.03218,200.071429 C125.03218,201.285714 124.906677,201.428571 123.965406,201.857143 C123.055511,202.321429 80.3531778,219.857143 80.3531778,219.857143 C80.3531778,219.857143 78.6275141,220.464286 78.1255028,220.464286 C77.5921158,220.464286 75.8978278,219.714286 75.8978278,219.714286 C75.8978278,219.714286 33.1954948,202.178571 32.2855994,201.714286 C31.3757039,201.25 31.2188254,201.107143 31.2188254,199.928571 L31.2188254,121.785714 C30.9678198,117.75 52.4288013,115.642857 78,115.642857 Z"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -6,10 +6,10 @@ import { connect } from 'react-redux';
|
|||
import { AppState } from 'reducers';
|
||||
|
||||
interface Props {
|
||||
allowReadOnly: boolean;
|
||||
disabledWallets?: string[];
|
||||
}
|
||||
export const OfflineAwareUnlockHeader: React.SFC<Props> = ({ allowReadOnly }) => (
|
||||
<UnlockHeader title={<Title />} allowReadOnly={allowReadOnly} />
|
||||
export const OfflineAwareUnlockHeader: React.SFC<Props> = ({ disabledWallets }) => (
|
||||
<UnlockHeader title={<Title />} disabledWallets={disabledWallets} />
|
||||
);
|
||||
|
||||
interface StateProps {
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
import { isKeystorePassRequired } from 'libs/wallet';
|
||||
import React, { Component } from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { TShowNotification } from 'actions/notifications';
|
||||
|
||||
export interface KeystoreValue {
|
||||
file: string;
|
||||
password: string;
|
||||
valid: boolean;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
value: KeystoreValue;
|
||||
onChange(value: KeystoreValue): void;
|
||||
onUnlock(): void;
|
||||
showNotification(level: string, message: string): TShowNotification;
|
||||
}
|
||||
|
||||
function isPassRequired(file: string): boolean {
|
||||
let passReq = false;
|
||||
try {
|
||||
passReq = isKeystorePassRequired(file);
|
||||
} catch (e) {
|
||||
// TODO: communicate invalid file to user
|
||||
}
|
||||
return passReq;
|
||||
}
|
||||
|
||||
function isValidFile(rawFile: File): boolean {
|
||||
const fileType = rawFile.type;
|
||||
return fileType === '' || fileType === 'application/json';
|
||||
}
|
||||
|
||||
export default class KeystoreDecrypt extends Component<Props> {
|
||||
public render() {
|
||||
const { file, password } = this.props.value;
|
||||
const passReq = isPassRequired(file);
|
||||
|
||||
return (
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<div id="selectedUploadKey">
|
||||
<h4>{translate('ADD_Radio_2_alt')}</h4>
|
||||
|
||||
<div className="form-group">
|
||||
<input
|
||||
className={'hidden'}
|
||||
type="file"
|
||||
id="fselector"
|
||||
onChange={this.handleFileSelection}
|
||||
/>
|
||||
<label htmlFor="fselector" style={{ width: '100%' }}>
|
||||
<a className="btn btn-default btn-block" id="aria1" tabIndex={0} role="button">
|
||||
{translate('ADD_Radio_2_short')}
|
||||
</a>
|
||||
</label>
|
||||
<div className={file.length && passReq ? '' : 'hidden'}>
|
||||
<p>{translate('ADD_Label_3')}</p>
|
||||
<input
|
||||
className={`form-control ${password.length > 0 ? 'is-valid' : 'is-invalid'}`}
|
||||
value={password}
|
||||
onChange={this.onPasswordChange}
|
||||
onKeyDown={this.onKeyDown}
|
||||
placeholder={translateRaw('x_Password')}
|
||||
type="password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
public onKeyDown = (e: any) => {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.onUnlock();
|
||||
}
|
||||
};
|
||||
|
||||
public onPasswordChange = (e: any) => {
|
||||
const valid = this.props.value.file.length && e.target.value.length;
|
||||
this.props.onChange({
|
||||
...this.props.value,
|
||||
password: e.target.value,
|
||||
valid
|
||||
});
|
||||
};
|
||||
|
||||
public handleFileSelection = (e: any) => {
|
||||
const fileReader = new FileReader();
|
||||
const target = e.target;
|
||||
const inputFile = target.files[0];
|
||||
|
||||
fileReader.onload = () => {
|
||||
const keystore = fileReader.result;
|
||||
const passReq = isPassRequired(keystore);
|
||||
|
||||
this.props.onChange({
|
||||
...this.props.value,
|
||||
file: keystore,
|
||||
valid: keystore.length && !passReq
|
||||
});
|
||||
};
|
||||
|
||||
if (isValidFile(inputFile)) {
|
||||
fileReader.readAsText(inputFile, 'utf-8');
|
||||
} else {
|
||||
this.props.showNotification('danger', translateRaw('ERROR_3'));
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import translate from 'translations';
|
||||
import { donationAddressMap } from 'config/data';
|
||||
import { isValidETHAddress } from 'libs/validators';
|
||||
import { AddressOnlyWallet } from 'libs/wallet';
|
||||
|
||||
interface Props {
|
||||
onUnlock(param: any): void;
|
||||
}
|
||||
|
||||
interface State {
|
||||
address: string;
|
||||
}
|
||||
|
||||
export default class ViewOnlyDecrypt extends Component<Props, State> {
|
||||
public state = {
|
||||
address: ''
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { address } = this.state;
|
||||
const isValid = isValidETHAddress(address);
|
||||
|
||||
return (
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<div id="selectedUploadKey">
|
||||
<h4>{translate('MYWAL_Address')}</h4>
|
||||
|
||||
<form className="form-group" onSubmit={this.openWallet}>
|
||||
<input
|
||||
className={`form-control
|
||||
${isValid ? 'is-valid' : 'is-invalid'}
|
||||
`}
|
||||
onChange={this.changeAddress}
|
||||
value={address}
|
||||
placeholder={donationAddressMap.ETH}
|
||||
/>
|
||||
|
||||
<button className="btn btn-primary btn-block" disabled={!isValid}>
|
||||
{translate('NAV_ViewWallet')}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
private changeAddress = (ev: React.FormEvent<HTMLInputElement>) => {
|
||||
this.setState({ address: ev.currentTarget.value });
|
||||
};
|
||||
|
||||
private openWallet = (ev: React.FormEvent<HTMLFormElement>) => {
|
||||
const { address } = this.state;
|
||||
ev.preventDefault();
|
||||
if (isValidETHAddress(address)) {
|
||||
const wallet = new AddressOnlyWallet(address);
|
||||
this.props.onUnlock(wallet);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
@import 'common/sass/variables';
|
||||
@import 'common/sass/mixins';
|
||||
|
||||
$speed: 500ms;
|
||||
|
||||
@keyframes decrypt-enter {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(8px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin decrypt-title {
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
margin: 0 0 30px;
|
||||
font-weight: normal;
|
||||
animation: decrypt-enter $speed ease 1;
|
||||
}
|
||||
|
||||
.WalletDecrypt {
|
||||
position: relative;
|
||||
|
||||
&-wallets {
|
||||
&-title {
|
||||
@include decrypt-title;
|
||||
}
|
||||
|
||||
&-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 10px;
|
||||
|
||||
@media screen and (max-width: $screen-xs) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
&:last-child {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-decrypt {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding-bottom: $space;
|
||||
|
||||
&-back {
|
||||
@include reset-button;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
line-height: $font-size-large;
|
||||
opacity: 0.4;
|
||||
transition: opacity 120ms ease, transform 120ms ease;
|
||||
|
||||
@media (max-width: $screen-md) {
|
||||
top: auto;
|
||||
bottom: -10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&:active {
|
||||
outline: none;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fa {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
@include decrypt-title;
|
||||
}
|
||||
|
||||
&-form {
|
||||
max-width: 360px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Animation between two slides
|
||||
.DecryptContent {
|
||||
&-enter {
|
||||
opacity: 0;
|
||||
transition: opacity $speed * .25 ease $speed * .125;
|
||||
|
||||
&-active {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&-exit {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
opacity: 1;
|
||||
transition: opacity $speed * .25 ease;
|
||||
pointer-events: none;
|
||||
|
||||
&-active {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,393 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { TransitionGroup, CSSTransition } from 'react-transition-group';
|
||||
import {
|
||||
setWallet,
|
||||
TSetWallet,
|
||||
unlockKeystore,
|
||||
TUnlockKeystore,
|
||||
unlockMnemonic,
|
||||
TUnlockMnemonic,
|
||||
unlockPrivateKey,
|
||||
TUnlockPrivateKey,
|
||||
unlockWeb3,
|
||||
TUnlockWeb3,
|
||||
resetWallet,
|
||||
TResetWallet
|
||||
} from 'actions/wallet';
|
||||
import { reset, TReset } from 'actions/transaction';
|
||||
import translate from 'translations';
|
||||
import {
|
||||
DigitalBitboxDecrypt,
|
||||
KeystoreDecrypt,
|
||||
LedgerNanoSDecrypt,
|
||||
MnemonicDecrypt,
|
||||
PrivateKeyDecrypt,
|
||||
PrivateKeyValue,
|
||||
TrezorDecrypt,
|
||||
ViewOnlyDecrypt,
|
||||
Web3Decrypt,
|
||||
NavigationPrompt,
|
||||
WalletButton
|
||||
} from './components';
|
||||
import { AppState } from 'reducers';
|
||||
import { knowledgeBaseURL } from 'config/data';
|
||||
import { IWallet } from 'libs/wallet';
|
||||
import DigitalBitboxIcon from 'assets/images/wallets/digital-bitbox.svg';
|
||||
import LedgerIcon from 'assets/images/wallets/ledger.svg';
|
||||
import MetamaskIcon from 'assets/images/wallets/metamask.svg';
|
||||
import MistIcon from 'assets/images/wallets/mist.svg';
|
||||
import TrezorIcon from 'assets/images/wallets/trezor.svg';
|
||||
import './WalletDecrypt.scss';
|
||||
|
||||
type UnlockParams = {} | PrivateKeyValue;
|
||||
|
||||
interface Props {
|
||||
resetTransactionState: TReset;
|
||||
unlockKeystore: TUnlockKeystore;
|
||||
unlockMnemonic: TUnlockMnemonic;
|
||||
unlockPrivateKey: TUnlockPrivateKey;
|
||||
setWallet: TSetWallet;
|
||||
unlockWeb3: TUnlockWeb3;
|
||||
resetWallet: TResetWallet;
|
||||
wallet: IWallet;
|
||||
hidden?: boolean;
|
||||
offline: boolean;
|
||||
disabledWallets?: string[];
|
||||
}
|
||||
|
||||
interface State {
|
||||
selectedWalletKey: string | null;
|
||||
value: UnlockParams | null;
|
||||
}
|
||||
|
||||
interface BaseWalletInfo {
|
||||
lid: string;
|
||||
component: any;
|
||||
initialParams: object;
|
||||
unlock: any;
|
||||
helpLink?: string;
|
||||
isReadOnly?: boolean;
|
||||
attemptUnlock?: boolean;
|
||||
}
|
||||
|
||||
export interface SecureWalletInfo extends BaseWalletInfo {
|
||||
icon?: string | null;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface InsecureWalletInfo extends BaseWalletInfo {
|
||||
example: string;
|
||||
}
|
||||
|
||||
const WEB3_TYPES = {
|
||||
MetamaskInpageProvider: {
|
||||
lid: 'x_MetaMask',
|
||||
icon: MetamaskIcon
|
||||
},
|
||||
EthereumProvider: {
|
||||
lid: 'x_Mist',
|
||||
icon: MistIcon
|
||||
}
|
||||
};
|
||||
const WEB3_TYPE: string | false =
|
||||
(window as any).web3 && (window as any).web3.currentProvider.constructor.name;
|
||||
|
||||
const SECURE_WALLETS = ['web3', 'ledger-nano-s', 'trezor', 'digital-bitbox'];
|
||||
const INSECURE_WALLETS = ['private-key', 'keystore-file', 'mnemonic-phrase'];
|
||||
|
||||
export class WalletDecrypt extends Component<Props, State> {
|
||||
public WALLETS: { [key: string]: SecureWalletInfo | InsecureWalletInfo } = {
|
||||
web3: {
|
||||
lid: WEB3_TYPE ? WEB3_TYPES[WEB3_TYPE].lid : 'x_Web3',
|
||||
icon: WEB3_TYPE && WEB3_TYPES[WEB3_TYPE].icon,
|
||||
description: 'ADD_Web3Desc',
|
||||
component: Web3Decrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.unlockWeb3,
|
||||
attemptUnlock: true,
|
||||
helpLink: `${knowledgeBaseURL}/migration/moving-from-private-key-to-metamask`
|
||||
},
|
||||
'ledger-nano-s': {
|
||||
lid: 'x_Ledger',
|
||||
icon: LedgerIcon,
|
||||
description: 'ADD_HardwareDesc',
|
||||
component: LedgerNanoSDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink:
|
||||
'https://ledger.zendesk.com/hc/en-us/articles/115005200009-How-to-use-MyEtherWallet-with-Ledger'
|
||||
},
|
||||
trezor: {
|
||||
lid: 'x_Trezor',
|
||||
icon: TrezorIcon,
|
||||
description: 'ADD_HardwareDesc',
|
||||
component: TrezorDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: 'https://doc.satoshilabs.com/trezor-apps/mew.html'
|
||||
},
|
||||
'digital-bitbox': {
|
||||
lid: 'x_DigitalBitbox',
|
||||
icon: DigitalBitboxIcon,
|
||||
description: 'ADD_HardwareDesc',
|
||||
component: DigitalBitboxDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: 'https://digitalbitbox.com/ethereum'
|
||||
},
|
||||
'keystore-file': {
|
||||
lid: 'x_Keystore2',
|
||||
example: 'UTC--2017-12-15T17-35-22.547Z--6be6e49e82425a5aa56396db03512f2cc10e95e8',
|
||||
component: KeystoreDecrypt,
|
||||
initialParams: {
|
||||
file: '',
|
||||
password: ''
|
||||
},
|
||||
unlock: this.props.unlockKeystore,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
'mnemonic-phrase': {
|
||||
lid: 'x_Mnemonic',
|
||||
example: 'brain surround have swap horror cheese file distinct',
|
||||
component: MnemonicDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.unlockMnemonic,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
'private-key': {
|
||||
lid: 'x_PrivKey2',
|
||||
example: 'f1d0e0789c6d40f399ca90cc674b7858de4c719e0d5752a60d5d2f6baa45d4c9',
|
||||
component: PrivateKeyDecrypt,
|
||||
initialParams: {
|
||||
key: '',
|
||||
password: ''
|
||||
},
|
||||
unlock: this.props.unlockPrivateKey,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
'view-only': {
|
||||
lid: 'View Address',
|
||||
example: '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8',
|
||||
component: ViewOnlyDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: '',
|
||||
isReadOnly: true
|
||||
}
|
||||
};
|
||||
public state: State = {
|
||||
selectedWalletKey: null,
|
||||
value: null
|
||||
};
|
||||
|
||||
public componentWillReceiveProps(nextProps) {
|
||||
// Reset state when unlock is hidden / revealed
|
||||
if (nextProps.hidden !== this.props.hidden) {
|
||||
this.setState({
|
||||
value: null,
|
||||
selectedWalletKey: null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public getSelectedWallet() {
|
||||
const { selectedWalletKey } = this.state;
|
||||
if (!selectedWalletKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.WALLETS[selectedWalletKey];
|
||||
}
|
||||
|
||||
public getDecryptionComponent() {
|
||||
const selectedWallet = this.getSelectedWallet();
|
||||
if (!selectedWallet) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<selectedWallet.component
|
||||
value={this.state.value}
|
||||
onChange={this.onChange}
|
||||
onUnlock={this.onUnlock}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public isOnlineRequiredWalletAndOffline(selectedWalletKey) {
|
||||
const onlineRequiredWallets = ['trezor', 'ledger-nano-s'];
|
||||
return this.props.offline && onlineRequiredWallets.includes(selectedWalletKey);
|
||||
}
|
||||
|
||||
public buildWalletOptions() {
|
||||
const viewOnly = this.WALLETS['view-only'] as InsecureWalletInfo;
|
||||
|
||||
return (
|
||||
<div className="WalletDecrypt-wallets">
|
||||
<h2 className="WalletDecrypt-wallets-title">{translate('decrypt_Access')}</h2>
|
||||
|
||||
<div className="WalletDecrypt-wallets-row">
|
||||
{SECURE_WALLETS.map(type => {
|
||||
const wallet = this.WALLETS[type] as SecureWalletInfo;
|
||||
return (
|
||||
<WalletButton
|
||||
key={type}
|
||||
name={translate(wallet.lid)}
|
||||
description={translate(wallet.description)}
|
||||
icon={wallet.icon}
|
||||
helpLink={wallet.helpLink}
|
||||
walletType={type}
|
||||
isSecure={true}
|
||||
isDisabled={this.isWalletDisabled(type)}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="WalletDecrypt-wallets-row">
|
||||
{INSECURE_WALLETS.map(type => {
|
||||
const wallet = this.WALLETS[type] as InsecureWalletInfo;
|
||||
return (
|
||||
<WalletButton
|
||||
key={type}
|
||||
name={translate(wallet.lid)}
|
||||
example={wallet.example}
|
||||
helpLink={wallet.helpLink}
|
||||
walletType={type}
|
||||
isSecure={false}
|
||||
isDisabled={this.isWalletDisabled(type)}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
<WalletButton
|
||||
key="view-only"
|
||||
name={translate(viewOnly.lid)}
|
||||
example={viewOnly.example}
|
||||
helpLink={viewOnly.helpLink}
|
||||
walletType="view-only"
|
||||
isReadOnly={true}
|
||||
isDisabled={this.isWalletDisabled('view-only')}
|
||||
onClick={this.handleWalletChoice}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public handleWalletChoice = (walletType: string) => {
|
||||
const wallet = this.WALLETS[walletType];
|
||||
if (!wallet) {
|
||||
return;
|
||||
}
|
||||
|
||||
let timeout = 0;
|
||||
|
||||
if (wallet.attemptUnlock) {
|
||||
timeout = 250;
|
||||
wallet.unlock();
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
selectedWalletKey: walletType,
|
||||
value: wallet.initialParams
|
||||
});
|
||||
}, timeout);
|
||||
};
|
||||
|
||||
public clearWalletChoice = () => {
|
||||
this.setState({
|
||||
selectedWalletKey: null,
|
||||
value: null
|
||||
});
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { wallet, hidden } = this.props;
|
||||
const selectedWallet = this.getSelectedWallet();
|
||||
const decryptionComponent = this.getDecryptionComponent();
|
||||
const unlocked = !!wallet;
|
||||
return (
|
||||
<div>
|
||||
<NavigationPrompt when={unlocked} onConfirm={this.props.resetWallet} />
|
||||
{!hidden && (
|
||||
<article className="Tab-content-pane">
|
||||
<div className="WalletDecrypt">
|
||||
<TransitionGroup>
|
||||
{decryptionComponent && selectedWallet ? (
|
||||
<CSSTransition classNames="DecryptContent" timeout={500} key="decrypt">
|
||||
<div className="WalletDecrypt-decrypt">
|
||||
<button
|
||||
className="WalletDecrypt-decrypt-back"
|
||||
onClick={this.clearWalletChoice}
|
||||
>
|
||||
<i className="fa fa-arrow-left" /> {translate('Change Wallet')}
|
||||
</button>
|
||||
<h2 className="WalletDecrypt-decrypt-title">
|
||||
{!selectedWallet.isReadOnly && 'Unlock your'}{' '}
|
||||
{translate(selectedWallet.lid)}
|
||||
</h2>
|
||||
<section className="WalletDecrypt-decrypt-form">
|
||||
{decryptionComponent}
|
||||
</section>
|
||||
</div>
|
||||
</CSSTransition>
|
||||
) : (
|
||||
<CSSTransition classNames="DecryptContent" timeout={500} key="wallets">
|
||||
{this.buildWalletOptions()}
|
||||
</CSSTransition>
|
||||
)}
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</article>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public onChange = (value: UnlockParams) => {
|
||||
this.setState({ value });
|
||||
};
|
||||
|
||||
public onUnlock = (payload: any) => {
|
||||
const { value, selectedWalletKey } = this.state;
|
||||
if (!selectedWalletKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
// some components (TrezorDecrypt) don't take an onChange prop, and thus
|
||||
// this.state.value will remain unpopulated. in this case, we can expect
|
||||
// the payload to contain the unlocked wallet info.
|
||||
const unlockValue = value && !isEmpty(value) ? value : payload;
|
||||
this.WALLETS[selectedWalletKey].unlock(unlockValue);
|
||||
this.props.resetTransactionState();
|
||||
};
|
||||
|
||||
private isWalletDisabled = (walletKey: string) => {
|
||||
if (!this.props.disabledWallets) {
|
||||
return false;
|
||||
}
|
||||
return this.props.disabledWallets.indexOf(walletKey) !== -1;
|
||||
};
|
||||
}
|
||||
|
||||
function mapStateToProps(state: AppState) {
|
||||
return {
|
||||
offline: state.config.offline,
|
||||
wallet: state.wallet.inst
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
unlockKeystore,
|
||||
unlockMnemonic,
|
||||
unlockPrivateKey,
|
||||
unlockWeb3,
|
||||
setWallet,
|
||||
resetWallet,
|
||||
resetTransactionState: reset
|
||||
})(WalletDecrypt);
|
|
@ -52,7 +52,7 @@ interface State {
|
|||
page: number;
|
||||
}
|
||||
|
||||
class DeterministicWalletsModal extends React.Component<Props, State> {
|
||||
class DeterministicWalletsModalClass extends React.Component<Props, State> {
|
||||
public state = {
|
||||
selectedAddress: '',
|
||||
selectedAddrIndex: 0,
|
||||
|
@ -310,7 +310,7 @@ function mapStateToProps(state: AppState) {
|
|||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
export const DeterministicWalletsModal = connect(mapStateToProps, {
|
||||
getDeterministicWallets,
|
||||
setDesiredToken
|
||||
})(DeterministicWalletsModal);
|
||||
})(DeterministicWalletsModalClass);
|
|
@ -0,0 +1,7 @@
|
|||
import React from 'react';
|
||||
|
||||
export class DigitalBitboxDecrypt extends React.Component<{}, {}> {
|
||||
public render() {
|
||||
return <strong>Not yet implemented</strong>;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
import { isKeystorePassRequired } from 'libs/wallet';
|
||||
import React, { Component } from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
|
||||
export interface KeystoreValue {
|
||||
file: string;
|
||||
password: string;
|
||||
valid: boolean;
|
||||
}
|
||||
|
||||
function isPassRequired(file: string): boolean {
|
||||
let passReq = false;
|
||||
try {
|
||||
passReq = isKeystorePassRequired(file);
|
||||
} catch (e) {
|
||||
// TODO: communicate invalid file to user
|
||||
}
|
||||
return passReq;
|
||||
}
|
||||
|
||||
export class KeystoreDecrypt extends Component {
|
||||
public props: {
|
||||
value: KeystoreValue;
|
||||
onChange(value: KeystoreValue): void;
|
||||
onUnlock(): void;
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { file, password } = this.props.value;
|
||||
const passReq = isPassRequired(file);
|
||||
const unlockDisabled = !file || (passReq && !password);
|
||||
|
||||
return (
|
||||
<form id="selectedUploadKey" onSubmit={this.unlock}>
|
||||
<div className="form-group">
|
||||
<input
|
||||
className={'hidden'}
|
||||
type="file"
|
||||
id="fselector"
|
||||
onChange={this.handleFileSelection}
|
||||
/>
|
||||
<label htmlFor="fselector" style={{ width: '100%' }}>
|
||||
<a className="btn btn-default btn-block" id="aria1" tabIndex={0} role="button">
|
||||
{translate('ADD_Radio_2_short')}
|
||||
</a>
|
||||
</label>
|
||||
<div className={file.length && passReq ? '' : 'hidden'}>
|
||||
<p>{translate('ADD_Label_3')}</p>
|
||||
<input
|
||||
className={`form-control ${password.length > 0 ? 'is-valid' : 'is-invalid'}`}
|
||||
value={password}
|
||||
onChange={this.onPasswordChange}
|
||||
onKeyDown={this.onKeyDown}
|
||||
placeholder={translateRaw('x_Password')}
|
||||
type="password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className="btn btn-primary btn-block" disabled={unlockDisabled}>
|
||||
{translate('ADD_Label_6_short')}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
private onKeyDown = (e: any) => {
|
||||
if (e.keyCode === 13) {
|
||||
this.unlock(e);
|
||||
}
|
||||
};
|
||||
|
||||
private unlock = (e: React.SyntheticEvent<HTMLElement>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.onUnlock();
|
||||
};
|
||||
|
||||
private onPasswordChange = (e: any) => {
|
||||
const valid = this.props.value.file.length && e.target.value.length;
|
||||
this.props.onChange({
|
||||
...this.props.value,
|
||||
password: e.target.value,
|
||||
valid
|
||||
});
|
||||
};
|
||||
|
||||
private handleFileSelection = (e: any) => {
|
||||
const fileReader = new FileReader();
|
||||
const target = e.target;
|
||||
const inputFile = target.files[0];
|
||||
|
||||
fileReader.onload = () => {
|
||||
const keystore = fileReader.result;
|
||||
const passReq = isPassRequired(keystore);
|
||||
|
||||
this.props.onChange({
|
||||
...this.props.value,
|
||||
file: keystore,
|
||||
valid: keystore.length && !passReq
|
||||
});
|
||||
};
|
||||
|
||||
fileReader.readAsText(inputFile, 'utf-8');
|
||||
};
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
.LedgerDecrypt {
|
||||
text-align: center;
|
||||
padding-top: 30px;
|
||||
|
||||
&-decrypt {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-help {
|
||||
margin-top: 10px;
|
||||
|
@ -21,14 +16,15 @@
|
|||
}
|
||||
|
||||
&-buy {
|
||||
margin-top: 10px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
&-message {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
svg {
|
||||
|
||||
.Spinner {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import './LedgerNano.scss';
|
||||
import React, { Component } from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
||||
import { DeterministicWalletsModal } from './DeterministicWalletsModal';
|
||||
import { LedgerWallet } from 'libs/wallet';
|
||||
import Ledger3 from 'vendor/ledger3';
|
||||
import LedgerEth from 'vendor/ledger-eth';
|
||||
|
@ -23,7 +23,7 @@ interface State {
|
|||
showTip: boolean;
|
||||
}
|
||||
|
||||
export default class LedgerNanoSDecrypt extends Component<Props, State> {
|
||||
export class LedgerNanoSDecrypt extends Component<Props, State> {
|
||||
public state: State = {
|
||||
publicKey: '',
|
||||
chainCode: '',
|
||||
|
@ -44,7 +44,7 @@ export default class LedgerNanoSDecrypt extends Component<Props, State> {
|
|||
const showErr = error ? 'is-showing' : '';
|
||||
|
||||
return (
|
||||
<section className="LedgerDecrypt col-md-4 col-sm-6">
|
||||
<div className="LedgerDecrypt">
|
||||
{showTip && (
|
||||
<p>
|
||||
<strong>Tip: </strong>Make sure you're logged into the ethereum app on your hardware
|
||||
|
@ -52,7 +52,7 @@ export default class LedgerNanoSDecrypt extends Component<Props, State> {
|
|||
</p>
|
||||
)}
|
||||
<button
|
||||
className="LedgerDecrypt-decrypt btn btn-primary btn-lg"
|
||||
className="LedgerDecrypt-decrypt btn btn-primary btn-lg btn-block"
|
||||
onClick={this.handleNullConnect}
|
||||
disabled={isLoading}
|
||||
>
|
||||
|
@ -66,6 +66,17 @@ export default class LedgerNanoSDecrypt extends Component<Props, State> {
|
|||
)}
|
||||
</button>
|
||||
|
||||
<a
|
||||
className="LedgerDecrypt-buy btn btn-sm btn-default"
|
||||
href="https://www.ledgerwallet.com/r/fa4b?path=/products/"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
{translate('Don’t have a Ledger? Order one now!')}
|
||||
</a>
|
||||
|
||||
<div className={`LedgerDecrypt-error alert alert-danger ${showErr}`}>{error || '-'}</div>
|
||||
|
||||
<div className="LedgerDecrypt-help">
|
||||
Guides:
|
||||
<div>
|
||||
|
@ -87,15 +98,7 @@ export default class LedgerNanoSDecrypt extends Component<Props, State> {
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`LedgerDecrypt-error alert alert-danger ${showErr}`}>{error || '-'}</div>
|
||||
<a
|
||||
className="LedgerDecrypt-buy btn btn-sm btn-default"
|
||||
href="https://www.ledgerwallet.com/r/fa4b?path=/products/"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
{translate('Don’t have a Ledger? Order one now!')}
|
||||
</a>
|
||||
|
||||
<DeterministicWalletsModal
|
||||
isOpen={!!publicKey && !!chainCode}
|
||||
publicKey={publicKey}
|
||||
|
@ -107,7 +110,7 @@ export default class LedgerNanoSDecrypt extends Component<Props, State> {
|
|||
onPathChange={this.handlePathChange}
|
||||
walletType={translateRaw('x_Ledger')}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import { mnemonicToSeed, validateMnemonic } from 'bip39';
|
|||
import DPATHS from 'config/dpaths';
|
||||
import React, { Component } from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
||||
import { DeterministicWalletsModal } from './DeterministicWalletsModal';
|
||||
import { formatMnemonic } from 'utils/formatters';
|
||||
|
||||
const DEFAULT_PATH = DPATHS.MNEMONIC[0].value;
|
||||
|
@ -18,7 +18,7 @@ interface State {
|
|||
dPath: string;
|
||||
}
|
||||
|
||||
export default class MnemonicDecrypt extends Component<Props, State> {
|
||||
export class MnemonicDecrypt extends Component<Props, State> {
|
||||
public state: State = {
|
||||
phrase: '',
|
||||
formattedPhrase: '',
|
||||
|
@ -32,9 +32,8 @@ export default class MnemonicDecrypt extends Component<Props, State> {
|
|||
const isValidMnemonic = validateMnemonic(formattedPhrase);
|
||||
|
||||
return (
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<div>
|
||||
<div id="selectedTypeKey">
|
||||
<h4>{translate('ADD_Radio_5')}</h4>
|
||||
<div className="form-group">
|
||||
<textarea
|
||||
id="aria-private-key"
|
||||
|
@ -55,17 +54,16 @@ export default class MnemonicDecrypt extends Component<Props, State> {
|
|||
type="password"
|
||||
/>
|
||||
</div>
|
||||
{isValidMnemonic && (
|
||||
<div className="form-group">
|
||||
<button
|
||||
style={{ width: '100%' }}
|
||||
onClick={this.onDWModalOpen}
|
||||
className="btn btn-primary btn-lg"
|
||||
disabled={!isValidMnemonic}
|
||||
>
|
||||
{translate('Choose Address')}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<DeterministicWalletsModal
|
||||
|
@ -78,7 +76,7 @@ export default class MnemonicDecrypt extends Component<Props, State> {
|
|||
onPathChange={this.handlePathChange}
|
||||
walletType={translateRaw('x_Mnemonic')}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ interface State {
|
|||
openModal: boolean;
|
||||
}
|
||||
|
||||
class NavigationPrompt extends React.Component<Props, State> {
|
||||
class NavigationPromptClass extends React.Component<Props, State> {
|
||||
public unblock;
|
||||
|
||||
constructor(props) {
|
||||
|
@ -88,4 +88,4 @@ class NavigationPrompt extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
export default withRouter<Props>(NavigationPrompt);
|
||||
export const NavigationPrompt = withRouter<Props>(NavigationPromptClass);
|
|
@ -38,21 +38,20 @@ function validatePkeyAndPass(pkey: string, pass: string): Validated {
|
|||
};
|
||||
}
|
||||
|
||||
export default class PrivateKeyDecrypt extends Component {
|
||||
public props: {
|
||||
interface Props {
|
||||
value: PrivateKeyValue;
|
||||
onChange(value: PrivateKeyValue): void;
|
||||
onUnlock(): void;
|
||||
};
|
||||
}
|
||||
|
||||
export class PrivateKeyDecrypt extends Component<Props> {
|
||||
public render() {
|
||||
const { key, password } = this.props.value;
|
||||
const { isValidPkey, isPassRequired } = validatePkeyAndPass(key, password);
|
||||
const unlockDisabled = !isValidPkey || (isPassRequired && !password.length);
|
||||
|
||||
return (
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<div id="selectedTypeKey">
|
||||
<h4>{translate('ADD_Radio_3')}</h4>
|
||||
<form id="selectedTypeKey" onSubmit={this.unlock}>
|
||||
<div className="form-group">
|
||||
<textarea
|
||||
id="aria-private-key"
|
||||
|
@ -78,8 +77,10 @@ export default class PrivateKeyDecrypt extends Component {
|
|||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
<button className="btn btn-block btn-primary" disabled={unlockDisabled}>
|
||||
{translate('ADD_Label_6_short')}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -103,11 +104,15 @@ export default class PrivateKeyDecrypt extends Component {
|
|||
});
|
||||
};
|
||||
|
||||
public onKeyDown = (e: any) => {
|
||||
public onKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {
|
||||
if (e.keyCode === 13) {
|
||||
this.unlock(e);
|
||||
}
|
||||
};
|
||||
|
||||
private unlock = (e: React.SyntheticEvent<HTMLElement>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.onUnlock();
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
.TrezorDecrypt {
|
||||
text-align: center;
|
||||
padding-top: 30px;
|
||||
|
||||
&-decrypt {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-help {
|
||||
margin-top: 10px;
|
||||
|
@ -21,14 +16,15 @@
|
|||
}
|
||||
|
||||
&-buy {
|
||||
margin-top: 10px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
&-message {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
svg {
|
||||
|
||||
.Spinner {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import { TrezorWallet } from 'libs/wallet';
|
|||
import React, { Component } from 'react';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import TrezorConnect from 'vendor/trezor-connect';
|
||||
import DeterministicWalletsModal from './DeterministicWalletsModal';
|
||||
import { DeterministicWalletsModal } from './DeterministicWalletsModal';
|
||||
import './Trezor.scss';
|
||||
import { Spinner } from 'components/ui';
|
||||
const DEFAULT_PATH = DPATHS.TREZOR[0].value;
|
||||
|
@ -19,7 +19,7 @@ interface State {
|
|||
isLoading: boolean;
|
||||
}
|
||||
|
||||
export default class TrezorDecrypt extends Component<Props, State> {
|
||||
export class TrezorDecrypt extends Component<Props, State> {
|
||||
public state: State = {
|
||||
publicKey: '',
|
||||
chainCode: '',
|
||||
|
@ -33,9 +33,9 @@ export default class TrezorDecrypt extends Component<Props, State> {
|
|||
const showErr = error ? 'is-showing' : '';
|
||||
|
||||
return (
|
||||
<section className="TrezorDecrypt col-md-4 col-sm-6">
|
||||
<div className="TrezorDecrypt">
|
||||
<button
|
||||
className="TrezorDecrypt-decrypt btn btn-primary btn-lg"
|
||||
className="TrezorDecrypt-decrypt btn btn-primary btn-lg btn-block"
|
||||
onClick={this.handleNullConnect}
|
||||
disabled={isLoading}
|
||||
>
|
||||
|
@ -49,6 +49,17 @@ export default class TrezorDecrypt extends Component<Props, State> {
|
|||
)}
|
||||
</button>
|
||||
|
||||
<a
|
||||
className="TrezorDecrypt-buy btn btn-sm btn-default"
|
||||
href="https://trezor.io/?a=myetherwallet.com"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
{translate('Don’t have a TREZOR? Order one now!')}
|
||||
</a>
|
||||
|
||||
<div className={`TrezorDecrypt-error alert alert-danger ${showErr}`}>{error || '-'}</div>
|
||||
|
||||
<div className="TrezorDecrypt-help">
|
||||
Guide:{' '}
|
||||
<a
|
||||
|
@ -60,17 +71,6 @@ export default class TrezorDecrypt extends Component<Props, State> {
|
|||
</a>
|
||||
</div>
|
||||
|
||||
<div className={`TrezorDecrypt-error alert alert-danger ${showErr}`}>{error || '-'}</div>
|
||||
|
||||
<a
|
||||
className="TrezorDecrypt-buy btn btn-sm btn-default"
|
||||
href="https://trezor.io/?a=myetherwallet.com"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
{translate('Don’t have a TREZOR? Order one now!')}
|
||||
</a>
|
||||
|
||||
<DeterministicWalletsModal
|
||||
isOpen={!!publicKey && !!chainCode}
|
||||
publicKey={publicKey}
|
||||
|
@ -82,7 +82,7 @@ export default class TrezorDecrypt extends Component<Props, State> {
|
|||
onPathChange={this.handlePathChange}
|
||||
walletType={translateRaw('x_Trezor')}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import React, { Component } from 'react';
|
||||
import translate from 'translations';
|
||||
import { donationAddressMap } from 'config/data';
|
||||
import { isValidETHAddress } from 'libs/validators';
|
||||
import { AddressOnlyWallet } from 'libs/wallet';
|
||||
|
||||
interface Props {
|
||||
onUnlock(param: any): void;
|
||||
}
|
||||
|
||||
interface State {
|
||||
address: string;
|
||||
}
|
||||
|
||||
export class ViewOnlyDecrypt extends Component<Props, State> {
|
||||
public state = {
|
||||
address: ''
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { address } = this.state;
|
||||
const isValid = isValidETHAddress(address);
|
||||
|
||||
return (
|
||||
<div id="selectedUploadKey">
|
||||
<form className="form-group" onSubmit={this.openWallet}>
|
||||
<textarea
|
||||
className={`form-control
|
||||
${isValid ? 'is-valid' : 'is-invalid'}
|
||||
`}
|
||||
value={address}
|
||||
onChange={this.changeAddress}
|
||||
onKeyDown={this.handleEnterKey}
|
||||
placeholder={donationAddressMap.ETH}
|
||||
rows={3}
|
||||
/>
|
||||
|
||||
<button className="btn btn-primary btn-block" disabled={!isValid}>
|
||||
{translate('NAV_ViewWallet')}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private changeAddress = (ev: React.FormEvent<HTMLTextAreaElement>) => {
|
||||
this.setState({ address: ev.currentTarget.value });
|
||||
};
|
||||
|
||||
private handleEnterKey = (ev: React.KeyboardEvent<HTMLElement>) => {
|
||||
if (ev.keyCode === 13) {
|
||||
this.openWallet(ev);
|
||||
}
|
||||
};
|
||||
|
||||
private openWallet = (ev: React.FormEvent<HTMLElement>) => {
|
||||
const { address } = this.state;
|
||||
ev.preventDefault();
|
||||
if (isValidETHAddress(address)) {
|
||||
const wallet = new AddressOnlyWallet(address);
|
||||
this.props.onUnlock(wallet);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
@import 'common/sass/variables';
|
||||
@import 'common/sass/mixins';
|
||||
|
||||
@keyframes wallet-button-enter {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(6px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes wallet-button-enter-disabled {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
30%,
|
||||
100% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
.WalletButton {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
height: 155px;
|
||||
max-width: 230px;
|
||||
min-width: 200px;
|
||||
padding: 25px 15px;
|
||||
margin: 0 $space-md $space;
|
||||
|
||||
background: #FFF;
|
||||
box-shadow: 0 1px 4px rgba(#000, 0.2);
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: transform 150ms ease, box-shadow 150ms ease;
|
||||
animation: wallet-button-enter 400ms ease 1;
|
||||
animation-fill-mode: backwards;
|
||||
outline: none;
|
||||
|
||||
@for $i from 0 to 5 {
|
||||
&:nth-child(#{$i}) {
|
||||
animation-delay: 100ms + ($i * 60ms);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.is-disabled) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
transform: translateY(-2px);
|
||||
z-index: 2;
|
||||
box-shadow: 0 1px 4px rgba(#000, 0.12),
|
||||
0 4px 6px rgba(#000, 0.12);
|
||||
|
||||
.WalletButton-title {
|
||||
color: $brand-primary;
|
||||
|
||||
&-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 1px 2px rgba(#000, 0.2),
|
||||
0 3px 4px rgba(#000, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
opacity: 0.3 !important;
|
||||
outline: none;
|
||||
cursor: not-allowed;
|
||||
animation-name: wallet-button-enter, wallet-button-enter-disabled;
|
||||
}
|
||||
|
||||
&-title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: $font-size-medium;
|
||||
margin-bottom: $space * 1.25;
|
||||
transition: color 150ms ease;
|
||||
|
||||
&-icon {
|
||||
margin-right: 8px;
|
||||
max-height: 26px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
&-description {
|
||||
color: $gray;
|
||||
font-size: $font-size-small;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
&-example {
|
||||
font-size: $font-size-xs;
|
||||
color: rgba($brand-danger, 0.7);
|
||||
@include ellipsis;
|
||||
}
|
||||
|
||||
&-icons {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
right: 5px;
|
||||
|
||||
&-icon {
|
||||
position: relative;
|
||||
margin-left: 8px;
|
||||
@include show-tooltip-on-hover;
|
||||
|
||||
.fa {
|
||||
position: relative;
|
||||
opacity: 0.6;
|
||||
font-size: $font-size-medium;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&-shield {
|
||||
color: $brand-primary;
|
||||
}
|
||||
|
||||
&-exclamation-triangle {
|
||||
color: $brand-warning;
|
||||
}
|
||||
|
||||
&-question-circle,
|
||||
&-eye {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
&-question-circle:hover {
|
||||
color: $brand-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--small {
|
||||
height: 105px;
|
||||
max-width: 180px;
|
||||
min-width: 160px;
|
||||
margin: 0 $space-sm $space-md;
|
||||
padding: 20px 15px;
|
||||
|
||||
.WalletButton {
|
||||
&-title {
|
||||
font-size: $font-size-bump;
|
||||
margin-bottom: $space-sm;
|
||||
}
|
||||
|
||||
&-icons {
|
||||
&-icon {
|
||||
margin-left: 6px;
|
||||
|
||||
.fa {
|
||||
font-size: $font-size-bump;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile handling
|
||||
@media screen and (max-width: $screen-xs) {
|
||||
padding: 16px;
|
||||
|
||||
&, &--small {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: none;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&-title {
|
||||
justify-content: flex-start;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&-description,
|
||||
&-example {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-icons {
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
&-icon {
|
||||
float: left;
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
width: 48px;
|
||||
text-align: center;
|
||||
border-left: 1px solid #F4F4F4;
|
||||
background: #FEFEFE;
|
||||
|
||||
a {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.fa {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--small {
|
||||
padding: 12px;
|
||||
|
||||
.WalletButton-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.WalletButton-icons {
|
||||
&-icon {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { translateRaw } from 'translations';
|
||||
import { NewTabLink, Tooltip } from 'components/ui';
|
||||
import './WalletButton.scss';
|
||||
|
||||
interface Props {
|
||||
name: React.ReactElement<string> | string;
|
||||
description?: React.ReactElement<string> | string;
|
||||
example?: React.ReactElement<string> | string;
|
||||
icon?: string | null;
|
||||
helpLink?: string;
|
||||
walletType: string;
|
||||
isSecure?: boolean;
|
||||
isReadOnly?: boolean;
|
||||
isDisabled?: boolean;
|
||||
onClick(walletType: string): void;
|
||||
}
|
||||
|
||||
export class WalletButton extends React.Component<Props, {}> {
|
||||
public render() {
|
||||
const {
|
||||
name,
|
||||
description,
|
||||
example,
|
||||
icon,
|
||||
helpLink,
|
||||
isSecure,
|
||||
isReadOnly,
|
||||
isDisabled
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames({
|
||||
WalletButton: true,
|
||||
'WalletButton--small': !isSecure,
|
||||
'is-disabled': isDisabled
|
||||
})}
|
||||
onClick={this.handleClick}
|
||||
tabIndex={isDisabled ? -1 : 0}
|
||||
aria-disabled={isDisabled}
|
||||
>
|
||||
<div className="WalletButton-title">
|
||||
{icon && <img className="WalletButton-title-icon" src={icon} />}
|
||||
<span>{name}</span>
|
||||
</div>
|
||||
{description && <div className="WalletButton-description">{description}</div>}
|
||||
{example && <div className="WalletButton-example">{example}</div>}
|
||||
<div className="WalletButton-icons">
|
||||
{isSecure === true && (
|
||||
<span className="WalletButton-icons-icon" onClick={this.stopPropogation}>
|
||||
<i className="fa fa-shield" />
|
||||
<Tooltip>{translateRaw('This wallet type is secure')}</Tooltip>
|
||||
</span>
|
||||
)}
|
||||
{isSecure === false && (
|
||||
<span className="WalletButton-icons-icon" onClick={this.stopPropogation}>
|
||||
<i className="fa fa-exclamation-triangle" />
|
||||
<Tooltip>{translateRaw('This wallet type is insecure')}</Tooltip>
|
||||
</span>
|
||||
)}
|
||||
{isReadOnly === true && (
|
||||
<span className="WalletButton-icons-icon" onClick={this.stopPropogation}>
|
||||
<i className="fa fa-eye" />
|
||||
<Tooltip>{translateRaw('You cannot send using address only')}</Tooltip>
|
||||
</span>
|
||||
)}
|
||||
{helpLink && (
|
||||
<span className="WalletButton-icons-icon">
|
||||
<NewTabLink href={helpLink} onClick={this.stopPropogation}>
|
||||
<i className="fa fa-question-circle" />
|
||||
</NewTabLink>
|
||||
<Tooltip>{translateRaw('NAV_Help')}</Tooltip>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private handleClick = () => {
|
||||
if (this.props.isDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onClick(this.props.walletType);
|
||||
};
|
||||
|
||||
private stopPropogation = (ev: React.SyntheticEvent<any>) => {
|
||||
ev.stopPropagation();
|
||||
};
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
.Web3Decrypt {
|
||||
text-align: center;
|
||||
padding-top: 30px;
|
||||
|
||||
&-decrypt {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-help {
|
||||
margin-top: 10px;
|
|
@ -7,13 +7,13 @@ interface Props {
|
|||
onUnlock(): void;
|
||||
}
|
||||
|
||||
export default class Web3Decrypt extends Component<Props> {
|
||||
export class Web3Decrypt extends Component<Props> {
|
||||
public render() {
|
||||
return (
|
||||
<section className="Web3Decrypt col-md-4 col-sm-6">
|
||||
<div className="Web3Decrypt">
|
||||
<div>
|
||||
<button
|
||||
className="Web3Decrypt-decrypt btn btn-primary btn-lg"
|
||||
className="Web3Decrypt-decrypt btn btn-primary btn-lg btn-block"
|
||||
onClick={this.props.onUnlock}
|
||||
>
|
||||
{translate('ADD_MetaMask')}
|
||||
|
@ -22,12 +22,12 @@ export default class Web3Decrypt extends Component<Props> {
|
|||
|
||||
<div>
|
||||
<NewTabLink
|
||||
className="Web3Decrypt-install btn btn-sm btn-default"
|
||||
className="Web3Decrypt-install btn btn-sm btn-default btn-block"
|
||||
content={translate('Download MetaMask')}
|
||||
href="https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
export * from './DeterministicWalletsModal';
|
||||
export * from './DigitalBitbox';
|
||||
export * from './Keystore';
|
||||
export * from './LedgerNano';
|
||||
export * from './Mnemonic';
|
||||
export * from './NavigationPrompt';
|
||||
export * from './PrivateKey';
|
||||
export * from './Trezor';
|
||||
export * from './ViewOnly';
|
||||
export * from './WalletButton';
|
||||
export * from './Web3';
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"READ_ONLY": ["view-only"],
|
||||
"UNABLE_TO_SIGN": ["trezor", "view-only"]
|
||||
}
|
|
@ -1,258 +1,3 @@
|
|||
import {
|
||||
setWallet,
|
||||
TSetWallet,
|
||||
unlockKeystore,
|
||||
TUnlockKeystore,
|
||||
unlockMnemonic,
|
||||
TUnlockMnemonic,
|
||||
unlockPrivateKey,
|
||||
TUnlockPrivateKey,
|
||||
unlockWeb3,
|
||||
TUnlockWeb3,
|
||||
resetWallet,
|
||||
TResetWallet
|
||||
} from 'actions/wallet';
|
||||
import { reset, TReset } from 'actions/transaction';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import map from 'lodash/map';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import translate from 'translations';
|
||||
import KeystoreDecrypt from './Keystore';
|
||||
import LedgerNanoSDecrypt from './LedgerNano';
|
||||
import MnemonicDecrypt from './Mnemonic';
|
||||
import PrivateKeyDecrypt, { PrivateKeyValue } from './PrivateKey';
|
||||
import TrezorDecrypt from './Trezor';
|
||||
import ViewOnlyDecrypt from './ViewOnly';
|
||||
import { AppState } from 'reducers';
|
||||
import Web3Decrypt from './Web3';
|
||||
import Help from 'components/ui/Help';
|
||||
import { knowledgeBaseURL } from 'config/data';
|
||||
import NavigationPrompt from './NavigationPrompt';
|
||||
import { IWallet } from 'libs/wallet';
|
||||
import { showNotification, TShowNotification } from 'actions/notifications';
|
||||
|
||||
type UnlockParams = {} | PrivateKeyValue;
|
||||
|
||||
interface Props {
|
||||
resetTransactionState: TReset;
|
||||
unlockKeystore: TUnlockKeystore;
|
||||
unlockMnemonic: TUnlockMnemonic;
|
||||
unlockPrivateKey: TUnlockPrivateKey;
|
||||
setWallet: TSetWallet;
|
||||
unlockWeb3: TUnlockWeb3;
|
||||
resetWallet: TResetWallet;
|
||||
showNotification: TShowNotification;
|
||||
wallet: IWallet;
|
||||
hidden?: boolean;
|
||||
offline: boolean;
|
||||
allowReadOnly?: boolean;
|
||||
disabledWallets?: string[];
|
||||
}
|
||||
|
||||
interface State {
|
||||
selectedWalletKey: string;
|
||||
value: UnlockParams;
|
||||
}
|
||||
|
||||
export class WalletDecrypt extends Component<Props, State> {
|
||||
public WALLETS = {
|
||||
web3: {
|
||||
lid: 'x_MetaMask',
|
||||
component: Web3Decrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.unlockWeb3,
|
||||
helpLink: `${knowledgeBaseURL}/migration/moving-from-private-key-to-metamask`
|
||||
},
|
||||
'ledger-nano-s': {
|
||||
lid: 'x_Ledger',
|
||||
component: LedgerNanoSDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink:
|
||||
'https://ledger.zendesk.com/hc/en-us/articles/115005200009-How-to-use-MyEtherWallet-with-Ledger'
|
||||
},
|
||||
trezor: {
|
||||
lid: 'x_Trezor',
|
||||
component: TrezorDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: 'https://doc.satoshilabs.com/trezor-apps/mew.html'
|
||||
},
|
||||
'keystore-file': {
|
||||
lid: 'x_Keystore2',
|
||||
component: KeystoreDecrypt,
|
||||
initialParams: {
|
||||
file: '',
|
||||
password: ''
|
||||
},
|
||||
unlock: this.props.unlockKeystore,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
'mnemonic-phrase': {
|
||||
lid: 'x_Mnemonic',
|
||||
component: MnemonicDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.unlockMnemonic,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
'private-key': {
|
||||
lid: 'x_PrivKey2',
|
||||
component: PrivateKeyDecrypt,
|
||||
initialParams: {
|
||||
key: '',
|
||||
password: ''
|
||||
},
|
||||
unlock: this.props.unlockPrivateKey,
|
||||
helpLink: `${knowledgeBaseURL}/private-keys-passwords/difference-beween-private-key-and-keystore-file.html`
|
||||
},
|
||||
'view-only': {
|
||||
lid: 'View with Address Only',
|
||||
component: ViewOnlyDecrypt,
|
||||
initialParams: {},
|
||||
unlock: this.props.setWallet,
|
||||
helpLink: ''
|
||||
}
|
||||
};
|
||||
public state: State = {
|
||||
selectedWalletKey: 'keystore-file',
|
||||
value: this.WALLETS['keystore-file'].initialParams
|
||||
};
|
||||
|
||||
public getDecryptionComponent() {
|
||||
const { selectedWalletKey, value } = this.state;
|
||||
const selectedWallet = this.WALLETS[selectedWalletKey];
|
||||
|
||||
if (!selectedWallet) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<selectedWallet.component
|
||||
value={value}
|
||||
onChange={this.onChange}
|
||||
onUnlock={this.onUnlock}
|
||||
showNotification={this.props.showNotification}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public isOnlineRequiredWalletAndOffline(selectedWalletKey) {
|
||||
const onlineRequiredWallets = ['trezor', 'ledger-nano-s'];
|
||||
return this.props.offline && onlineRequiredWallets.includes(selectedWalletKey);
|
||||
}
|
||||
|
||||
public buildWalletOptions() {
|
||||
return map(this.WALLETS, (wallet, key) => {
|
||||
const { helpLink } = wallet;
|
||||
const isSelected = this.state.selectedWalletKey === key;
|
||||
const isDisabled =
|
||||
this.isOnlineRequiredWalletAndOffline(key) ||
|
||||
(!this.props.allowReadOnly && wallet.component === ViewOnlyDecrypt) ||
|
||||
this.isWalletDisabled(key);
|
||||
|
||||
return (
|
||||
<label className="radio" key={key}>
|
||||
<input
|
||||
aria-flowto={`aria-${key}`}
|
||||
aria-labelledby={`${key}-label`}
|
||||
type="radio"
|
||||
name="decryption-choice-radio-group"
|
||||
value={key}
|
||||
checked={isSelected}
|
||||
disabled={isDisabled}
|
||||
onChange={this.handleDecryptionChoiceChange}
|
||||
/>
|
||||
<span id={`${key}-label`}>{translate(wallet.lid)}</span>
|
||||
{helpLink ? <Help link={helpLink} /> : null}
|
||||
</label>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public handleDecryptionChoiceChange = (event: React.FormEvent<HTMLInputElement>) => {
|
||||
const wallet = this.WALLETS[event.currentTarget.value];
|
||||
|
||||
if (!wallet) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
selectedWalletKey: event.currentTarget.value,
|
||||
value: wallet.initialParams
|
||||
});
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { wallet, hidden } = this.props;
|
||||
const decryptionComponent = this.getDecryptionComponent();
|
||||
const unlocked = !!wallet;
|
||||
return (
|
||||
<div>
|
||||
<NavigationPrompt when={unlocked} onConfirm={this.props.resetWallet} />
|
||||
{!hidden && (
|
||||
<article className="Tab-content-pane row">
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<h4>{translate('decrypt_Access')}</h4>
|
||||
|
||||
{this.buildWalletOptions()}
|
||||
</section>
|
||||
|
||||
{decryptionComponent}
|
||||
{!!(this.state.value as PrivateKeyValue).valid && (
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<h4 id="uploadbtntxt-wallet">{translate('ADD_Label_6')}</h4>
|
||||
<div className="form-group">
|
||||
<a
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
className="btn btn-primary btn-block"
|
||||
onClick={this.onUnlock}
|
||||
>
|
||||
{translate('ADD_Label_6_short')}
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</article>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public onChange = (value: UnlockParams) => {
|
||||
this.setState({ value });
|
||||
};
|
||||
|
||||
public onUnlock = (payload: any) => {
|
||||
// some components (TrezorDecrypt) don't take an onChange prop, and thus this.state.value will remain unpopulated.
|
||||
// in this case, we can expect the payload to contain the unlocked wallet info.
|
||||
const unlockValue = this.state.value && !isEmpty(this.state.value) ? this.state.value : payload;
|
||||
this.WALLETS[this.state.selectedWalletKey].unlock(unlockValue);
|
||||
this.props.resetTransactionState();
|
||||
};
|
||||
|
||||
private isWalletDisabled = (walletKey: string) => {
|
||||
if (!this.props.disabledWallets) {
|
||||
return false;
|
||||
}
|
||||
return this.props.disabledWallets.indexOf(walletKey) !== -1;
|
||||
};
|
||||
}
|
||||
|
||||
function mapStateToProps(state: AppState) {
|
||||
return {
|
||||
offline: state.config.offline,
|
||||
wallet: state.wallet.inst
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
unlockKeystore,
|
||||
unlockMnemonic,
|
||||
unlockPrivateKey,
|
||||
unlockWeb3,
|
||||
setWallet,
|
||||
resetWallet,
|
||||
resetTransactionState: reset,
|
||||
showNotification
|
||||
})(WalletDecrypt);
|
||||
import WalletDecrypt from './WalletDecrypt';
|
||||
export default WalletDecrypt;
|
||||
export { default as DISABLE_WALLETS } from './disables.json';
|
||||
|
|
|
@ -15,3 +15,4 @@ export { default as Footer } from './Footer';
|
|||
export { default as BalanceSidebar } from './BalanceSidebar';
|
||||
export { default as PaperWallet } from './PaperWallet';
|
||||
export { default as AlphaAgreement } from './AlphaAgreement';
|
||||
export { default as WalletDecrypt } from './WalletDecrypt';
|
||||
|
|
|
@ -5,3 +5,4 @@ export * from './TokenQuery';
|
|||
export * from './OnlyUnlocked';
|
||||
export * from './WhenQueryExists';
|
||||
export * from './SerializedTransaction';
|
||||
export { default as FullWalletOnly } from './FullWalletOnly';
|
||||
|
|
|
@ -27,6 +27,7 @@ interface AAttributes {
|
|||
shape?: 'default' | 'rect' | 'circle' | 'poly';
|
||||
target?: '_blank' | '_parent' | '_self' | '_top';
|
||||
type?: string;
|
||||
onClick?(ev: React.MouseEvent<HTMLAnchorElement>): void;
|
||||
}
|
||||
|
||||
interface NewTabLinkProps extends AAttributes {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
@import 'common/sass/variables';
|
||||
@import 'common/sass/mixins';
|
||||
|
||||
.Tooltip {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
width: 220px;
|
||||
color: #FFF;
|
||||
font-size: $font-size-xs;
|
||||
font-family: $font-family-sans-serif;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translate(-50%, -100%) translateY(-5px);
|
||||
transition-property: opacity, transform, visibility;
|
||||
transition-duration: 100ms, 100ms, 0ms;
|
||||
transition-delay: 0ms, 0ms, 100ms;
|
||||
z-index: $zindex-tooltip;
|
||||
|
||||
> span {
|
||||
display: inline-block;
|
||||
background: rgba(#000, 0.9);
|
||||
border-radius: 2px;
|
||||
padding: 4px 8px;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 100%);
|
||||
@include triangle(8px, rgba(#000, 0.9), down);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import React from 'react';
|
||||
import './Tooltip.scss';
|
||||
|
||||
interface Props {
|
||||
children: React.ReactElement<string> | string;
|
||||
}
|
||||
|
||||
const Tooltip: React.SFC<Props> = ({ children }) => (
|
||||
<div className="Tooltip">
|
||||
<span className="Tooltip-text">{children}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Tooltip;
|
|
@ -9,7 +9,7 @@ import './UnlockHeader.scss';
|
|||
interface Props {
|
||||
title: React.ReactElement<any>;
|
||||
wallet: IWallet;
|
||||
allowReadOnly: boolean;
|
||||
disabledWallets?: string[];
|
||||
}
|
||||
interface State {
|
||||
isExpanded: boolean;
|
||||
|
@ -26,7 +26,7 @@ export class UnlockHeader extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const { title, wallet, allowReadOnly } = this.props;
|
||||
const { title, wallet, disabledWallets } = this.props;
|
||||
const { isExpanded } = this.state;
|
||||
|
||||
return (
|
||||
|
@ -52,7 +52,7 @@ export class UnlockHeader extends React.Component<Props, State> {
|
|||
<i className="fa fa-times" />
|
||||
</button>
|
||||
)}
|
||||
<WalletDecrypt hidden={!this.state.isExpanded} allowReadOnly={allowReadOnly} />
|
||||
<WalletDecrypt hidden={!this.state.isExpanded} disabledWallets={disabledWallets} />
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ export { default as QRCode } from './QRCode';
|
|||
export { default as NewTabLink } from './NewTabLink';
|
||||
export { default as UnitDisplay } from './UnitDisplay';
|
||||
export { default as Spinner } from './Spinner';
|
||||
export { default as Tooltip } from './Tooltip';
|
||||
export * from './ConditionalInput';
|
||||
export * from './Aux';
|
||||
export * from './Expandable';
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
.Deploy {
|
||||
&-field {
|
||||
margin-top: 0;
|
||||
|
||||
&-label {
|
||||
float: left;
|
||||
}
|
||||
|
||||
&-reset {
|
||||
float: right;
|
||||
|
||||
.fa {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,25 +5,30 @@ import { GasFieldFactory } from 'components/GasFieldFactory';
|
|||
import { SendButtonFactory } from 'components/SendButtonFactory';
|
||||
import { SigningStatus } from 'components/SigningStatus';
|
||||
import { NonceField } from 'components/NonceField';
|
||||
import { OfflineAwareUnlockHeader } from 'components';
|
||||
import WalletDecrypt, { DISABLE_WALLETS } from 'components/WalletDecrypt';
|
||||
import { GenerateTransaction } from 'components/GenerateTransaction';
|
||||
import React, { Component } from 'react';
|
||||
import { setToField, TSetToField } from 'actions/transaction';
|
||||
import { resetWallet, TResetWallet } from 'actions/wallet';
|
||||
import { connect } from 'react-redux';
|
||||
import { Aux } from 'components/ui';
|
||||
import { OnlyUnlocked } from 'components/renderCbs';
|
||||
import { FullWalletOnly } from 'components/renderCbs';
|
||||
import './Deploy.scss';
|
||||
|
||||
interface DispatchProps {
|
||||
setToField: TSetToField;
|
||||
resetWallet: TResetWallet;
|
||||
}
|
||||
|
||||
class DeployClass extends Component<DispatchProps> {
|
||||
public render() {
|
||||
const content = (
|
||||
<div className="Deploy">
|
||||
<section>
|
||||
<label className="Deploy-field form-group">
|
||||
<h4 className="Deploy-field-label">{translate('CONTRACT_ByteCode')}</h4>
|
||||
const makeContent = () => (
|
||||
<main className="Deploy Tab-content-pane" role="main">
|
||||
<div className="Deploy-field form-group">
|
||||
<h3 className="Deploy-field-label">{translate('CONTRACT_ByteCode')}</h3>
|
||||
<button className="Deploy-field-reset btn btn-default btn-sm" onClick={this.changeWallet}>
|
||||
<i className="fa fa-refresh" />
|
||||
{translate('Change Wallet')}
|
||||
</button>
|
||||
<DataFieldFactory
|
||||
withProps={({ data: { raw, value }, onChange, readOnly }) => (
|
||||
<textarea
|
||||
|
@ -39,7 +44,7 @@ class DeployClass extends Component<DispatchProps> {
|
|||
/>
|
||||
)}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label className="Deploy-field form-group">
|
||||
<h4 className="Deploy-field-label">Gas Limit</h4>
|
||||
|
@ -75,19 +80,20 @@ class DeployClass extends Component<DispatchProps> {
|
|||
</button>
|
||||
)}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
||||
return (
|
||||
<Aux>
|
||||
<OfflineAwareUnlockHeader allowReadOnly={false} />
|
||||
<OnlyUnlocked whenUnlocked={content} />
|
||||
</Aux>
|
||||
);
|
||||
const makeDecrypt = () => <WalletDecrypt disabledWallets={DISABLE_WALLETS.READ_ONLY} />;
|
||||
|
||||
return <FullWalletOnly withFullWallet={makeContent} withoutFullWallet={makeDecrypt} />;
|
||||
}
|
||||
|
||||
private changeWallet = () => {
|
||||
this.props.resetWallet();
|
||||
};
|
||||
}
|
||||
|
||||
export const Deploy = connect(null, {
|
||||
setToField
|
||||
setToField,
|
||||
resetWallet
|
||||
})(DeployClass);
|
||||
|
|
|
@ -1,23 +1,17 @@
|
|||
import { Aux } from 'components/ui';
|
||||
import { GasField } from './GasField';
|
||||
import { AmountField } from './AmountField';
|
||||
import { NonceField } from 'components/NonceField';
|
||||
import { OfflineAwareUnlockHeader } from 'components/OfflineAwareUnlockHeader';
|
||||
import { SendButton } from 'components/SendButton';
|
||||
import React, { Component } from 'react';
|
||||
import { SigningStatus } from 'components/SigningStatus';
|
||||
import { OnlyUnlocked } from 'components/renderCbs';
|
||||
import { NonceField, SendButton, SigningStatus } from 'components';
|
||||
import WalletDecrypt, { DISABLE_WALLETS } from 'components/WalletDecrypt';
|
||||
import { FullWalletOnly } from 'components/renderCbs';
|
||||
import { Aux } from 'components/ui';
|
||||
|
||||
interface OwnProps {
|
||||
button: React.ReactElement<any>;
|
||||
}
|
||||
export class Fields extends Component<OwnProps> {
|
||||
public render() {
|
||||
return (
|
||||
<Aux>
|
||||
<OfflineAwareUnlockHeader allowReadOnly={false} />
|
||||
<OnlyUnlocked
|
||||
whenUnlocked={
|
||||
const makeContent = () => (
|
||||
<Aux>
|
||||
<GasField />
|
||||
<AmountField />
|
||||
|
@ -26,9 +20,10 @@ export class Fields extends Component<OwnProps> {
|
|||
<SigningStatus />
|
||||
<SendButton />
|
||||
</Aux>
|
||||
}
|
||||
/>
|
||||
</Aux>
|
||||
);
|
||||
|
||||
const makeDecrypt = () => <WalletDecrypt disabledWallets={DISABLE_WALLETS.READ_ONLY} />;
|
||||
|
||||
return <FullWalletOnly withFullWallet={makeContent} withoutFullWallet={makeDecrypt} />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,14 +47,14 @@ class InteractClass extends Component<DispatchProps, State> {
|
|||
const { showExplorer, currentContract } = this.state;
|
||||
|
||||
return (
|
||||
<div className="Interact">
|
||||
<main className="Interact Tab-content-pane" role="main">
|
||||
<InteractForm accessContract={this.accessContract} resetState={this.resetState} />
|
||||
<hr />
|
||||
{showExplorer &&
|
||||
currentContract && (
|
||||
<InteractExplorer contractFunctions={Contract.getFunctions(currentContract)} />
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,9 +63,7 @@ class Contracts extends Component<Props, State> {
|
|||
</h1>
|
||||
</div>
|
||||
|
||||
<main className="Tab-content-pane" role="main">
|
||||
<div className="Contracts-content">{content}</div>
|
||||
</main>
|
||||
</section>
|
||||
</TabSection>
|
||||
);
|
||||
|
|
|
@ -44,7 +44,7 @@ class SendTransaction extends React.Component<Props> {
|
|||
return (
|
||||
<TabSection>
|
||||
<section className="Tab-content">
|
||||
<OfflineAwareUnlockHeader allowReadOnly={true} />
|
||||
<OfflineAwareUnlockHeader />
|
||||
{wallet && <WalletTabs {...tabProps} />}
|
||||
</section>
|
||||
</TabSection>
|
||||
|
|
|
@ -2,6 +2,18 @@
|
|||
text-align: center;
|
||||
padding-top: 30px;
|
||||
|
||||
&-label {
|
||||
float: left;
|
||||
}
|
||||
|
||||
&-reset {
|
||||
float: right;
|
||||
|
||||
.fa {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&-sign {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import classnames from 'classnames';
|
||||
import WalletDecrypt from 'components/WalletDecrypt';
|
||||
import WalletDecrypt, { DISABLE_WALLETS } from 'components/WalletDecrypt';
|
||||
import translate from 'translations';
|
||||
import { showNotification, TShowNotification } from 'actions/notifications';
|
||||
import { resetWallet, TResetWallet } from 'actions/wallet';
|
||||
import { ISignedMessage } from 'libs/signing';
|
||||
import { IFullWallet } from 'libs/wallet';
|
||||
import { AppState } from 'reducers';
|
||||
|
@ -12,9 +13,10 @@ import { isWalletFullyUnlocked } from 'selectors/wallet';
|
|||
import './index.scss';
|
||||
|
||||
interface Props {
|
||||
showNotification: TShowNotification;
|
||||
wallet: IFullWallet;
|
||||
unlocked: boolean;
|
||||
showNotification: TShowNotification;
|
||||
resetWallet: TResetWallet;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -33,6 +35,10 @@ const messagePlaceholder =
|
|||
export class SignMessage extends Component<Props, State> {
|
||||
public state: State = initialState;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.props.resetWallet();
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { wallet, unlocked } = this.props;
|
||||
const { message, signedMessage } = this.state;
|
||||
|
@ -44,8 +50,16 @@ export class SignMessage extends Component<Props, State> {
|
|||
|
||||
return (
|
||||
<div>
|
||||
{unlocked ? (
|
||||
<div className="Tab-content-pane">
|
||||
<h4>{translate('MSG_message')}</h4>
|
||||
<h3 className="SignMessage-label">{translate('MSG_message')}</h3>
|
||||
<button
|
||||
className="SignMessage-reset btn btn-default btn-sm"
|
||||
onClick={this.changeWallet}
|
||||
>
|
||||
<i className="fa fa-refresh" />
|
||||
{translate('Change Wallet')}
|
||||
</button>
|
||||
<div className="form-group">
|
||||
<textarea
|
||||
className={messageBoxClass}
|
||||
|
@ -56,15 +70,12 @@ export class SignMessage extends Component<Props, State> {
|
|||
<div className="SignMessage-help">{translate('MSG_info2')}</div>
|
||||
</div>
|
||||
|
||||
{unlocked && (
|
||||
<SignButton
|
||||
wallet={wallet}
|
||||
message={this.state.message}
|
||||
showNotification={this.props.showNotification}
|
||||
onSignMessage={this.onSignMessage}
|
||||
/>
|
||||
)}
|
||||
<WalletDecrypt hidden={unlocked} disabledWallets={['trezor']} />
|
||||
|
||||
{!!signedMessage && (
|
||||
<div>
|
||||
|
@ -80,6 +91,9 @@ export class SignMessage extends Component<Props, State> {
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<WalletDecrypt hidden={unlocked} disabledWallets={DISABLE_WALLETS.UNABLE_TO_SIGN} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -92,6 +106,10 @@ export class SignMessage extends Component<Props, State> {
|
|||
private onSignMessage = (signedMessage: ISignedMessage) => {
|
||||
this.setState({ signedMessage });
|
||||
};
|
||||
|
||||
private changeWallet = () => {
|
||||
this.props.resetWallet();
|
||||
};
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: AppState) => ({
|
||||
|
@ -99,4 +117,7 @@ const mapStateToProps = (state: AppState) => ({
|
|||
unlocked: isWalletFullyUnlocked(state)
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { showNotification })(SignMessage);
|
||||
export default connect(mapStateToProps, {
|
||||
showNotification,
|
||||
resetWallet
|
||||
})(SignMessage);
|
||||
|
|
|
@ -69,3 +69,30 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin triangle($size, $color, $direction) {
|
||||
height: 0;
|
||||
width: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
border-width: $size / 2;
|
||||
|
||||
@if $direction == up {
|
||||
border-bottom-color: $color;
|
||||
} @else if $direction == right {
|
||||
border-left-color: $color;
|
||||
} @else if $direction == down {
|
||||
border-top-color: $color;
|
||||
} @else if $direction == left {
|
||||
border-right-color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin show-tooltip-on-hover {
|
||||
&:hover .Tooltip {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translate(-50%, -100%) translateY(-8px);
|
||||
transition-delay: 400ms, 400ms, 300ms;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
$zindex-navbar: 1000;
|
||||
$zindex-dropdown: 1000;
|
||||
$zindex-popover: 1060;
|
||||
$zindex-tooltip: 1070;
|
||||
$zindex-navbar-fixed: 1030;
|
||||
$zindex-modal-background: 1040;
|
||||
$zindex-modal: 1050;
|
||||
$zindex-alerts: 1060;
|
||||
$zindex-popover: 1060;
|
||||
$zindex-tooltip: 1070;
|
||||
|
||||
$zindex-top: 10000;
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "JSON File (unencrypted) ",
|
||||
"x_JsonDesc": "This is the unencrypted, JSON format of your private key. This means you do not need the password but anyone who finds your JSON can access your wallet & Ether without the password. ",
|
||||
"x_Keystore": "Keystore File (UTC / JSON · Recommended · Encrypted) ",
|
||||
"x_Keystore2": "Keystore File (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore File ",
|
||||
"x_KeystoreDesc": "This Keystore file matches the format used by Mist so you can easily import it in the future. It is the recommended file to download and back up. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "JSON-Datei (unverschlüsselt) ",
|
||||
"x_JsonDesc": "Dies ist die unverschlüsselte Version deines privaten Schlüssels im JSON-Format. Du benötigst daher kein Passwort, aber jeder, der über diese JSON-Datei verfügt, hat ohne Passwort Zugang zu deinem Wallet und dem darin enthaltenen Ether. ",
|
||||
"x_Keystore": "Keystore File (UTC / JSON · Empfohlen · Verschlüsselt) ",
|
||||
"x_Keystore2": "Keystore File (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore File ",
|
||||
"x_KeystoreDesc": "Diese Keystore-Datei passt zu dem Format, das von Mist verwendet wird, sodass du diese Datei dort zukünftig einfach importieren kannst. Es ist empfehlenswert, diese Datei herunterzuladen und zu sichern. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
@ -282,7 +282,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "Mehrere Adressen ",
|
||||
"MNEM_prev": "Letzte Adressen ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Verbinde deinen Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Öffne das Ethereum Programm (oder ein Vertragsprogramm) ",
|
||||
"ADD_Ledger_3": "Gehe sicher, dass Browser Support aktiviert ist. ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "Αρχείο JSON (μη κρυπτογραφημένο) ",
|
||||
"x_JsonDesc": "Αυτή είναι η μη κρυπτογραφημένη, JSON μορφή του ιδιωτικού κλειδιού σας. Αυτό σημαίνει ότι δεν απαιτείται συνθηματικό όμως οποιοσδήποτε βρει το JSON σας έχει πρόσβαση στο πορτοφόλι και στον αιθέρα σας χωρίς συνθηματικό. ",
|
||||
"x_Keystore": "Αρχείο Keystore (UTC / JSON · Συνιστάται · Κρυπτογραφημένο) ",
|
||||
"x_Keystore2": "Αρχείο Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "Αρχείο Keystore ",
|
||||
"x_KeystoreDesc": "Αυτό το αρχείο Keystore έχει την ίδια μορφή που χρησιμοποιείται από το Mist ώστε να μπορείτε εύκολα να το εισάγετε στο μέλλον. Είναι το συνιστώμενο αρχείο για λήψη και δημιουργία αντιγράφου ασφαλείας. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Μνημονικό ",
|
||||
|
@ -283,7 +283,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "Περισσότερες διευθύνσεις ",
|
||||
"MNEM_prev": "Προηγούμενες διευθύνσεις ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Συνδέστε το Ledger Wallet σας ",
|
||||
"ADD_Ledger_2": "Ανοίξτε την εφαρμογή Ethereum (ή μια εφαρμογή συμβολαίου) ",
|
||||
"ADD_Ledger_3": "Βεβαιωθείτε ότι η υποστήριξη περιηγητή είναι ενεργοποιημένη στις ρυθμίσεις ",
|
||||
|
|
|
@ -81,9 +81,11 @@
|
|||
"x_Json": "JSON File (unencrypted) ",
|
||||
"x_JsonDesc": "This is the unencrypted, JSON format of your private key. This means you do not need the password but anyone who finds your JSON can access your wallet & Ether without the password. ",
|
||||
"x_Keystore": "Keystore File (UTC / JSON · Recommended · Encrypted) ",
|
||||
"x_Keystore2": "Keystore File (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore File ",
|
||||
"x_KeystoreDesc": "This Keystore file matches the format used by Mist so you can easily import it in the future. It is the recommended file to download and back up. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_MetaMask": "MetaMask",
|
||||
"x_Mist": "Mist",
|
||||
"x_Web3": "Web3",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
"x_ParityPhrase": "Parity Phrase ",
|
||||
"x_Password": "Password ",
|
||||
|
@ -123,7 +125,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "More Addresses ",
|
||||
"MNEM_prev": "Previous Addresses ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Connect your Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open the Ethereum application (or a contract application) ",
|
||||
"ADD_Ledger_3": "Verify that Browser Support is enabled in Settings ",
|
||||
|
@ -161,6 +163,8 @@
|
|||
"ADD_Label_6_short": "Unlock ",
|
||||
"ADD_Label_7": "Add Account ",
|
||||
"ADD_Label_8": "Password (optional): ",
|
||||
"ADD_Web3Desc": "Connect & Sign via Your Browser or Extension",
|
||||
"ADD_HardwareDesc": "Connect & sign via your hardware wallet",
|
||||
"MYWAL_Nick": "Wallet Nickname ",
|
||||
"MYWAL_Address": "Wallet Address ",
|
||||
"MYWAL_Bal": "Balance ",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "Archivo JSON (sin encriptar) ",
|
||||
"x_JsonDesc": "Esta es tu clave privada sin encriptar en formato JSON. Esto significa que no necesitas una contraseña, pero cualquiera que encuentre tu archivo JSON puede acceder a tu cartera y ether sin necesitar ninguna contraseña. ",
|
||||
"x_Keystore": "Archivo Keystore (UTC / JSON · Recomendado · Encriptado) ",
|
||||
"x_Keystore2": "Archivo Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "Archivo Keystore ",
|
||||
"x_KeystoreDesc": "Este archivo Keystore/JSON concuerda con el formato usado por Mist para una fácil importación en el futuro. Es el archivo recomendado para descargar y guardar como copia de seguridad. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
@ -282,7 +282,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "Más direcciones ",
|
||||
"MNEM_prev": "Direcciones anteriores ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Conecta tu Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Inicia la aplicacin Ethereum (o una aplicación de contrato) ",
|
||||
"ADD_Ledger_3": "Comprueba que \"Browser Support\" está activado en \"Settings\" ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "JSON Tiedosto (salaamaton) ",
|
||||
"x_JsonDesc": "Tämä on salaamaton JSON tiedosto yksityisestä salausavaimestasi. Tämä tarkoittaa että et tarvitse salasanaa mutta kuka tahansa joka löytää JSON tiedostosi saa pääsyn lompakkoosi ja sen sisältämään Etheriin ilman salasanaa. ",
|
||||
"x_Keystore": "Avainsäilö Tiedosto (UTC / JSON · Suositeltu · Salattu) ",
|
||||
"x_Keystore2": "Avainsäilö Tiedosto (UTC / JSON) ",
|
||||
"x_Keystore2": "Avainsäilö Tiedosto ",
|
||||
"x_KeystoreDesc": "Tämä Avainsäilö tiedosto vastaa sitä tiedostoformaattia jota Mist käyttävät, joten voit helposti importata sen tulevaisuudessa. Se on suositeltu tiedostomuoto ladata ja varmuuskopioida. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
@ -283,7 +283,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "More Addresses ",
|
||||
"MNEM_prev": "Previous Addresses ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Connect your Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open the Ethereum application (or a contract application) ",
|
||||
"ADD_Ledger_3": "Verify that Browser Support is enabled in Settings ",
|
||||
|
|
|
@ -81,9 +81,9 @@
|
|||
"x_Json": "Fichier JSON (non-chiffré) ",
|
||||
"x_JsonDesc": "C'est la version non-chiffrée au format JSON de votre clé privée. Cela signifie que vous n'avez pas besoin de votre mot de passe pour l'utiliser mais que toute personne qui trouve ce JSON peut accéder à votre portefeuille et vos Ether sans mot de passe. ",
|
||||
"x_Keystore": "Fichier Keystore (UTC / JSON · Recommandé · Chiffré) ",
|
||||
"x_Keystore2": "Fichier Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "Fichier Keystore ",
|
||||
"x_KeystoreDesc": "Ce fichier Keystore utilise le même format que celui que Mist, vous pouvez donc facilement l'importer plus tard dans ces logiciels. C'est le fichier que nous vous recommandons de télécharger et sauvegarder. ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Phrase mnémonique ",
|
||||
"x_ParityPhrase": "Phrase Parity ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "JSON File (unencrypted) ",
|
||||
"x_JsonDesc": "This is the unencrypted, JSON format of your private key. This means you do not need the password but anyone who finds your JSON can access your wallet & Ether without the password. ",
|
||||
"x_Keystore": "Keystore File (UTC / JSON · Recommended · Encrypted) ",
|
||||
"x_Keystore2": "Keystore File (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore File ",
|
||||
"x_KeystoreDesc": "This Keystore file matches the format used by Mist so you can easily import it in the future. It is the recommended file to download and back up. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
@ -124,7 +124,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "More Addresses ",
|
||||
"MNEM_prev": "Previous Addresses ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Connect your Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open the Ethereum application (or a contract application) ",
|
||||
"ADD_Ledger_3": "Verify that Browser Support is enabled in Settings ",
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
"x_Json": "JSON Fájl (titkosítatlan) ",
|
||||
"x_JsonDesc": "Ez a titkosítotatlan, JSON formátumú változata a privát kulcsodnak. Ez azt jelenti, hogy nincs szükség jelszóra az eléréséhez, viszont ha bárki megtalálja a JSON fájlt, akkor hozzáférhet a tárcádhoz és az Etheredhez a jelszó ismerete nélkül. ",
|
||||
"x_Keystore": "Keystore Fájl (UTC / JSON · Ajánlott · Titkosított) ",
|
||||
"x_Keystore2": "Keystore Fájl (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore Fájl ",
|
||||
"x_KeystoreDesc": "Ez a Keystore fájl ugyanolyan formátumú, amit a Mist használ, tehát könnyedén importálhatod a későbbiekben. Leginkább ezt a fájlt ajánlott letölteni és elmenteni. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonikus frázis ",
|
||||
|
@ -283,7 +283,7 @@
|
|||
"MSG_info1": "Include the current date so the signature cannot be reused on a different date. ",
|
||||
"MSG_info2": "Include your nickname and where you use the nickname so someone else cannot use it. ",
|
||||
"MSG_info3": "Include a specific reason for the message so it cannot be reused for a different purpose. ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_scan": "Csatlakozás a Ledger Wallet-hez ",
|
||||
"ADD_Ledger_1": "Csatlakoztasd a Ledger Wallet-et ",
|
||||
"ADD_Ledger_2": "Nyisd meg az Ethereum applikációt (vagy egy kontraktus applikációt) ",
|
||||
|
|
|
@ -82,9 +82,9 @@
|
|||
"x_Json": "File JSON (tidak ter-enkripsi) ",
|
||||
"x_JsonDesc": "Ini adalah \"Private Key\" Anda dalam format JSON yang tidak ter-enkripsi. Tidak diperlukan password dan siapapun yang memiliki JSON Anda dapat mengakses dompet dan Ether Anda tanpa password. ",
|
||||
"x_Keystore": "File Keystore (UTC / JSON · Format yang direkomendasikan · Ter-enkripsi) ",
|
||||
"x_Keystore2": "File Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "File Keystore ",
|
||||
"x_KeystoreDesc": "File Keystore ini sesuai dengan format yang dipakai Mist sehingga memudahkan untuk diimpor di kemudian hari. File ini yang disarankan untuk di unduh dan di backup. ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "\"Mnemonic Phrase\" ",
|
||||
"x_ParityPhrase": "Parity Phrase ",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "File JSON (non crittografato) ",
|
||||
"x_JsonDesc": "Questa è la tua chiave privata in formato JSON non crittografato. Significa che non hai bisogno della password, ma chiunque trovi questo file JSON potrà avere accesso al tuo portafoglio e ai tuoi ether senza password. ",
|
||||
"x_Keystore": "File Keystore (UTC / JSON · Consigliato · Crittografato) ",
|
||||
"x_Keystore2": "File Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "File Keystore ",
|
||||
"x_KeystoreDesc": "Questo file Keystore è compatibile con il formato usato da Mist, in modo da poterlo facilmente importare in futuro. È il file consigliato da scaricare e conservare. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Frase mnemonica ",
|
||||
|
@ -232,7 +232,7 @@
|
|||
"MNEM_2": "Con una singola frase mnemonica puoi avere accesso a un certo numero di portafogli / indirizzi. Seleziona l'indirizzo con il quale vuoi interagire in questo momento. ",
|
||||
"MNEM_more": "Altri indirizzi ",
|
||||
"MNEM_prev": "Indirizzi precedenti ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_0a": "Devi accedere a MyEtherWallet tramite una connessione sicura (SSL / HTTPS) per poterti collegare. ",
|
||||
"ADD_Ledger_0b": "Riapri MyEtherWallet utilizzando [Chrome](https://www.google.com/chrome/browser/desktop/) o [Opera](https://www.opera.com/) ",
|
||||
"ADD_Ledger_1": "Collega il tuo Ledger Wallet ",
|
||||
|
|
|
@ -82,9 +82,9 @@
|
|||
"x_Json": "JSON ファイル (未暗号化) ",
|
||||
"x_JsonDesc": "これはパスワードが不要な暗号化されていないJSONフォーマットの秘密鍵です。この暗号化されていないJSONフォーマットの秘密鍵を使えば、誰でもパスワードを使わずに自分のお財布とEtherにアクセスできます。 ",
|
||||
"x_Keystore": "Keystore ファイル (UTC / JSON · 推奨 · 暗号化) ",
|
||||
"x_Keystore2": "Keystore ファイル (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore ファイル ",
|
||||
"x_KeystoreDesc": "この Keystore / JSON ファイルは、後で容易にインポートするため、Mistで使われているフォーマットと一致させる必要があります。ダウンロードしてバックアップを取ることをおすすめします。 ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "ニーモニック文節 ",
|
||||
"x_ParityPhrase": "パリティ文節 ",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "JSON 파일 (암호화되지 않음) ",
|
||||
"x_JsonDesc": "이것은 암호화되지 않은 JSON 형식의 개인 키입니다. 이 암호화되지 않은 JSON 형식의 개인 키를 사용하면 누구나 암호없이 자신의 지갑과 이더리움에 액세스 할 수 있습니다. ",
|
||||
"x_Keystore": "Keystore 파일 (UTC / JSON · 권장 · 암호화됨) ",
|
||||
"x_Keystore2": "Keystore 파일 (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore 파일 ",
|
||||
"x_KeystoreDesc": "이 Keystore / JSON 파일은 Mist에서 사용하는 형식과 일치하므로 나중에 쉽게 가져올 수 있습니다. 다운로드하고 백업하는 것을 권장합니다. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic 문구 ",
|
||||
|
@ -123,7 +123,7 @@
|
|||
"MNEM_2": "하나의 HD Mnemonic 문구에서 여러 가지 지갑/주소를 액세스할 수 있습니다. 액세스하려는 주소를 선택해주세요. ",
|
||||
"MNEM_more": "나머지 주소 ",
|
||||
"MNEM_prev": "이전 주소 ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "사용자의 Ledger Wallet를 연결해주세요 ",
|
||||
"ADD_Ledger_2": "이더리움 어플리케이션을 실행해주세요 (또는 컨트랙트 어플리케이션) ",
|
||||
"ADD_Ledger_3": "Browser Support가 활성화된 상태인지 확인해주세요 ",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "JSON Bestand (onversleuteld) ",
|
||||
"x_JsonDesc": "Dit is het onversleutelde, JSON formaat van je prive sleutel (\"Private Key\"). Dit betekend dat je het wachtwoord niet nodig hebt, maar ook dat een ieder die je JSON bestand vind toegang heeft tot je wallet & Ether zonder wachtwoord. ",
|
||||
"x_Keystore": "Keystore Bestand (UTC / JSON · Aangeraden · versleuteld) ",
|
||||
"x_Keystore2": "Keystore Bestand (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore Bestand ",
|
||||
"x_KeystoreDesc": "Dit Keystore bestand voldoet aan het formaat zoals gebruikt door Mist waardoor je het gemakkelijk kunt importeren in de toekomst. Dit is de aanbevolen methode voor download en back up. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Zin ",
|
||||
|
@ -123,7 +123,7 @@
|
|||
"MNEM_2": "Met jouw enkele HD mnemonic zin heb je toegang tot meerdere wallets / adressen. Selecteer het adres waarmee je nu wilt communiceren. ",
|
||||
"MNEM_more": "Meer Adressen ",
|
||||
"MNEM_prev": "Vorige Adressen ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Verbind je Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open de Ethereum applicatie (of een contract applicatie) ",
|
||||
"ADD_Ledger_3": "Controleer of \"Browser Support\" is ingeschakeld in je instellingen ",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "JSON-fil (ukryptert) ",
|
||||
"x_JsonDesc": "Dette er det ukrypterte JSON-formatet av din private nøkkel. Dette betyr at du ikke trenger noe passord, men også at den som finner din JSON kan få tilgang til lommeboken din og etherne dine uten passord. ",
|
||||
"x_Keystore": "Keystore-fil (UTC / JSON · Anbefalt · Kryptert) ",
|
||||
"x_Keystore2": "Keystore-fil (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore-fil ",
|
||||
"x_KeystoreDesc": "Denne Keystore-filen samsvarer med formatet som brukes av Mist, så du enkelt kan importere den i fremtiden. Det er den anbefalte filen å laste ned og sikkerhetskopiere. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonisk Frase ",
|
||||
|
@ -142,7 +142,7 @@
|
|||
"ADD_Label_6_short": "Lås opp ",
|
||||
"ADD_Label_7": "Legg til konto ",
|
||||
"ADD_Label_8": "Password (optional): ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Koble til din Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Åpne Ethereum-applikasjonen (eller kontraktsapplikasjonen) ",
|
||||
"ADD_Ledger_3": "Sjekk at nettleserstøtte er aktivert i innstillingene. ",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "Plik JSON (nieszyfrowany) ",
|
||||
"x_JsonDesc": "Nieszyfrowany klucz prywatny, plik w formacie JSON. Nie wymaga podania hasła, ale każdy kto zdobędzie ten plik uzyska również pełny dostęp do Twojego portfela i zgromadzonych na nim środków. ",
|
||||
"x_Keystore": "Plik Keystore (UTC / JSON · Zalecany · Szyfrowany) ",
|
||||
"x_Keystore2": "Plik Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "Plik Keystore ",
|
||||
"x_KeystoreDesc": "Ten plik Keystore odpowiada formatowi stosowanemu przez Mist, więc może być w prosty sposób zaimportowany w przyszłości. Jest to zalecana forma pliku do pobrania i przechowywania jako kopii zapasowej. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonik ",
|
||||
|
@ -246,7 +246,7 @@
|
|||
"MNEM_2": "Jedna grupa słów mnemonicznych ma dostęp do wielu portfeli / adresów. Wybierz adres, do którego chcesz uzyskać dostęp tym razem. ",
|
||||
"MNEM_more": "Więcej Adresów ",
|
||||
"MNEM_prev": "Poprzednie Adresy ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Podłącz swój Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Otwórz aplikację Ethereum (lub aplikację kontraktu) ",
|
||||
"ADD_Ledger_3": "Sprawdź czy opcja Obsługa Przeglądarki jest włączona w Ustawieniach ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "Arquivo JSON (não criptografada) ",
|
||||
"x_JsonDesc": "Este é o descriptografado, formato JSON da sua chave privada. Isto significa que você não precisa da senha, mas qualquer um que encontrar o seu JSON pode acessar sua carteira & Éter sem a senha. ",
|
||||
"x_Keystore": "Arquivo de armazenamento de chaves (UTC / JSON · Recomendado · Criptografado) ",
|
||||
"x_Keystore2": "Arquivo de armazenamento de chaves (UTC / JSON) ",
|
||||
"x_Keystore2": "Arquivo de armazenamento de chaves ",
|
||||
"x_KeystoreDesc": "Este arquivo de armazenamento de chaves corresponde ao formato usado pela Mist para que você possa facilmente importá-lo no futuro. É recomendado que o arquivo seja transferido e feito seu backup. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Frase Mnemonic ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "Файл JSON (не зашифрован) ",
|
||||
"x_JsonDesc": "Это Ваш незашифрованный закрытый ключ в формате JSON, для использования которого не требуется воодить пароль. Любой, у кого есть этот файл, может распоряжаться вашим кошельком и эфиром (ether) без ввода пароля. ",
|
||||
"x_Keystore": "Файл Keystore (UTC / JSON · рекомендуется · зашифрован) ",
|
||||
"x_Keystore2": "Файл Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "Файл Keystore ",
|
||||
"x_KeystoreDesc": "Этот файл Keystore использует формат совместимый с Mist. Вы сможете в будущем импортировать его. Рекомендуется скачать этот файл и сделать резервную копию. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Кодовая фраза ",
|
||||
|
@ -284,7 +284,7 @@
|
|||
"TOKEN_show": "Отправить все токены ",
|
||||
"TRANS_gas": "Лимит газа ",
|
||||
"WARN_Send_Link": "Вы попали сюда по ссылке, которая уже содержит в себе адрес, сумму, лимит газа и дополнительные параметры транзакции. ВЫ можете изменить эти данные перед отправкой транзакции. Для начала отоприте ваш кошелёк. ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Присоедините ваш Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Запустите приложение Ethereum (или приложение контракта) ",
|
||||
"ADD_Ledger_3": "Убедитесь, что использование из браузера разрешено в настройках ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "JSON Súbor (nezašifrovaný) ",
|
||||
"x_JsonDesc": "Toto je nezašifrovaný JSON format vášho sukromného kľúča. To znamená, že nepotrebujete heslo, ale ak niekto získa váš JSON, je schopný sprístupniť vašu peňaženku a Ether bez hesla. ",
|
||||
"x_Keystore": "Keystore Súbor (UTC / JSON · Odporúčané · Šifrované) ",
|
||||
"x_Keystore2": "Keystore Súbor (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore Súbor ",
|
||||
"x_KeystoreDesc": "Tento Keystore súbor je rovnakého formatu ako Mist takže ho budete môcť jednoducho importovať. Tento subor odporúčame stiahnuť a zálohovať. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase (MetaMask / Jaxx ) ",
|
||||
|
@ -236,7 +236,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "More Addresses ",
|
||||
"MNEM_prev": "Previous Addresses ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Connect your Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open the Ethereum application (or a contract application) ",
|
||||
"ADD_Ledger_3": "Verify that Browser Support is enabled in Settings ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "JSON Datoteka (nekriptirana) ",
|
||||
"x_JsonDesc": "To je nekriptirana, JSON datoteka vašega osebnega ključa. To pomeni, da za uporabo ne potrebujete gesla. V primeru da kdorkoli najde datoteko vašega ključa, dobi takojšen dostop do vaše denarnice in vašega Ethra brez uporabe gesla. ",
|
||||
"x_Keystore": "Datoteka za Shrambo ključa Keystore (UTC / JSON · Priporočeno · Kriptirano) ",
|
||||
"x_Keystore2": "Datoteka za Shrambo ključa Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "Datoteka za Shrambo ključa Keystore ",
|
||||
"x_KeystoreDesc": "Ta datoteka za shrambo osebnega ključa Keystore se ujema s formatom datoteke, ki jo uporabljata programa Mist, kar pomeni da ga lahko v prihodnosti enostavno izvozite iz te internetne strani in uvozite v Mist ali Geth. Priporočamo vam da to datoteko prenesete na vaš računalnik in jo shranite na varnem mestu. Za dodatno varnost priporočamo, da datoteko shranite na večih napravah. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
@ -146,7 +146,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "More Addresses ",
|
||||
"MNEM_prev": "Previous Addresses ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Connect your Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open the Ethereum application (or a contract application) ",
|
||||
"ADD_Ledger_3": "Verify that Browser Support is enabled in Settings ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "JSON Fil (okrypterad) ",
|
||||
"x_JsonDesc": "Det här är din okrypterade privata nyckel i JSON format. Det här betyder att du inte behöver ditt lösenord men vem som helst som hittar din JSON kan få tillgång till din plånbok och Ether utan ditt lösenord. ",
|
||||
"x_Keystore": "Keystore Fil (UTC / JSON · Rekomenderad · Krypterad) ",
|
||||
"x_Keystore2": "Keystore Fil (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore Fil ",
|
||||
"x_KeystoreDesc": "Den här Keystore filen matchar formatet som används av Mist så du kan enkelt importera det i framtiden. Det är det rekommenderade format att hämta för backup. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
@ -124,7 +124,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "More Addresses ",
|
||||
"MNEM_prev": "Previous Addresses ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Connect your Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open the Ethereum application (or a contract application) ",
|
||||
"ADD_Ledger_3": "Verify that Browser Support is enabled in Settings ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "JSON dosya (şifrelenmemis) ",
|
||||
"x_JsonDesc": "Bu özel anahtarinin sifresiz, JSON formatidir. Demekki parolasiz cüzdanini acabilirsin. Özel anahatarina sahip olan herkez sifresiz cüzdani aca bilir. ",
|
||||
"x_Keystore": "Keystore dosya (UTC / JSON · Tavsiye edilen · şifrelenmiş) ",
|
||||
"x_Keystore2": "Keystore dosya (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore dosya ",
|
||||
"x_KeystoreDesc": "This Keystore file matches the format used by Mist so you can easily import it in the future. It is the recommended file to download and back up. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
@ -276,7 +276,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "Daha Fazla Adres ",
|
||||
"MNEM_prev": "Önceki Adresler ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Connect your Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open the Ethereum application (or a contract application) ",
|
||||
"ADD_Ledger_3": "Verify that Browser Support is enabled in Settings ",
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
"x_Json": "Định Dạng JSON (Không mã hoá) ",
|
||||
"x_JsonDesc": "Định Dạng JSON là một tập tin chứa dữ liệu ví chưa được mã hoá của Private Key. Bạn có thể đăng nhập vào ví của bạn bằng việc sử dụng định dạng JSON mà không cần đến mật khẩu. Vì vậy, bất kỳ người nào sở hữu định dạng JSON của bạn thì họ đều có khả năng đăng nhập vào ví của bạn mà không cần đến mật khẩu. ",
|
||||
"x_Keystore": "Định Dạng Keystore (UTC / JSON) (Đã mã hoá. Định Dạng này sử dụng cho Mist) ",
|
||||
"x_Keystore2": "Định Dạng Keystore (UTC / JSON) ",
|
||||
"x_Keystore2": "Định Dạng Keystore ",
|
||||
"x_KeystoreDesc": "Định dạng Keystore là tập một tin chứa dữ liệu ví đã được mã hoá của Private Key và sử dụng cho Mist. Do đó bạn có thể dễ dàng bỏ nó vào bên trong Mist và tiếp tục sử dụng ví của bạn. Đây là một tập tin được đề xuất nhằm sao lưu dữ liệu ví cá nhân. ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Cụm từ dễ nhớ ",
|
||||
|
@ -255,7 +255,7 @@
|
|||
"x_Trezor": "TREZOR ",
|
||||
"ADD_Trezor_scan": "Connect to TREZOR ",
|
||||
"ADD_Trezor_select": "This is a TREZOR seed ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Kết Nối Với Ledger Wallet Của Bạn ",
|
||||
"ADD_Ledger_2": "Mở Lên Ứng Dụng Của Ethereum (Hoặc một ứng dụng của Hợp Đồng) ",
|
||||
"ADD_Ledger_3": "Xác nhận lại phần Hổ Trợ dành cho Trình Duyệt đã được kích hoạt trong mục Cài Đặt ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "JSON文件(未加密) ",
|
||||
"x_JsonDesc": "这是你的未加密JSON格式的私钥文件。 这意味着你发送交易时不需要密码,也意味着拿到你的JSON文件的可以无需密码就可以控制你的钱包和以太币。 ",
|
||||
"x_Keystore": "Keystore File (UTC / JSON · 推荐加密的) ",
|
||||
"x_Keystore2": "Keystore File (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore File ",
|
||||
"x_KeystoreDesc": "这个Keystore/JSON文件和Mist、Geth使用的钱包文件是一样的,所以将来你可以非常容易地导入。 It is the recommended file to download and back up.推荐下载和备份这个文件。 ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "Mnemonic Phrase ",
|
||||
|
@ -283,7 +283,7 @@
|
|||
"MNEM_2": "Your single HD mnemonic phrase can access a number of wallets / addresses. Please select the address you would like to interact with at this time. ",
|
||||
"MNEM_more": "More Addresses ",
|
||||
"MNEM_prev": "Previous Addresses ",
|
||||
"x_Ledger": "Ledger Wallet ",
|
||||
"x_Ledger": "Ledger ",
|
||||
"ADD_Ledger_1": "Connect your Ledger Wallet ",
|
||||
"ADD_Ledger_2": "Open the Ethereum application (or a contract application) ",
|
||||
"ADD_Ledger_3": "Verify that Browser Support is enabled in Settings ",
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"x_Json": "JSON 檔 (未加密) ",
|
||||
"x_JsonDesc": "這是未加密的JSON格式私鑰檔。這表示你不需要密碼就可以控制錢包,但任何持有此JSON文件的人也都無須密碼便能控制你的錢包和乙太幣。 ",
|
||||
"x_Keystore": "Keystore 檔 (UTC / JSON · 推薦 · 經過加密) ",
|
||||
"x_Keystore2": "Keystore 檔 (UTC / JSON) ",
|
||||
"x_Keystore2": "Keystore 檔 ",
|
||||
"x_KeystoreDesc": "此Keystore檔和Mist錢包相容,因此你可以輕鬆地匯入錢包。我們推薦你下載並備份此檔案。 ",
|
||||
"x_MetaMask": "Metamask / Mist ",
|
||||
"x_Mnemonic": "助憶口令 ",
|
||||
|
|
|
@ -140,8 +140,7 @@
|
|||
"tscheck": "tsc --noEmit",
|
||||
"start": "npm run dev",
|
||||
"precommit": "lint-staged",
|
||||
"formatAll":
|
||||
"find ./common/ -name '*.ts*' | xargs prettier --write --config ./.prettierrc --config-precedence file-override",
|
||||
"formatAll": "find ./common/ -name '*.ts*' | xargs prettier --write --config ./.prettierrc --config-precedence file-override",
|
||||
"prepush": "npm run tslint && npm run tscheck"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
Loading…
Reference in New Issue