Compare commits

...

156 Commits

Author SHA1 Message Date
James Prado 816ce3180f Translation Updates (#1323)
* Update account view routing

* Temporarily add unicode character to translated strings for testing

* Temporarily select add unicode to all untranslated strings

* Format changes

* Add all english translations for /account & /generate

* Add the rest of the english translations

* Add a few more missing translations

* Update en translations

* Get selectedLanguage from localstorage instead of redux sttate

* Update snapshots

* Add missing translation keys & Update translate functs & change variable prefix

* translate all markdown strings & remove old translation strings

* Update snapshot

* Add a few more translation strs

* Move raw strings being translated into json

* All translation keys are now Uppercase

* Fix up the last few translations

* Update snapshot

* Uppercase de translation strings

* Bring back shapeshift logo on swap

* Fix contracts tab translations

* Fix a few more translations

* Fix translations

* remove debugging stuff

* Update snapshots

* Use react.fragment as markdown root renderer

* Seperate markdown translations into their own function

* Clean up translation functions

* Clean up translation functions

* Update snapshot

* Fix some broken translation strings

* Add prettier ignore file
2018-03-21 22:50:25 -05:00
William O'Beirne 7521337bda Custom DPaths, Improvements, and Fix SingularDTV (#1351)
* Add dpath to select option display

* Re-enable custom path

* Make it a submittable form to behave better with HW wallets

* Adjust styles

* Widen regex to allow for SingularDTV dpath
2018-03-21 15:19:15 -05:00
greenkeeper[bot] f42b81ac8a fix(package): update electron-updater to version 2.21.1 (#1338) 2018-03-21 14:45:05 -05:00
greenkeeper[bot] aa08c1902d chore(package): update ts-jest to version 22.4.2 (#1339) 2018-03-21 14:08:54 -05:00
Michael - Blurpesec 8eeefe7e25 Fix offline broadcast link (#1350)
* Fixed offline broadcast link

* fix for link from root
2018-03-21 13:49:33 -05:00
William O'Beirne 5d41a7f774 Remove all LESS code (#1348)
* Checking in removal process.

* Final removal of all SCSS

* Remove unnecessary test

* tscheck
2018-03-20 15:08:57 -05:00
William O'Beirne 0b44919912 Update node-sass (#1346) 2018-03-20 11:00:49 -05:00
Danny Skubak 937cc3fde5 Add Jenkins Integration (#1295)
* add jenkins changes

* run prettier

* update icons

* update icons to use latest favicon
2018-03-19 10:42:42 -05:00
Danny Skubak 9be46bf8aa Update blockie package in webpack config (#1337) 2018-03-17 23:52:47 -05:00
Daniel Ternyak f5716514b1
chore(package): update node-sass to version 4.8.1 (#1315)
Closes #1310
2018-03-17 19:48:37 -05:00
Daniel Ternyak 8c0dd3f455
Use ethereum-blockies-base64 (#1326)
* use makeBlockie from ethereum-blockies-base64

* adjust type ethereum-blockies-base64 type declaration

* add ethereum-blockies-base64

* update ethereum-blockies-base64; remove redundent declaration file
2018-03-17 16:31:28 -05:00
Daniel Ternyak 825e467db7
fix(package): update query-string to version 6.0.0 (#1325)
Closes #1322
2018-03-17 00:52:04 -05:00
greenkeeper[bot] 9e723e609c chore(package): update css-loader to version 0.28.11 (#1331) 2018-03-17 00:14:58 -05:00
greenkeeper[bot] be9729c302 chore(package): update @types/react-router-dom to version 4.2.5 (#1328) 2018-03-17 00:14:14 -05:00
greenkeeper[bot] 9a5e2a8c2a chore(package): update electron-builder to version 20.5.1 (#1324) 2018-03-17 00:13:57 -05:00
greenkeeper[bot] 0976552a0b chore(package): update @types/lodash to version 4.14.105 (#1327) 2018-03-17 00:13:17 -05:00
greenkeeper[bot] bd4a63e591 chore(package): update @types/react-select to version 1.2.5 (#1329) 2018-03-17 00:12:56 -05:00
greenkeeper[bot] aeb1b74d8d chore(package): update webpack-subresource-integrity to version 1.1.0-rc.4 (#1330) 2018-03-17 00:12:38 -05:00
greenkeeper[bot] 433a3276bb chore(package): update electron to version 1.8.4 (#1335) 2018-03-17 00:12:20 -05:00
greenkeeper[bot] 4b6cba3211 chore(package): update enzyme-to-json to version 3.3.3 (#1332) 2018-03-17 00:12:03 -05:00
William O'Beirne db6b737cad Show Recent Txs on Check Tx Page (#1147)
* Save transactions to local storage.

* Checksum more things + reset hash on network change.

* Fix IHexTransaction type, grab from from tx object directly.

* Refactor storage of recent transactions to use redux storage and loading.

* Refactor types to a transactions types file.

* Initial crack at recent transactions tab on account

* Punctuation.

* Transaction Status responsive behavior.

* Refactor transaction helper function out to remove circular dependency.

* Fix typings

* Collapse subtabs to select list when too small.

* s/wallet/address

* Type select onChange

* Get fields from current state if web3 tx
2018-03-14 15:10:14 -05:00
greenkeeper[bot] 740b191542 chore(package): update tslint-config-prettier to version 1.10.0 (#1316) 2018-03-14 14:53:11 -05:00
greenkeeper[bot] 0bc24f5825 chore(package): update nodemon to version 1.17.2 (#1320) 2018-03-14 14:52:57 -05:00
greenkeeper[bot] 92e757ceb2 chore(package): update image-webpack-loader to version 4.2.0 (#1319) 2018-03-14 14:52:02 -05:00
William O'Beirne 4b8adc81ce Allow 0 ETH Transactions (#1307)
* Allow zero number

* Fail when request payment is zero value, or if you try to send token with zero value.

* Parseint instead of addition casting to catch empty string.
2018-03-14 14:51:37 -05:00
anticlimactic 16469e1a62 Show Disabled Send Button on /pushtx (#1302)
* Fixes #1291. Implemented a new boolean that allows you to toggle whether you are using a disabled send tx button that persists or a send tx button that remains invisible until a valid transaction is present.

* Fixed object shorthand precommit error.

* Cleanup boolean logic, remove redundant code, make comparision elements more obvious
2018-03-12 00:06:09 -05:00
Daniel Ternyak 3d8f678887
chore(package): update electron-builder to version 20.4.0 (#1299)
Closes #1271
2018-03-11 18:09:31 -05:00
Daniel Ternyak 8649655019
Add HackerOne to Announcement (#1218) 2018-03-11 17:25:24 -05:00
greenkeeper[bot] 9284fb56eb chore(package): update @types/react-select to version 1.2.4 (#1301) 2018-03-11 17:24:35 -05:00
greenkeeper[bot] 7905b0cf67 chore(package): update less-loader to version 4.1.0 (#1304) 2018-03-11 17:24:20 -05:00
greenkeeper[bot] 3f6681711f chore(package): update style-loader to version 0.20.3 (#1305) 2018-03-11 17:23:31 -05:00
greenkeeper[bot] 7b7728cf9d chore(package): update copy-webpack-plugin to version 4.5.1 (#1306) 2018-03-11 17:23:15 -05:00
greenkeeper[bot] 033407460b fix(package): update wallet-address-validator to version 0.1.3 (#1303) 2018-03-11 17:22:38 -05:00
James Prado 4788381641 Update Account SubTab Routing / Token Scanner CSS Updates (#1276)
* Redirect user to subtab after logging in

* Update token balances styles

* Adjust routing for readOnly wallets
2018-03-11 17:19:35 -05:00
William O'Beirne 56943232a0 Roll Back enzyme-to-json Revoked Version (#1308) 2018-03-09 18:34:08 -06:00
greenkeeper[bot] aa287f478a chore(package): update electron to version 1.8.3 (#1266) 2018-03-08 13:29:09 -06:00
James Prado 9cac0298a2 Improve accessibility (a11y) (#1267)
* Manage modal focus

* Add isOpen prop to CustomNodeModal

* Remove outline overrides

* Update outline style for inputs

* Fix modal focus management & Cleanup CustomNodeModal

* Add aria-label on modal close button

* Fix modal scroll to top

* Add aria-live property for notifications

* Add aria-busy to Spinner component

* Fix border styles for generatewallet password inputs

* Update token balances inputs

* Remove multiple h1's & Update styles

* Add alt text to all img elements

* Update swap link from bity to shapeshift

* Update aria-labels and alt text

* Only show keystore password input when required

* Revert "Only show keystore password input when required"

This reverts commit 7ec5de52da0982cd3131f365b142f6915638d831.

* address changes requested
2018-03-08 13:28:43 -06:00
greenkeeper[bot] 6e8d807b22 fix(package): update react-markdown to version 3.3.0 (#1272) 2018-03-08 12:06:06 -06:00
greenkeeper[bot] 80383a831e fix(package): update ethereumjs-tx to version 1.3.4 (#1283) 2018-03-08 12:05:29 -06:00
greenkeeper[bot] 5e97a9fe66 chore(package): update url-search-params-polyfill to version 3.0.0 (#1296) 2018-03-08 12:04:58 -06:00
greenkeeper[bot] 3af6607901 chore(package): update enzyme-to-json to version 3.3.2 (#1297) 2018-03-08 12:04:20 -06:00
aitrean cf9887f21f Outstanding tasks to Productionize Tx (#1194)
* Verify and complete all branching saga logic tests for transaction stack.

* Write reducer tests for refactored transaction stack.

* Add selector tests. Some files still need to be debugged.

* Add snapshot test for fields, additional seelector testing.

* Remove fields snapshots.

* Remove ABIs from the TestState json

* Use redux state instead of raw json in selector testing.

* Fix merge issues.

* Remove log

* Fix state values.

* Change test value to wei.

* Last touchup.

* Fix buffer shape, change Wei typo, use reasonable wei values.

* Last touch up.
2018-03-08 12:03:45 -06:00
HenryNguyen5 94b3f3403b Fix recommended gas price breaking on subtab switch (#1268) 2018-03-07 17:55:46 -06:00
HenryNguyen5 16e6677c0f Derive available tx metadata (#1257)
* Derive "from" and "unit" parameters from current transaction when possible

* Fix tsc errors

* Address changes
2018-03-07 17:42:16 -06:00
William O'Beirne 3bce82ba86 Fix favicon transparency. (#1289) 2018-03-07 17:37:59 -06:00
HenryNguyen5 c340246ca0 Enable no-implicit-any (#1263)
* Progress commit

* Update more types

* Fix more types

* Fix abi function types

* Fix lib types

* Fix rest of types

* Address wbobeirne changes

* Change origin and destination check
2018-03-07 17:36:05 -06:00
Daniel Ternyak 0e26f7af4c
Tag Beta 0.5.1 (#1287) 2018-03-07 10:55:29 -06:00
Daniel Ternyak 3278318fa6
Fix Coinbase Widget (#1286)
* Connect Promos; pass current wallet address to Coinbase

* Use ShapeShift as promo if no wallet instance when showing Coinbase

* use appstate for typing
2018-03-07 10:54:14 -06:00
greenkeeper[bot] b901c3e125 chore(package): update @types/jest to version 22.2.0 (#1261) 2018-03-05 23:52:43 -06:00
Daniel Ternyak 8acef8e54f
Revert hard-source-webpack-plugin updates (#1269)
* Revert "fix(package): update hard-source-webpack-plugin to version 0.6.4 (#1254)"

This reverts commit e45324e7f1.

* Revert "fix(package): update hard-source-webpack-plugin to version 0.6.1 (#1232)"

This reverts commit b016d35819.
2018-03-05 23:52:20 -06:00
HenryNguyen5 2d057eb0b2 Fix swap timer (#1265) 2018-03-05 22:51:31 -06:00
William O'Beirne a5be81e96d Change swap link icon to ShapeShift logo. Get rid of new banner. (#1264) 2018-03-05 21:22:45 -06:00
Daniel Ternyak 0d4bc5bbb1
Tag Beta Release 0.5.0 (#1255) 2018-03-05 14:36:20 -06:00
greenkeeper[bot] 446d7043c3 chore(package): update resolve-url-loader to version 2.3.0 (#1243) 2018-03-05 13:52:27 -06:00
greenkeeper[bot] 3bdf41cf59 chore(package): update electron-builder to version 20.2.1 (#1250) 2018-03-05 13:51:45 -06:00
Taylor Monahan 7941403782 Copy / messaging tweaks (#1253)
* replace "don't have a wallet" with "account" for more consistency

* Update Copyright info in disclaimer model

* fix prettier issues
2018-03-05 13:51:06 -06:00
greenkeeper[bot] 533255094b fix(package): update electron-updater to version 2.21.0 (#1251) 2018-03-05 13:49:42 -06:00
William O'Beirne d0379b19a0 Fix Disclaimer Open on ESC (#1245)
* Don’t listen to escape while modal is closed.

* Remove console
2018-03-05 13:00:54 -06:00
Daniel Ternyak e45324e7f1
fix(package): update hard-source-webpack-plugin to version 0.6.4 (#1254)
Closes #1252
2018-03-05 12:59:09 -06:00
William O'Beirne 3a36818412 Add Check TX Button to Transaction Notification (#1217)
* Reinstates v3 behavior on transaction send:

* Alert shows Check TX Status button

* Check TX page uses txHash query param

* LogOutPrompt now carries over search params and hash

* Remove console log

* Update test.
2018-03-05 12:58:53 -06:00
William O'Beirne e3194a649e Fix Blurry Modals (#1246) 2018-03-05 12:52:35 -06:00
greenkeeper[bot] b016d35819 fix(package): update hard-source-webpack-plugin to version 0.6.1 (#1232) 2018-03-03 13:29:42 -06:00
Daniel Ternyak dd83071ec7
chore(package): update url-loader to version 1.0.1 (#1240)
Closes #1237
2018-03-03 13:27:27 -06:00
greenkeeper[bot] 383df967a7 chore(package): update sass-loader to version 6.0.7 (#1236) 2018-03-03 13:27:10 -06:00
greenkeeper[bot] 611e511b33 fix(package): update moment to version 2.21.0 (#1235) 2018-03-03 13:26:36 -06:00
Luit Hollander a9aeacb775 Fix Repo Link (#1239) 2018-03-03 13:12:45 -06:00
William O'Beirne 6927aa0b55 Prevent Scrolling From Altering Amount Field (#1234)
* Prevent scrolling to adjust number input.

* Blur instead, less annoying.
2018-03-03 13:11:05 -06:00
HenryNguyen5 4dd0fc9785 Fix contract interact (#1233)
* reduce unintended side effects from empty units

* Fix contract interaction "to" address being empty

* Fix tsc errors
2018-03-02 15:57:17 -06:00
greenkeeper[bot] 86992e8198 chore(package): update ts-jest to version 22.4.1 (#1231) 2018-03-02 11:19:04 -06:00
Daniel Ternyak 7c451ffd4f
Tag Beta Release 0.4.0 (#1225) 2018-03-02 00:31:26 -06:00
HenryNguyen5 e9d719be52 Remove tx on state change (#1224)
* Clear serialized transaction on any change to transaction state

* Fix tsc errors

* remove console error

* Remove property mutations

* dont reset network unit when unit property isnt being reset
2018-03-02 00:28:50 -06:00
Daniel Ternyak 84319ab9a1
Fix unit value (#1223) 2018-03-01 23:31:27 -06:00
greenkeeper[bot] dbb5d9944d fix(package): update wallet-address-validator to version 0.1.2 (#1222) 2018-03-01 23:05:54 -06:00
greenkeeper[bot] f442cdae61 chore(package): update copy-webpack-plugin to version 4.5.0 (#1221) 2018-03-01 19:30:43 -06:00
James Prado aabcd3f7a3 Use Network Symbol in Confirmation Modal (#1039)
* Set default unit to 'ETH' instead of 'ether'

* Use 'isEtherUnit()' everywhere

* Set default unit to empty string

* Update isEthUnit to isNetworkUnit

* Fix unit conversion for non-ethereum networks

* Set default network unit properly

* Fix tests

* fix typos

* Update isNetworkUnit selector

* Update isNetworkUnit

* Fix validationhelpers tests

* Add mock state to tests & Move isNetworkUnit to selectors

* Fix validation helper spec

* fix unit swap spec
2018-03-01 19:24:14 -06:00
greenkeeper[bot] 08335fbca0 chore(package): update file-loader to version 1.1.11 (#1220) 2018-03-01 17:18:56 -06:00
greenkeeper[bot] 2c37463f7c chore(package): update copy-webpack-plugin to version 4.4.3 (#1219) 2018-03-01 16:35:06 -06:00
Daniel Ternyak 162713ac6d
Logo updates (#1216)
* Update image brand color, remove unused images.

* Update brand color.
2018-03-01 13:49:07 -06:00
greenkeeper[bot] 328bd05859 chore(package): update @types/react to version 16.0.40 (#1214) 2018-03-01 13:37:43 -06:00
William O'Beirne 653c363279 Copy address touchups (#1215)
* Checksum address, adjust styles.

* Pull up address
2018-03-01 13:36:30 -06:00
James Prado 9ef1920fe0 Update dropdowns, inputs, and textareas (#1169)
* Align footer to bottom

* Fix request payment offset padding

* Update request payment padding

* Add new Input and Dropdown components

* Fix offset margins in equiv vals

* Update all send tx inputs & dropdowns

* Update generate wallet dropdowns

* Update inputs & dropdowns for contracts tab

* Add inputs & dropdowns for all but swap tab

* amend

* Fix imports

* inputs are invalid when not disabled or readonly

* Fix offset refresh button

* Add togglable password back to wallet generation

* Update swap inputs, textareas, and dropdowns

* Update any outstanding inputs

* Make UnitDropDown searchable

* unitdropdown searchanble if options > 10

* Fix css issues

* Reset before setting currentTo
2018-03-01 11:53:29 -06:00
Daniel Ternyak 95072d350a
chore(package): update html-webpack-plugin to version 3.0.3 (#1212)
Closes #1211
2018-03-01 11:45:49 -06:00
Kenneth Ashley 3953af5f03 Remove exclusion of font-awesome assets (#1172)
Excluding font awesome assets causes error due to webpack not knowing how to read the files.
2018-02-28 22:58:35 -06:00
Danny Skubak 23546a1cf9 Force Node Change on Web3 Unset (#1207)
* add CONFIG_NODE_CHANGE_FORCE action

* implement forceful node change on web3

* update comment

* add test

* make tsc happy

* update test
2018-02-28 22:31:33 -06:00
greenkeeper[bot] 1a711b5c20 chore(package): update lint-staged to version 7.0.0 (#1156) 2018-02-28 21:31:46 -06:00
Daniel Ternyak c01a4beaaa
chore(package): update thread-loader to version 1.1.5 (#1210)
Closes #1159
2018-02-28 21:13:15 -06:00
Rajiv Shah f12d72a57e Fix typo in disclaimer modal (#1118) 2018-02-28 21:04:58 -06:00
greenkeeper[bot] d147ec1b15 fix(package): update ethereumjs-util to version 5.1.5 (#1179) 2018-02-28 21:03:10 -06:00
greenkeeper[bot] bc2c4b776f chore(package): update css-loader to version 0.28.10 (#1163) 2018-02-28 21:01:21 -06:00
William O'Beirne 1eb57a38bc Address component for checksumming + linking to explorer (#1168)
* Add address component that checksums and optionally links to block explorer.

* tscheck

* Add exclusive props, type guard.
2018-02-28 20:54:43 -06:00
Daniel Ternyak 5fcec1ecd7
chore(package): update prettier to version 1.11.1 (#1209)
Closes #1186
2018-02-28 20:36:09 -06:00
greenkeeper[bot] a9b07cdf18 chore(package): update @types/jest to version 22.1.4 (#1202) 2018-02-28 20:26:44 -06:00
greenkeeper[bot] c6f58bb19c fix(package): update rc-slider to version 8.6.1 (#1188) 2018-02-28 20:26:17 -06:00
greenkeeper[bot] 093b0fecf6 chore(package): update less-loader to version 4.0.6 (#1187) 2018-02-28 20:19:53 -06:00
Daniel Ternyak 070b07ae40
chore(package): update nodemon to version 1.17.1 (#1195)
Closes #1190
2018-02-28 20:16:12 -06:00
greenkeeper[bot] e5b2ccef7a chore(package): update @types/react to version 16.0.39 (#1208) 2018-02-28 19:35:09 -06:00
greenkeeper[bot] 375360e71a chore(package): update cache-loader to version 1.2.2 (#1196) 2018-02-28 10:34:42 -06:00
William O'Beirne a430fe650c Update copy / links for Beta (#1193)
* AlphaAgreement -> BetaAgreement.

* Banner color.

* Remove language disclaimer.

* Discord link in footer.

* Update font for discord icon.

* Adjust copy.

* Link to github repo in error message.

* Remove always error
2018-02-27 15:35:32 -06:00
greenkeeper[bot] 296b78d62e fix(package): update react-markdown to version 3.2.2 (#1180) 2018-02-26 19:23:47 -06:00
greenkeeper[bot] 0a1f36a413 chore(package): update cache-loader to version 1.2.1 (#1184) 2018-02-26 19:23:04 -06:00
James Prado 81d4444dff Add regex for BIP44 Strings (#1035)
* Add regex check for BIP44 paths

* Add tests for BIP44 regex

* Remove '/config' from excluded paths in jest

* update path

* Update Validator tests & remove old dPathRegex tests

* Test hardcoded dpaths
2018-02-26 19:20:41 -06:00
greenkeeper[bot] b3da25c3f7 chore(package): update awesome-typescript-loader to version 3.5.0 (#1171) 2018-02-26 19:03:17 -06:00
greenkeeper[bot] 5436f20db7 chore(package): update file-loader to version 1.1.10 (#1182) 2018-02-26 18:11:11 -06:00
greenkeeper[bot] 696258e7cd chore(package): update worker-loader to version 1.1.1 (#1174) 2018-02-25 19:58:03 -06:00
Amidou Kante 4576b8f325 Copy to clipboard (#1146)
* added code for copy to clipbaord svg

* removed svg link

* can copy clipboard to mouse

* can copy clipboard to mouse

* can copy clipboard to mouse

* change copy svg to copy icon

* updated css styling

* locked in version number

* removed css state color

* scss updates coloring instead of additonal state

* change colors to scss variables

* changed p tag to span tag

* final style updates

* function to revert copied text
2018-02-25 14:02:03 -06:00
greenkeeper[bot] 23deceeb05 chore(package): update tslint-config-prettier to version 1.9.0 (#1176) 2018-02-25 13:20:16 -06:00
greenkeeper[bot] bd302ec730 chore(package): update ts-jest to version 22.4.0 (#1177) 2018-02-25 13:19:23 -06:00
Daniel Ternyak 2ae567005f
chore(package): update file-loader to version 1.1.9 (#1173)
Closes #1143
2018-02-24 19:38:36 -06:00
greenkeeper[bot] 21b946b0c1 chore(package): update webpack-dev-middleware to version 2.0.6 (#1164) 2018-02-24 19:36:04 -06:00
greenkeeper[bot] aa8bf24ab1 chore(package): update nodemon to version 1.15.1 (#1140) 2018-02-24 19:35:38 -06:00
Daniel Ternyak 29205626f2
chore(package): update electron-builder to version 20.2.0 (#1170)
Closes #1139
2018-02-24 19:33:14 -06:00
William O'Beirne 1b6143e457 Don't refresh on network change (#1144)
* Configure sagas and components to react to network switch.

* tscheck

* Update tests with new behavior.

* tscheck

* Log out of wallet on network change.

* Fix up test.
2018-02-24 19:32:34 -06:00
William O'Beirne 33f5ede22a Minor swap rates refactor (#1162)
* Refactor swaps:
* Remove references to bity fallback, it aint happening
* Consolidate sagas to single orchestrator function like other sagas
* Grab rates once, dont continuously poll

* tscheck

* Re-instate the auto-fetching behavior. This time, only notify the first time.

* Make CurrentRates responsible for redux actions. Fix up some typings.

* Remove commented code.

* Update snapshot.
2018-02-24 19:29:34 -06:00
William O'Beirne b48617e95e Simplify custom node URL (#1141)
* Simplify custom nodes to just be a URL, not a url + port.

* Allow modals to specify max width (#1142)
2018-02-24 12:02:07 -06:00
greenkeeper[bot] dc24a52e2c fix(package): update qrcode.react to version 0.8.0 (#1148) 2018-02-24 12:00:49 -06:00
William O'Beirne c76d0b3fa5 Handle Gas / Estimates on a Per Network Basis (#1160)
* Give each network the ability to specify default estimates, and whether or not they should fetch estimates from API. Convert gas slider to always use estimates.

* Fix gas cache invalidation, invalid too high / low logic.

* Fix up tests.

* tscheck
2018-02-24 12:00:00 -06:00
greenkeeper[bot] afaf045edd chore(package): update copy-webpack-plugin to version 4.4.2 (#1167) 2018-02-24 11:58:46 -06:00
James Prado 48536f79be Align footer to bottom (#1150) 2018-02-24 11:57:54 -06:00
Danny Skubak 94061e0c3e Add Blockscale Beta Node (#1134) 2018-02-24 11:56:18 -06:00
Daniel Ternyak a50dc2ebb0
Adjust Wallet Interface (#1154)
* Adjust Base Wallet Interface to not return promises' for getAdderssString; adjust callers to not await

* remove async for saveWalletConfig
2018-02-21 12:23:04 -06:00
greenkeeper[bot] f2bf7529b3 fix(package): update react-markdown to version 3.2.1 (#1155) 2018-02-21 11:23:29 -06:00
William O'Beirne 9727051290 Source version number from package.json (#1145) 2018-02-19 21:46:07 -06:00
greenkeeper[bot] 00cea6f548 chore(package): update electron-builder to version 20.0.5 (#1109) 2018-02-17 20:36:50 -06:00
Daniel Ternyak 891014894e
Tag Beta 0.3.2 (#1132)
* Patch Web3 boolean logic

* Tag Beta 0.3.2
2018-02-17 18:49:19 -06:00
Daniel Ternyak 39fba57831
Patch Web3 boolean logic (#1131) 2018-02-17 18:48:31 -06:00
Daniel Ternyak e630b1f9ba
Tag Beta 0.3.1 (#1129) 2018-02-17 18:27:30 -06:00
Pete Jihoon Kim 2f23aa96de Fix compatibility with unknown Web 3 providers (#1128)
* Fix compatibility with unknown Web3 providers

* Detect Cipher Browser

* Fix incorrect translation label
2018-02-17 18:25:01 -06:00
Daniel Ternyak 23cb069ca8
Tag Beta 0.3.0 (#1126) 2018-02-17 16:08:24 -06:00
William O'Beirne 41c5c32d51 Fix Modals on Mobile (#1110) 2018-02-17 15:57:15 -06:00
greenkeeper[bot] 97d58c4a18 chore(package): update lint-staged to version 6.1.1 (#1105) 2018-02-17 15:47:32 -06:00
greenkeeper[bot] 81d8a4878d fix(package): update react-redux to version 5.0.7 (#1121) 2018-02-17 15:45:53 -06:00
greenkeeper[bot] 3ed72b880e chore(package): update hoist-non-react-statics to version 2.5.0 (#1114) 2018-02-17 13:40:17 -06:00
greenkeeper[bot] 422f5677bd chore(package): update @types/lodash to version 4.14.104 (#1113) 2018-02-17 13:37:31 -06:00
greenkeeper[bot] 13484b4b62 chore(package): update @types/jest to version 22.1.3 (#1125) 2018-02-17 13:14:53 -06:00
William O'Beirne 3c5dd2743e Swap Bity Promo w/ Shapeshift, Adjust Promo Display (#1115) 2018-02-16 14:46:50 -06:00
William O'Beirne c5f32a9ce2 Re-set address state when wallet changes (#1107) 2018-02-16 14:34:58 -06:00
William O'Beirne 31912c0f83 Gas Price Estimates API (#1050)
* Setup api / reducers / actions for gas.

* Implement gas price saga, fetch from component, and loading states. Blocked on CORS.

* Implement caching mechanism.

* Add tests for gas saga and reducer.

* More testing.

* Indicate that gas price is recommended when fetched from API.

* Hide track while loading.

* Fix tscheck.

* Check gas estimate before assuming its ok.

* Check for correct logical order of gas prices.

* Tscheck fixes.
2018-02-16 13:01:39 -06:00
William O'Beirne cec0d690c7 Hide refresh button and its spinner on initial balance fetch (#1108) 2018-02-16 12:47:28 -06:00
William O'Beirne 1ff26baa63 Fix bad browser copy (#1111) 2018-02-16 12:39:50 -06:00
William O'Beirne b574c209a6 Add missing keys on insecure wallet checkboxes. (#1112) 2018-02-16 12:39:05 -06:00
William O'Beirne be61d804e0 Check Transaction page (Pt. 1 - The Basics) (#1099)
* Component layer and routing for transaction status.

* Initial start on redux for transactions.

* Initial crack at reducer / actions / saga for transactions.

* Finish off check transaction saga, reducer, component, and page.
2018-02-16 10:57:23 -06:00
greenkeeper[bot] f46df010db chore(package): update tslint-config-prettier to version 1.8.0 (#1098) 2018-02-15 19:48:35 -06:00
greenkeeper[bot] 5db958128a chore(package): update style-loader to version 0.20.2 (#1100) 2018-02-15 19:48:12 -06:00
greenkeeper[bot] 43853fd198 chore(package): update @types/lodash to version 4.14.103 (#1101) 2018-02-15 19:47:56 -06:00
greenkeeper[bot] 7807cf09aa chore(package): update nodemon to version 1.15.0 (#1102) 2018-02-15 19:47:42 -06:00
greenkeeper[bot] b5b1ff73ad chore(package): update @types/react-select to version 1.2.3 (#1091) 2018-02-14 17:26:47 -06:00
Luit Hollander 9f682f6a46 Update infura endpoints (#1094) 2018-02-14 17:05:43 -06:00
greenkeeper[bot] 20c6007a7b chore(package): update webpack-subresource-integrity to version 1.0.4 (#1092) 2018-02-14 16:41:18 -06:00
Daniel Ternyak ab51bde9e8
Add Coveralls Badge (#1093) 2018-02-14 15:21:02 -06:00
greenkeeper[bot] 5abf5ba632 chore(package): update electron-builder to version 20.0.4 (#1077) 2018-02-13 20:15:28 -06:00
greenkeeper[bot] a4c7e0e3c0 chore(package): update tslint-react to version 3.5.1 (#1085) 2018-02-13 20:15:14 -06:00
greenkeeper[bot] 643ea7c351 chore(package): update tslint-microsoft-contrib to version 5.0.3 (#1086) 2018-02-13 20:14:44 -06:00
greenkeeper[bot] 011b8d5ce8 chore(package): update @types/query-string to version 5.1.0 (#1087) 2018-02-13 20:14:32 -06:00
Michael - Blurpesec 84f5e9f00f Updated addresses for helpArticles list (#1089) 2018-02-13 20:11:47 -06:00
Daniel Ternyak 0d05e8ceb5
Merge pull request #1080 from MyCryptoHQ/greenkeeper/@types/react-16.0.38
Update @types/react to the latest version 🚀
2018-02-13 11:48:52 -06:00
greenkeeper[bot] d622554ab5 chore(package): update @types/react to version 16.0.38 2018-02-13 15:58:28 +00:00
485 changed files with 23625 additions and 21001 deletions

2
.gitignore vendored
View File

@ -56,3 +56,5 @@ webpack_config/server.csr
v8-compile-cache-0/
package-lock.json
yarn.lock

1
.prettierignore Normal file
View File

@ -0,0 +1 @@
common/translations

View File

@ -1,6 +1,7 @@
# MyCrypto Beta (VISIT [MyCryptoHQ/mycrypto.com](https://github.com/MyCryptoHQ/mycrypto.com) for the current site)<br/>Just looking to download? Grab our [latest release](https://github.com/MyCryptoHQ/MyCrypto/releases)
[![Greenkeeper badge](https://badges.greenkeeper.io/MyCryptoHq/MyCrypto.svg)](https://greenkeeper.io/)
[![Coverage Status](https://coveralls.io/repos/github/MyCryptoHQ/MyCrypto/badge.svg?branch=develop)](https://coveralls.io/github/MyCryptoHQ/MyCrypto?branch=develop)
## Running the App

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { Provider, connect } from 'react-redux';
import { withRouter, Switch, Redirect, HashRouter, Route, BrowserRouter } from 'react-router-dom';
// Components
import Contracts from 'containers/Tabs/Contracts';
@ -9,32 +9,47 @@ import SendTransaction from 'containers/Tabs/SendTransaction';
import Swap from 'containers/Tabs/Swap';
import SignAndVerifyMessage from 'containers/Tabs/SignAndVerifyMessage';
import BroadcastTx from 'containers/Tabs/BroadcastTx';
import CheckTransaction from 'containers/Tabs/CheckTransaction';
import ErrorScreen from 'components/ErrorScreen';
import PageNotFound from 'components/PageNotFound';
import LogOutPrompt from 'components/LogOutPrompt';
import { TitleBar } from 'components/ui';
import { Store } from 'redux';
import { pollOfflineStatus } from 'actions/config';
import { pollOfflineStatus, TPollOfflineStatus } from 'actions/config';
import { AppState } from 'reducers';
import { RouteNotFound } from 'components/RouteNotFound';
import { RedirectWithQuery } from 'components/RedirectWithQuery';
import 'what-input';
import { setUnitMeta, TSetUnitMeta } from 'actions/transaction';
import { getNetworkUnit } from 'selectors/config';
interface Props {
interface OwnProps {
store: Store<AppState>;
}
interface StateProps {
networkUnit: string;
}
interface DispatchProps {
pollOfflineStatus: TPollOfflineStatus;
setUnitMeta: TSetUnitMeta;
}
type Props = OwnProps & StateProps & DispatchProps;
interface State {
error: Error | null;
}
export default class Root extends Component<Props, State> {
class RootClass extends Component<Props, State> {
public state = {
error: null
};
public componentDidMount() {
this.props.store.dispatch(pollOfflineStatus());
this.props.pollOfflineStatus();
this.props.setUnitMeta(this.props.networkUnit);
}
public componentDidCatch(error: Error) {
@ -67,6 +82,7 @@ export default class Root extends Component<Props, State> {
<Route path="/contracts" component={Contracts} />
<Route path="/ens" component={ENS} exact={true} />
<Route path="/sign-and-verify-message" component={SignAndVerifyMessage} />
<Route path="/tx-status" component={CheckTransaction} exact={true} />
<Route path="/pushTx" component={BroadcastTx} />
<RouteNotFound />
</Switch>
@ -120,8 +136,7 @@ const LegacyRoutes = withRouter(props => {
history.push('/account/info');
break;
case '#check-tx-status':
history.push('/check-tx-status');
break;
return <RedirectWithQuery from={pathname} to={'/tx-status'} />;
}
}
@ -133,3 +148,14 @@ const LegacyRoutes = withRouter(props => {
</Switch>
);
});
const mapStateToProps = (state: AppState) => {
return {
networkUnit: getNetworkUnit(state)
};
};
export default connect(mapStateToProps, {
pollOfflineStatus,
setUnitMeta
})(RootClass);

View File

@ -48,6 +48,14 @@ export function changeNodeIntent(payload: string): interfaces.ChangeNodeIntentAc
};
}
export type TChangeNodeForce = typeof changeNodeForce;
export function changeNodeForce(payload: string): interfaces.ChangeNodeForceAction {
return {
type: TypeKeys.CONFIG_NODE_CHANGE_FORCE,
payload
};
}
export type TAddCustomNode = typeof addCustomNode;
export function addCustomNode(
payload: interfaces.AddCustomNodeAction['payload']

View File

@ -36,6 +36,11 @@ export interface ChangeNodeIntentAction {
type: TypeKeys.CONFIG_NODE_CHANGE_INTENT;
payload: string;
}
/*** Force Change Node ***/
export interface ChangeNodeForceAction {
type: TypeKeys.CONFIG_NODE_CHANGE_FORCE;
payload: string;
}
/*** Add Custom Node ***/
export interface AddCustomNodeAction {

View File

@ -10,6 +10,7 @@ export enum TypeKeys {
CONFIG_NODE_WEB3_UNSET = 'CONFIG_NODE_WEB3_UNSET',
CONFIG_NODE_CHANGE = 'CONFIG_NODE_CHANGE',
CONFIG_NODE_CHANGE_INTENT = 'CONFIG_NODE_CHANGE_INTENT',
CONFIG_NODE_CHANGE_FORCE = 'CONFIG_NODE_CHANGE_FORCE',
CONFIG_ADD_CUSTOM_NODE = 'CONFIG_ADD_CUSTOM_NODE',
CONFIG_REMOVE_CUSTOM_NODE = 'CONFIG_REMOVE_CUSTOM_NODE',

View File

@ -0,0 +1,19 @@
import * as interfaces from './actionTypes';
import { TypeKeys } from './constants';
export type TFetchGasEstimates = typeof fetchGasEstimates;
export function fetchGasEstimates(): interfaces.FetchGasEstimatesAction {
return {
type: TypeKeys.GAS_FETCH_ESTIMATES
};
}
export type TSetGasEstimates = typeof setGasEstimates;
export function setGasEstimates(
payload: interfaces.SetGasEstimatesAction['payload']
): interfaces.SetGasEstimatesAction {
return {
type: TypeKeys.GAS_SET_ESTIMATES,
payload
};
}

View File

@ -0,0 +1,14 @@
import { TypeKeys } from './constants';
import { GasEstimates } from 'api/gas';
export interface FetchGasEstimatesAction {
type: TypeKeys.GAS_FETCH_ESTIMATES;
}
export interface SetGasEstimatesAction {
type: TypeKeys.GAS_SET_ESTIMATES;
payload: GasEstimates;
}
/*** Union Type ***/
export type GasAction = FetchGasEstimatesAction | SetGasEstimatesAction;

View File

@ -0,0 +1,4 @@
export enum TypeKeys {
GAS_FETCH_ESTIMATES = 'GAS_FETCH_ESTIMATES',
GAS_SET_ESTIMATES = 'GAS_SET_ESTIMATES'
}

View File

@ -0,0 +1,3 @@
export * from './actionCreators';
export * from './actionTypes';
export * from './constants';

View File

@ -27,10 +27,10 @@ export function loadBityRatesSucceededSwap(
};
}
export type TLoadShapeshiftSucceededSwap = typeof loadShapeshiftRatesSucceededSwap;
export type TLoadShapeshiftRatesSucceededSwap = typeof loadShapeshiftRatesSucceededSwap;
export function loadShapeshiftRatesSucceededSwap(
payload
): interfaces.LoadShapshiftRatesSucceededSwapAction {
payload: interfaces.LoadShapeshiftRatesSucceededSwapAction['payload']
): interfaces.LoadShapeshiftRatesSucceededSwapAction {
return {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_SUCCEEDED,
payload
@ -59,13 +59,27 @@ export function loadBityRatesRequestedSwap(): interfaces.LoadBityRatesRequestedS
};
}
export type TLoadShapeshiftRequestedSwap = typeof loadShapeshiftRatesRequestedSwap;
export function loadShapeshiftRatesRequestedSwap(): interfaces.LoadShapeshiftRequestedSwapAction {
export type TLoadShapeshiftRatesRequestedSwap = typeof loadShapeshiftRatesRequestedSwap;
export function loadShapeshiftRatesRequestedSwap(): interfaces.LoadShapeshiftRatesRequestedSwapAction {
return {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_REQUESTED
};
}
export type TLoadBityRatesFailedSwap = typeof loadBityRatesFailedSwap;
export function loadBityRatesFailedSwap(): interfaces.LoadBityRatesFailedSwapAction {
return {
type: TypeKeys.SWAP_LOAD_BITY_RATES_FAILED
};
}
export type TLoadShapeshiftFailedSwap = typeof loadShapeshiftRatesFailedSwap;
export function loadShapeshiftRatesFailedSwap(): interfaces.LoadShapeshiftRatesFailedSwapAction {
return {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_FAILED
};
}
export type TStopLoadBityRatesSwap = typeof stopLoadBityRatesSwap;
export function stopLoadBityRatesSwap(): interfaces.StopLoadBityRatesSwapAction {
return {

View File

@ -8,7 +8,7 @@ export interface Pairs {
}
export interface SwapInput {
id: string;
label: string;
amount: number | string;
}
@ -43,7 +43,7 @@ export interface LoadBityRatesSucceededSwapAction {
payload: ApiResponse;
}
export interface LoadShapshiftRatesSucceededSwapAction {
export interface LoadShapeshiftRatesSucceededSwapAction {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_SUCCEEDED;
payload: ApiResponse;
}
@ -59,12 +59,18 @@ export interface RestartSwapAction {
export interface LoadBityRatesRequestedSwapAction {
type: TypeKeys.SWAP_LOAD_BITY_RATES_REQUESTED;
payload?: null;
}
export interface LoadShapeshiftRequestedSwapAction {
export interface LoadShapeshiftRatesRequestedSwapAction {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_REQUESTED;
payload?: null;
}
export interface LoadBityRatesFailedSwapAction {
type: TypeKeys.SWAP_LOAD_BITY_RATES_FAILED;
}
export interface LoadShapeshiftRatesFailedSwapAction {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_FAILED;
}
export interface ChangeStepSwapAction {
@ -240,12 +246,14 @@ export interface ShowLiteSendAction {
export type SwapAction =
| ChangeStepSwapAction
| InitSwap
| LoadBityRatesSucceededSwapAction
| LoadShapshiftRatesSucceededSwapAction
| DestinationAddressSwapAction
| RestartSwapAction
| LoadBityRatesRequestedSwapAction
| LoadShapeshiftRequestedSwapAction
| LoadBityRatesSucceededSwapAction
| LoadBityRatesFailedSwapAction
| LoadShapeshiftRatesRequestedSwapAction
| LoadShapeshiftRatesSucceededSwapAction
| LoadShapeshiftRatesFailedSwapAction
| StopLoadBityRatesSwapAction
| StopLoadShapeshiftRatesSwapAction
| BityOrderCreateRequestedSwapAction

View File

@ -7,6 +7,8 @@ export enum TypeKeys {
SWAP_RESTART = 'SWAP_RESTART',
SWAP_LOAD_BITY_RATES_REQUESTED = 'SWAP_LOAD_BITY_RATES_REQUESTED',
SWAP_LOAD_SHAPESHIFT_RATES_REQUESTED = 'SWAP_LOAD_SHAPESHIFT_RATES_REQUESTED',
SWAP_LOAD_BITY_RATES_FAILED = 'SWAP_LOAD_BITY_RATES_FAILED',
SWAP_LOAD_SHAPESHIFT_RATES_FAILED = 'SWAP_LOAD_SHAPESHIFT_RATES_FAILED',
SWAP_STOP_LOAD_BITY_RATES = 'SWAP_STOP_LOAD_BITY_RATES',
SWAP_STOP_LOAD_SHAPESHIFT_RATES = 'SWAP_STOP_LOAD_SHAPESHIFT_RATES',
SWAP_ORDER_TIME = 'SWAP_ORDER_TIME',

View File

@ -81,7 +81,10 @@ const setGasPriceField = (payload: SetGasPriceFieldAction['payload']): SetGasPri
});
type TReset = typeof reset;
const reset = (): ResetAction => ({ type: TypeKeys.RESET });
const reset = (payload: ResetAction['payload'] = { include: {}, exclude: {} }): ResetAction => ({
type: TypeKeys.RESET,
payload
});
export {
TInputGasLimit,

View File

@ -5,23 +5,22 @@ import {
SetTokenToMetaAction
} from 'actions/transaction';
type TSetTokenBalance = typeof setTokenValue;
type TSetUnitMeta = typeof setUnitMeta;
type TSetTokenTo = typeof setTokenTo;
const setTokenTo = (payload: SetTokenToMetaAction['payload']): SetTokenToMetaAction => ({
export type TSetTokenTo = typeof setTokenTo;
export const setTokenTo = (payload: SetTokenToMetaAction['payload']): SetTokenToMetaAction => ({
type: TypeKeys.TOKEN_TO_META_SET,
payload
});
const setTokenValue = (payload: SetTokenValueMetaAction['payload']): SetTokenValueMetaAction => ({
export type TSetTokenValue = typeof setTokenValue;
export const setTokenValue = (
payload: SetTokenValueMetaAction['payload']
): SetTokenValueMetaAction => ({
type: TypeKeys.TOKEN_VALUE_META_SET,
payload
});
const setUnitMeta = (payload: SetUnitMetaAction['payload']): SetUnitMetaAction => ({
export type TSetUnitMeta = typeof setUnitMeta;
export const setUnitMeta = (payload: SetUnitMetaAction['payload']): SetUnitMetaAction => ({
type: TypeKeys.UNIT_META_SET,
payload
});
export { TSetUnitMeta, TSetTokenBalance, TSetTokenTo, setUnitMeta, setTokenValue, setTokenTo };

View File

@ -7,6 +7,9 @@ import { SignAction } from './sign';
import { SwapAction } from './swap';
import { CurrentAction } from './current';
import { SendEverythingAction } from './sendEverything';
import { State as FieldState } from 'reducers/transaction/fields';
import { State as MetaState } from 'reducers/transaction/meta';
import { State as SignState } from 'reducers/transaction/sign';
export * from './broadcast';
export * from './fields';
@ -19,6 +22,18 @@ export * from './sendEverything';
export interface ResetAction {
type: TypeKeys.RESET;
payload: {
include: {
fields?: (keyof FieldState)[];
meta?: (keyof MetaState)[];
sign?: (keyof SignState)[];
};
exclude: {
fields?: (keyof FieldState)[];
meta?: (keyof MetaState)[];
sign?: (keyof SignState)[];
};
};
}
export type TransactionAction =

View File

@ -0,0 +1,35 @@
import * as interfaces from './actionTypes';
import { TypeKeys } from './constants';
export type TFetchTransactionData = typeof fetchTransactionData;
export function fetchTransactionData(txhash: string): interfaces.FetchTransactionDataAction {
return {
type: TypeKeys.TRANSACTIONS_FETCH_TRANSACTION_DATA,
payload: txhash
};
}
export type TSetTransactionData = typeof setTransactionData;
export function setTransactionData(
payload: interfaces.SetTransactionDataAction['payload']
): interfaces.SetTransactionDataAction {
return {
type: TypeKeys.TRANSACTIONS_SET_TRANSACTION_DATA,
payload
};
}
export type TResetTransactionData = typeof resetTransactionData;
export function resetTransactionData(): interfaces.ResetTransactionDataAction {
return { type: TypeKeys.TRANSACTIONS_RESET_TRANSACTION_DATA };
}
export type TAddRecentTransaction = typeof addRecentTransaction;
export function addRecentTransaction(
payload: interfaces.AddRecentTransactionAction['payload']
): interfaces.AddRecentTransactionAction {
return {
type: TypeKeys.TRANSACTIONS_ADD_RECENT_TRANSACTION,
payload
};
}

View File

@ -0,0 +1,33 @@
import { TypeKeys } from './constants';
import { SavedTransaction, TransactionData, TransactionReceipt } from 'types/transactions';
export interface FetchTransactionDataAction {
type: TypeKeys.TRANSACTIONS_FETCH_TRANSACTION_DATA;
payload: string;
}
export interface SetTransactionDataAction {
type: TypeKeys.TRANSACTIONS_SET_TRANSACTION_DATA;
payload: {
txhash: string;
data: TransactionData | null;
receipt: TransactionReceipt | null;
error: string | null;
};
}
export interface ResetTransactionDataAction {
type: TypeKeys.TRANSACTIONS_RESET_TRANSACTION_DATA;
}
export interface AddRecentTransactionAction {
type: TypeKeys.TRANSACTIONS_ADD_RECENT_TRANSACTION;
payload: SavedTransaction;
}
/*** Union Type ***/
export type TransactionsAction =
| FetchTransactionDataAction
| SetTransactionDataAction
| ResetTransactionDataAction
| AddRecentTransactionAction;

View File

@ -0,0 +1,7 @@
export enum TypeKeys {
TRANSACTIONS_FETCH_TRANSACTION_DATA = 'TRANSACTIONS_FETCH_TRANSACTION_DATA',
TRANSACTIONS_SET_TRANSACTION_DATA = 'TRANSACTIONS_SET_TRANSACTION_DATA',
TRANSACTIONS_SET_TRANSACTION_ERROR = 'TRANSACTIONS_SET_TRANSACTION_ERROR',
TRANSACTIONS_RESET_TRANSACTION_DATA = 'TRANSACTIONS_RESET_TRANSACTION_DATA',
TRANSACTIONS_ADD_RECENT_TRANSACTION = 'TRANSACTIONS_ADD_RECENT_TRANSACTION'
}

View File

@ -0,0 +1,3 @@
export * from './actionCreators';
export * from './actionTypes';
export * from './constants';

View File

@ -29,10 +29,14 @@ const repOptions = {
name: 'Augur'
};
export interface MappedRates {
[key: string]: any;
}
export function getAllRates() {
const mappedRates = {};
const mappedRates: MappedRates = {};
return _getAllRates().then(bityRates => {
bityRates.objects.forEach(each => {
bityRates.objects.forEach((each: any) => {
const pairName = each.pair;
const from = { id: pairName.substring(0, 3) };
const to = { id: pairName.substring(3, 6) };

88
common/api/gas.ts Normal file
View File

@ -0,0 +1,88 @@
import { checkHttpStatus, parseJSON } from './utils';
import { Omit } from 'react-redux';
const MAX_GAS_FAST = 250;
interface RawGasEstimates {
safeLow: number;
standard: number;
fast: number;
fastest: number;
block_time: number;
blockNum: number;
}
export interface GasEstimates {
safeLow: number;
standard: number;
fast: number;
fastest: number;
time: number;
chainId: number;
isDefault: boolean;
}
interface GasExpressResponse {
block_time: number;
blockNum: number;
fast: number;
fastest: number;
safeLow: number;
standard: number;
}
export function fetchGasEstimates(): Promise<GasEstimates> {
return fetch('https://dev.blockscale.net/api/gasexpress.json', {
mode: 'cors'
})
.then(checkHttpStatus)
.then(parseJSON)
.then((res: GasExpressResponse) => {
// Make sure it looks like a raw gas estimate, and it has valid values
const keys: (keyof Omit<GasExpressResponse, 'block_time' | 'blockNum'>)[] = [
'safeLow',
'standard',
'fast',
'fastest'
];
keys.forEach(key => {
if (typeof res[key] !== 'number') {
throw new Error(
`Gas estimate API has invalid shape: Expected numeric key '${key}' in response, got '${
res[key]
}' instead`
);
}
});
// Make sure the estimate isn't totally crazy
const estimateRes = res as RawGasEstimates;
if (estimateRes.fast > MAX_GAS_FAST) {
throw new Error(
`Gas estimate response estimate too high: Max fast is ${MAX_GAS_FAST}, was given ${
estimateRes.fast
}`
);
}
if (
estimateRes.safeLow > estimateRes.standard ||
estimateRes.standard > estimateRes.fast ||
estimateRes.fast > estimateRes.fastest
) {
throw new Error(
`Gas esimates are in illogical order: should be safeLow < standard < fast < fastest, received ${
estimateRes.safeLow
} < ${estimateRes.standard} < ${estimateRes.fast} < ${estimateRes.fastest}`
);
}
return estimateRes;
})
.then((res: RawGasEstimates) => ({
...res,
time: Date.now(),
chainId: 1,
isDefault: false
}));
}

View File

@ -28,6 +28,44 @@ export const SHAPESHIFT_TOKEN_WHITELIST = [
];
export const SHAPESHIFT_WHITELIST = [...SHAPESHIFT_TOKEN_WHITELIST, 'ETH', 'ETC', 'BTC'];
interface IPairData {
limit: number;
maxLimit: number;
min: number;
minerFee: number;
pair: string;
rate: string;
}
interface IExtraPairData {
status: string;
image: string;
name: string;
}
interface IAvailablePairData {
[pairName: string]: IExtraPairData;
}
interface ShapeshiftMarketInfo {
rate: string;
limit: number;
pair: string;
maxLimit: number;
min: number;
minerFee: number;
}
interface TokenMap {
[pairName: string]: {
id: string;
rate: string;
limit: number;
min: number;
options: (IExtraPairData & { id: string })[];
};
}
class ShapeshiftService {
public whitelist = SHAPESHIFT_WHITELIST;
private url = SHAPESHIFT_BASE_URL;
@ -36,13 +74,18 @@ class ShapeshiftService {
'Content-Type': 'application/json'
};
public checkStatus(address) {
public checkStatus(address: string) {
return fetch(`${this.url}/txStat/${address}`)
.then(checkHttpStatus)
.then(parseJSON);
}
public sendAmount(withdrawal, originKind, destinationKind, destinationAmount) {
public sendAmount(
withdrawal: string,
originKind: string,
destinationKind: string,
destinationAmount: number
) {
const pair = `${originKind.toLowerCase()}_${destinationKind.toLowerCase()}`;
return fetch(`${this.url}/sendamount`, {
@ -81,7 +124,7 @@ class ShapeshiftService {
return mappedRates;
};
private getPairRates(marketInfo) {
private getPairRates(marketInfo: ShapeshiftMarketInfo[]) {
const filteredMarketInfo = marketInfo.filter(obj => {
const { pair } = obj;
const pairArr = pair.split('_');
@ -97,7 +140,7 @@ class ShapeshiftService {
return pairRates;
}
private async checkAvl(pairRates) {
private async checkAvl(pairRates: IPairData[]) {
const avlCoins = await this.getAvlCoins();
const mapAvl = pairRates.map(p => {
const { pair } = p;
@ -121,7 +164,8 @@ class ShapeshiftService {
};
}
});
return mapAvl;
const filered = mapAvl.filter(v => v);
return filered as (IPairData & IAvailablePairData)[];
}
private getAvlCoins() {
@ -130,7 +174,7 @@ class ShapeshiftService {
.then(parseJSON);
}
private getSinglePairRate(pair) {
private getSinglePairRate(pair: string) {
return fetch(`${this.url}/rate/${pair}`)
.then(checkHttpStatus)
.then(parseJSON);
@ -142,12 +186,12 @@ class ShapeshiftService {
.then(parseJSON);
}
private isWhitelisted(coin) {
private isWhitelisted(coin: string) {
return this.whitelist.includes(coin);
}
private mapMarketInfo(marketInfo) {
const tokenMap = {};
private mapMarketInfo(marketInfo: (IPairData & IAvailablePairData)[]) {
const tokenMap: TokenMap = {};
marketInfo.forEach(m => {
const originKind = m.pair.substring(0, 3);
const destinationKind = m.pair.substring(4, 7);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' width='20px' height='20px' viewBox='0 0 79.536 79.536' style='enable-background:new 0 0 79.536 79.536;' xml:space='preserve'><path fill='#999' d='M39.769,0C17.8,0,0,17.8,0,39.768c0,21.965,17.8,39.768,39.769,39.768 c21.965,0,39.768-17.803,39.768-39.768C79.536,17.8,61.733,0,39.769,0z M34.142,58.513L15.397,39.768l7.498-7.498l11.247,11.247 l22.497-22.493l7.498,7.498L34.142,58.513z'/></svg>

Before

Width:  |  Height:  |  Size: 602 B

View File

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px" viewBox="0 0 528.899 528.899" style="enable-background:new 0 0 528.899 528.899;" xml:space="preserve"><path fill="#21a4ce" d="M328.883,89.125l107.59,107.589l-272.34,272.34L56.604,361.465L328.883,89.125z M518.113,63.177l-47.981-47.981 c-18.543-18.543-48.653-18.543-67.259,0l-45.961,45.961l107.59,107.59l53.611-53.611 C532.495,100.753,532.495,77.559,518.113,63.177z M0.3,512.69c-1.958,8.812,5.998,16.708,14.811,14.565l119.891-29.069 L27.473,390.597L0.3,512.69z"/></svg>

Before

Width:  |  Height:  |  Size: 761 B

View File

@ -1 +0,0 @@
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 92 92"><path fill="#ECECEC" d="M45.386.004C19.983.344-.333 21.215.005 46.619c.34 25.393 21.209 45.715 46.611 45.377 25.398-.342 45.718-21.213 45.38-46.615-.34-25.395-21.21-45.716-46.61-45.377zM45.25 74l-.254-.004c-3.912-.116-6.67-2.998-6.559-6.852.109-3.788 2.934-6.538 6.717-6.538l.227.004c4.021.119 6.748 2.972 6.635 6.937C51.904 71.346 49.123 74 45.25 74zm16.455-32.659c-.92 1.307-2.943 2.93-5.492 4.916l-2.807 1.938c-1.541 1.198-2.471 2.325-2.82 3.434-.275.873-.41 1.104-.434 2.88l-.004.451H39.43l.031-.907c.131-3.728.223-5.921 1.768-7.733 2.424-2.846 7.771-6.289 7.998-6.435.766-.577 1.412-1.234 1.893-1.936 1.125-1.551 1.623-2.772 1.623-3.972a7.74 7.74 0 0 0-1.471-4.576c-.939-1.323-2.723-1.993-5.303-1.993-2.559 0-4.311.812-5.359 2.478-1.078 1.713-1.623 3.512-1.623 5.35v.457H27.936l.02-.477c.285-6.769 2.701-11.643 7.178-14.487C37.947 18.918 41.447 18 45.531 18c5.346 0 9.859 1.299 13.412 3.861 3.6 2.596 5.426 6.484 5.426 11.556 0 2.837-.896 5.502-2.664 7.924z"/></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +1 @@
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 92 92"><path fill="#0e97c0" d="M45.386.004C19.983.344-.333 21.215.005 46.619c.34 25.393 21.209 45.715 46.611 45.377 25.398-.342 45.718-21.213 45.38-46.615-.34-25.395-21.21-45.716-46.61-45.377zM45.25 74l-.254-.004c-3.912-.116-6.67-2.998-6.559-6.852.109-3.788 2.934-6.538 6.717-6.538l.227.004c4.021.119 6.748 2.972 6.635 6.937C51.904 71.346 49.123 74 45.25 74zm16.455-32.659c-.92 1.307-2.943 2.93-5.492 4.916l-2.807 1.938c-1.541 1.198-2.471 2.325-2.82 3.434-.275.873-.41 1.104-.434 2.88l-.004.451H39.43l.031-.907c.131-3.728.223-5.921 1.768-7.733 2.424-2.846 7.771-6.289 7.998-6.435.766-.577 1.412-1.234 1.893-1.936 1.125-1.551 1.623-2.772 1.623-3.972a7.74 7.74 0 0 0-1.471-4.576c-.939-1.323-2.723-1.993-5.303-1.993-2.559 0-4.311.812-5.359 2.478-1.078 1.713-1.623 3.512-1.623 5.35v.457H27.936l.02-.477c.285-6.769 2.701-11.643 7.178-14.487C37.947 18.918 41.447 18 45.531 18c5.346 0 9.859 1.299 13.412 3.861 3.6 2.596 5.426 6.484 5.426 11.556 0 2.837-.896 5.502-2.664 7.924z"/></svg>
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 92 92"><path fill="#007896" d="M45.386.004C19.983.344-.333 21.215.005 46.619c.34 25.393 21.209 45.715 46.611 45.377 25.398-.342 45.718-21.213 45.38-46.615-.34-25.395-21.21-45.716-46.61-45.377zM45.25 74l-.254-.004c-3.912-.116-6.67-2.998-6.559-6.852.109-3.788 2.934-6.538 6.717-6.538l.227.004c4.021.119 6.748 2.972 6.635 6.937C51.904 71.346 49.123 74 45.25 74zm16.455-32.659c-.92 1.307-2.943 2.93-5.492 4.916l-2.807 1.938c-1.541 1.198-2.471 2.325-2.82 3.434-.275.873-.41 1.104-.434 2.88l-.004.451H39.43l.031-.907c.131-3.728.223-5.921 1.768-7.733 2.424-2.846 7.771-6.289 7.998-6.435.766-.577 1.412-1.234 1.893-1.936 1.125-1.551 1.623-2.772 1.623-3.972a7.74 7.74 0 0 0-1.471-4.576c-.939-1.323-2.723-1.993-5.303-1.993-2.559 0-4.311.812-5.359 2.478-1.078 1.713-1.623 3.512-1.623 5.35v.457H27.936l.02-.477c.285-6.769 2.701-11.643 7.178-14.487C37.947 18.918 41.447 18 45.531 18c5.346 0 9.859 1.299 13.412 3.861 3.6 2.596 5.426 6.484 5.426 11.556 0 2.837-.896 5.502-2.664 7.924z"/></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +0,0 @@
<svg version="1.1" width="20px" height="20px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 92 92" style="enable-background:new 0 0 92 92;" xml:space="preserve"><path fill="#2bb2dd" d="M45.386,0.004C19.983,0.344-0.333,21.215,0.005,46.619c0.34,25.393,21.209,45.715,46.611,45.377 c25.398-0.342,45.718-21.213,45.38-46.615C91.656,19.986,70.786-0.335,45.386,0.004z M45.25,74l-0.254-0.004 c-3.912-0.116-6.67-2.998-6.559-6.852c0.109-3.788,2.934-6.538,6.717-6.538l0.227,0.004c4.021,0.119,6.748,2.972,6.635,6.937 C51.904,71.346,49.123,74,45.25,74z M61.705,41.341c-0.92,1.307-2.943,2.93-5.492,4.916l-2.807,1.938 c-1.541,1.198-2.471,2.325-2.82,3.434c-0.275,0.873-0.41,1.104-0.434,2.88l-0.004,0.451H39.43l0.031-0.907 c0.131-3.728,0.223-5.921,1.768-7.733c2.424-2.846,7.771-6.289,7.998-6.435c0.766-0.577,1.412-1.234,1.893-1.936 c1.125-1.551,1.623-2.772,1.623-3.972c0-1.665-0.494-3.205-1.471-4.576c-0.939-1.323-2.723-1.993-5.303-1.993 c-2.559,0-4.311,0.812-5.359,2.478c-1.078,1.713-1.623,3.512-1.623,5.35v0.457H27.936l0.02-0.477 c0.285-6.769,2.701-11.643,7.178-14.487C37.947,18.918,41.447,18,45.531,18c5.346,0,9.859,1.299,13.412,3.861 c3.6,2.596,5.426,6.484,5.426,11.556C64.369,36.254,63.473,38.919,61.705,41.341z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' width='20px' height='20px' viewBox='0 0 511.626 511.626' style='enable-background:new 0 0 511.626 511.626;' xml:space='preserve'><path fill='#f0ad4e' d='M505.918,236.117c-26.651-43.587-62.485-78.609-107.497-105.065c-45.015-26.457-92.549-39.687-142.608-39.687 c-50.059,0-97.595,13.225-142.61,39.687C68.187,157.508,32.355,192.53,5.708,236.117C1.903,242.778,0,249.345,0,255.818 c0,6.473,1.903,13.04,5.708,19.699c26.647,43.589,62.479,78.614,107.495,105.064c45.015,26.46,92.551,39.68,142.61,39.68 c50.06,0,97.594-13.176,142.608-39.536c45.012-26.361,80.852-61.432,107.497-105.208c3.806-6.659,5.708-13.223,5.708-19.699 C511.626,249.345,509.724,242.778,505.918,236.117z M194.568,158.03c17.034-17.034,37.447-25.554,61.242-25.554 c3.805,0,7.043,1.336,9.709,3.999c2.662,2.664,4,5.901,4,9.707c0,3.809-1.338,7.044-3.994,9.704 c-2.662,2.667-5.902,3.999-9.708,3.999c-16.368,0-30.362,5.808-41.971,17.416c-11.613,11.615-17.416,25.603-17.416,41.971 c0,3.811-1.336,7.044-3.999,9.71c-2.667,2.668-5.901,3.999-9.707,3.999c-3.809,0-7.044-1.334-9.71-3.999 c-2.667-2.666-3.999-5.903-3.999-9.71C169.015,195.482,177.535,175.065,194.568,158.03z M379.867,349.04 c-38.164,23.12-79.514,34.687-124.054,34.687c-44.539,0-85.889-11.56-124.051-34.687s-69.901-54.2-95.215-93.222 c28.931-44.921,65.19-78.518,108.777-100.783c-11.61,19.792-17.417,41.207-17.417,64.236c0,35.216,12.517,65.329,37.544,90.362 s55.151,37.544,90.362,37.544c35.214,0,65.329-12.518,90.362-37.544s37.545-55.146,37.545-90.362 c0-23.029-5.808-44.447-17.419-64.236c43.585,22.265,79.846,55.865,108.776,100.783C449.767,294.84,418.031,325.913,379.867,349.04 z'/></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' width='20px' height='20px'
xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 27.965 27.965'
style='enable-background:new 0 0 27.965 27.965;'>
<path fill='#999'
d='M13.98,0C6.259,0,0,6.261,0,13.983c0,7.721,6.259,13.982,13.98,13.982c7.725,0,13.985-6.262,13.985-13.982 C27.965,6.261,21.705,0,13.98,0z M19.992,17.769l-2.227,2.224c0,0-3.523-3.78-3.786-3.78c-0.259,0-3.783,3.78-3.783,3.78 l-2.228-2.224c0,0,3.784-3.472,3.784-3.781c0-0.314-3.784-3.787-3.784-3.787l2.228-2.229c0,0,3.553,3.782,3.783,3.782 c0.232,0,3.786-3.782,3.786-3.782l2.227,2.229c0,0-3.785,3.523-3.785,3.787C16.207,14.239,19.992,17.769,19.992,17.769z'/>
</svg>

Before

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -8,7 +8,7 @@
<g id="Artboard" fill-rule="nonzero">
<g id="logo-mycrypto">
<g id="Group">
<circle id="Oval" fill="#0e97c0" cx="120.18" cy="121" r="120.18"></circle>
<circle id="Oval" fill="#007896" cx="120.18" cy="121" r="120.18"></circle>
<g transform="translate(39.000000, 51.000000)" fill="#FFFFFF" id="Shape">
<path d="M93.7,100.26 C90.4608521,103.553832 86.034676,105.408954 81.415,105.408954 C76.795324,105.408954 72.3691479,103.553832 69.13,100.26 L53.47,84.43 C51.4545763,82.3796602 48.700035,81.2248104 45.825,81.2248104 C42.949965,81.2248104 40.1954237,82.3796602 38.18,84.43 C31.3962777,91.3322169 31.3962777,102.397783 38.18,109.3 L69.18,140.59 C72.4191479,143.883832 76.845324,145.738954 81.465,145.738954 C86.084676,145.738954 90.5108521,143.883832 93.75,140.59 L124.67,109.26 C131.453722,102.357783 131.453722,91.2922169 124.67,84.39 C122.654576,82.3396602 119.900035,81.1848104 117.025,81.1848104 C114.149965,81.1848104 111.395424,82.3396602 109.38,84.39 L93.7,100.26 Z"></path>
<g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="120px" viewBox="0 0 81 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
<title>Artboard</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="100.099854%" y1="-16.122731%" x2="44.1579795%" y2="77.6511455%" id="linearGradient-1">
<stop stop-color="#2B415B" offset="13.45%"></stop>
<stop stop-color="#3B5676" offset="37.62%"></stop>
<stop stop-color="#54769E" offset="69.23%"></stop>
<stop stop-color="#52749B" offset="79.01%"></stop>
<stop stop-color="#4D6C92" offset="86.14%"></stop>
<stop stop-color="#436082" offset="92.44%"></stop>
<stop stop-color="#364F6C" offset="98.22%"></stop>
<stop stop-color="#314863" offset="100%"></stop>
</linearGradient>
<linearGradient x1="99.7887646%" y1="61.4941149%" x2="-4.60729499%" y2="13.3460499%" id="linearGradient-2">
<stop stop-color="#54769E" offset="0%"></stop>
<stop stop-color="#53749C" offset="48.02%"></stop>
<stop stop-color="#4F6F95" offset="68.78%"></stop>
<stop stop-color="#486588" offset="84.23%"></stop>
<stop stop-color="#435F80" offset="90.95%"></stop>
</linearGradient>
<linearGradient x1="725.856983%" y1="50.0229457%" x2="-347.124022%" y2="50.0229457%" id="linearGradient-3">
<stop stop-color="#20344C" offset="25.39%"></stop>
<stop stop-color="#273D57" offset="40.72%"></stop>
<stop stop-color="#395373" offset="67.33%"></stop>
<stop stop-color="#54769E" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-653.788268%" y1="50.0214562%" x2="455.494413%" y2="50.0214562%" id="linearGradient-4">
<stop stop-color="#54769E" offset="25.39%"></stop>
<stop stop-color="#4D6E93" offset="41.33%"></stop>
<stop stop-color="#3C5777" offset="68.97%"></stop>
<stop stop-color="#233850" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50.0370086%" y1="-209.335792%" x2="49.9575834%" y2="235.965027%" id="linearGradient-5">
<stop stop-color="#54769E" offset="0.6545247%"></stop>
<stop stop-color="#507198" offset="19.93%"></stop>
<stop stop-color="#466488" offset="45.02%"></stop>
<stop stop-color="#354F6D" offset="73.18%"></stop>
<stop stop-color="#21354D" offset="100%"></stop>
</linearGradient>
<linearGradient x1="163.859644%" y1="-95.5767241%" x2="-53.1396713%" y2="173.049483%" id="linearGradient-6">
<stop stop-color="#54769E" offset="25.39%"></stop>
<stop stop-color="#4D6E93" offset="41.02%"></stop>
<stop stop-color="#3C5777" offset="68.13%"></stop>
<stop stop-color="#22364E" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-44.1116757%" y1="-60.1463542%" x2="137.687762%" y2="146.957292%" id="linearGradient-7">
<stop stop-color="#54769E" offset="25.39%"></stop>
<stop stop-color="#4D6E93" offset="41.02%"></stop>
<stop stop-color="#3C5777" offset="68.13%"></stop>
<stop stop-color="#22364E" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-1.43584837%" y1="31.6007047%" x2="127.701745%" y2="103.798097%" id="linearGradient-8">
<stop stop-color="#54769E" offset="26.64%"></stop>
<stop stop-color="#425E7F" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-71.276129%" y1="-65.3137535%" x2="149.174581%" y2="96.3311507%" id="linearGradient-9">
<stop stop-color="#54769E" stop-opacity="0" offset="46.09%"></stop>
<stop stop-color="#52739A" stop-opacity="0.2156" offset="56.99%"></stop>
<stop stop-color="#4A698E" stop-opacity="0.4266" offset="67.64%"></stop>
<stop stop-color="#3D597B" stop-opacity="0.6356" offset="78.2%"></stop>
<stop stop-color="#2C435F" stop-opacity="0.8422" offset="88.63%"></stop>
<stop stop-color="#1B2E45" offset="96.61%"></stop>
</linearGradient>
<linearGradient x1="50.309375%" y1="295.997443%" x2="50.309375%" y2="-124.649242%" id="linearGradient-10">
<stop stop-color="#54769E" offset="25.39%"></stop>
<stop stop-color="#4D6E93" offset="41.02%"></stop>
<stop stop-color="#3C5777" offset="68.13%"></stop>
<stop stop-color="#22364E" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard" fill-rule="nonzero">
<g id="logo-shapeshift">
<polygon id="Shape" fill="#273C51" points="75.9045553 29.0113736 81 0.0349956255 59.7045553 8.88888889 36.3006508 8.88888889 15.0052061 0 20.1357918 29.0113736 15.3214751 45.1793526 19.8546638 48.0139983 0 65.3718285 0 81.67979 22.7010846 112.825897 44.1019523 119.965004 44.1370933 120 60.8642082 111.461067 60.8993492 111.426072 60.8993492 98.7926509 51.4112798 93.6132983 51.4112798 93.6132983 51.4112798 93.6132983 66.3110629 54.1032371 66.2056399 54.1032371 80.683731 45.1793526"></polygon>
<g id="Group">
<polygon id="Shape" fill="url(#linearGradient-1)" points="34.2584416 35.3372093 0 65.2325581 47.7233766 92.5465116 47.8987013 36.244186"></polygon>
<polygon id="Shape" fill="#466284" points="29.3844156 53.8255814 47.7584416 102.697674 47.8987013 56.5465116"></polygon>
<polygon id="Shape" fill="#354D6A" points="66.1675325 54 47.7584416 102.697674 47.8987013 56.5465116"></polygon>
<polygon id="Shape" fill="url(#linearGradient-2)" points="80.8246753 0.104651163 62.5558442 9.6627907 47.9337662 12.8372093 33.1714286 9.6627907 14.9727273 0.0697674419 21.2493506 28.9186047 15.2883117 45.1046512 36.187013 58.0116279 47.7935065 70.5697674 47.7935065 70.6744186 47.8636364 70.6046512 47.9337662 70.6744186 47.9337662 70.5697674 59.5402597 58.0116279 80.5090909 45.1046512 74.5480519 28.9534884"></polygon>
<polygon id="Shape" fill="url(#linearGradient-3)" points="80.8246753 0.104651163 75.7402597 28.9883721 80.5090909 45.1046512 74.5480519 28.9534884"></polygon>
<polygon id="Shape" fill="url(#linearGradient-4)" points="14.9727273 0.0697674419 20.0922078 28.9883721 15.2883117 45.1046512 21.2493506 28.9186047"></polygon>
<polygon id="Shape" fill="url(#linearGradient-5)" points="14.9727273 0.0697674419 36.2220779 8.93023256 59.5753247 8.93023256 80.8246753 0.104651163 62.5558442 9.6627907 47.9337662 12.8372093 33.1714286 9.6627907"></polygon>
<polygon id="Shape" fill="url(#linearGradient-6)" points="21.2493506 28.9186047 20.1974026 31.8139535 42.2532468 11.5813953"></polygon>
<polygon id="Shape" fill="url(#linearGradient-7)" points="74.5480519 28.9534884 53.6493506 11.5813953 75.5649351 31.6744186"></polygon>
<polygon id="Shape" fill="url(#linearGradient-8)" points="0 65.2325581 51.3 93.3837209 57.787013 109.534884 44.0415584 114.732558 22.6519481 112.534884 0 81.4883721"></polygon>
<polygon id="Shape" fill="#FFFFFF" points="42.4636364 88.5348837 22.7220779 112.465116 22.6519481 112.534884 44.0064935 119.651163 44.0415584 119.686047 60.7324675 111.174419 60.7675325 111.139535 60.7675325 98.5465116"></polygon>
<polygon id="Shape" fill="url(#linearGradient-9)" points="74.5480519 28.9534884 80.8246753 0.104651163 62.5558442 9.6627907 53.6493506 11.5813953"></polygon>
<polygon id="Shape" fill="#FFFFFF" points="47.8987013 70.6744186 42.112987 64.3604651 47.8987013 58.0116279 53.7194805 64.3604651"></polygon>
<polygon id="Shape" fill="url(#linearGradient-10)" points="47.3376623 12.6976744 47.9337662 12.8372093 48.4597403 12.7325581 47.8987013 49.5348837"></polygon>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -54,7 +54,7 @@
<path d="M82.77,744.06 L87.55,710.06 C87.8071361,708.226119 86.9908966,706.407071 85.45,705.38 C78.3717357,700.699197 75.198423,691.93208 77.6408657,683.805198 C80.0833084,675.678315 87.5640273,670.113147 96.05,670.11 C96.64,670.11 97.2,670.23 97.78,670.28 C88.9158298,664.439589 76.9954116,666.89083 71.1550005,675.755 C65.3145894,684.61917 67.7658301,696.539589 76.63,702.38 C78.1708966,703.407071 78.9871361,705.226119 78.73,707.06 L73.53,744.06 L82.77,744.06 Z" id="Shape" fill="#000000" opacity="0.1"></path>
<g id="mycrypto__circ__blue-on-navy__64" transform="translate(116.000000, 0.000000)">
<g id="Oval">
<use fill="#0E97C0" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill="#007896" fill-rule="evenodd" xlink:href="#path-1"></use>
<circle stroke="#000000" stroke-width="10" cx="145" cy="145" r="140"></circle>
</g>
<g id="Shape">
@ -69,4 +69,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -32,7 +32,7 @@
<rect id="Rectangle-path" fill="#FFCE00" x="40.72" y="256.52" width="16" height="48"></rect>
</g>
<g id="mycrypto__circ__blue-on-navy__64" transform="translate(216.000000, 191.000000)">
<circle id="Oval" fill="#0E97C0" cx="37" cy="37" r="37"></circle>
<circle id="Oval" fill="#007896" cx="37" cy="37" r="37"></circle>
<g id="Shape">
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
<path stroke="#000000" stroke-width="2" d="M48.7644965,40.0113785 C49.7178355,40.010501 50.6345076,40.3752222 51.3145109,41.0314555 C53.5618297,43.2182135 53.5618297,46.7390341 51.3110373,48.9291558 L41.5069096,58.3771804 C40.4445637,59.4168045 38.9938635,60.0003162 37.4823951,59.9999999 C35.9705083,60.0003162 34.5198081,59.4168045 33.4616659,58.3812702 L23.6854891,48.9257921 C21.4381703,46.7390341 21.4381703,43.2182135 23.6838532,41.033051 C24.3665268,40.3657303 25.2975124,39.9945561 26.2579466,40.0000451 C27.2198046,39.9987497 28.1441246,40.3696137 28.8202797,41.0305404 L33.7601132,45.8246431 C34.7441958,46.7780599 36.0942246,47.317442 37.505938,47.317442 C38.9176514,47.317442 40.2676802,46.7780599 41.2528603,45.8235816 L46.2009116,41.0443696 C46.8793196,40.3812496 47.8031089,40.0104213 48.7644965,40.0113785 Z"></path>
@ -44,4 +44,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -13,7 +13,7 @@
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<circle stroke="#0E97C0" stroke-width="20" cx="170" cy="170" r="160"></circle>
<circle stroke="#007896" stroke-width="20" cx="170" cy="170" r="160"></circle>
<rect id="Rectangle" fill="#FFE14D" mask="url(#mask-2)" x="-1.13333333" y="1.13333333" width="173.4" height="340"></rect>
<rect id="Rectangle" fill="#FFCC33" mask="url(#mask-2)" x="171.133333" y="1.13333333" width="173.4" height="340"></rect>
<circle id="Oval-2" stroke="#333333" stroke-width="20" mask="url(#mask-2)" cx="170" cy="170" r="160"></circle>
@ -23,7 +23,7 @@
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<circle stroke="#0E97C0" stroke-width="20" cx="170" cy="170" r="160"></circle>
<circle stroke="#007896" stroke-width="20" cx="170" cy="170" r="160"></circle>
<rect id="Rectangle" fill="#6EA6E8" mask="url(#mask-4)" x="-1.13333333" y="1.13333333" width="173.4" height="340"></rect>
<rect id="Rectangle" fill="#5C9BE4" mask="url(#mask-4)" x="171.133333" y="1.13333333" width="173.4" height="340"></rect>
<circle id="Oval-2" stroke="#333333" stroke-width="20" mask="url(#mask-4)" cx="170" cy="170" r="160"></circle>
@ -41,4 +41,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="330px" height="330px" viewBox="0 0 330 330" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 46 (44423) - http://www.bohemiancoding.com/sketch -->
<title>Group 3</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-3">
<circle id="Oval-2" fill="#000000" cx="164.912047" cy="164.912047" r="164.912047"></circle>
<g id="Group-2" transform="translate(164.934365, 164.978810) rotate(-315.000000) translate(-164.934365, -164.978810) translate(65.924073, 66.000110)" fill="#FFFFFF">
<g id="Group">
<path d="M20.5676823,0 L75.3319399,0 C86.6911571,-2.08665436e-15 95.8996221,9.20846501 95.8996221,20.5676823 L95.8996221,75.3319399 C95.8996221,86.6911571 86.6911571,95.8996221 75.3319399,95.8996221 L20.5676823,95.8996221 C9.20846501,95.8996221 1.3911029e-15,86.6911571 0,75.3319399 L0,20.5676823 C-1.3911029e-15,9.20846501 9.20846501,2.08665436e-15 20.5676823,0 Z M47.9498111,65.9309902 C57.8805421,65.9309902 65.9309902,57.8805421 65.9309902,47.9498111 C65.9309902,38.01908 57.8805421,29.9686319 47.9498111,29.9686319 C38.01908,29.9686319 29.9686319,38.01908 29.9686319,47.9498111 C29.9686319,57.8805421 38.01908,65.9309902 47.9498111,65.9309902 Z" id="Combined-Shape"></path>
<path d="M122.460048,7.71386383 C115.360537,7.71386383 109.605246,13.4691545 109.605246,20.5686652 L109.605246,75.3329229 C109.605246,82.4324336 115.360537,88.1877243 122.460048,88.1877243 L177.224305,88.1877243 C184.323816,88.1877243 190.079107,82.4324336 190.079107,75.3329229 L190.079107,20.5686652 C190.079107,13.4691545 184.323816,7.71386383 177.224305,7.71386383 L122.460048,7.71386383 Z M122.460048,0.000982982783 L177.224305,0.000982982783 C188.583523,0.000982982783 197.791988,9.20944799 197.791988,20.5686652 L197.791988,75.3329229 C197.791988,86.6921401 188.583523,95.9006051 177.224305,95.9006051 L122.460048,95.9006051 C111.100831,95.9006051 101.892366,86.6921401 101.892366,75.3329229 L101.892366,20.5686652 C101.892366,9.20944799 111.100831,0.000982982783 122.460048,0.000982982783 Z" id="Combined-Shape" fill-rule="nonzero"></path>
<circle id="Oval" cx="149.842177" cy="47.9507941" r="17.9811792"></circle>
<path d="M20.5676823,101.893349 L75.3319399,101.893349 C86.6911571,101.893349 95.8996221,111.101814 95.8996221,122.461031 L95.8996221,177.225288 C95.8996221,188.584506 86.6911571,197.792971 75.3319399,197.792971 L20.5676823,197.792971 C9.20846501,197.792971 1.3911029e-15,188.584506 0,177.225288 L0,122.461031 C-1.3911029e-15,111.101814 9.20846501,101.893349 20.5676823,101.893349 Z M47.9498111,167.824339 C57.8805421,167.824339 65.9309902,159.773891 65.9309902,149.84316 C65.9309902,139.912429 57.8805421,131.86198 47.9498111,131.86198 C38.01908,131.86198 29.9686319,139.912429 29.9686319,149.84316 C29.9686319,159.773891 38.01908,167.824339 47.9498111,167.824339 Z" id="Combined-Shape"></path>
<path d="M122.461031,101.893349 L177.225288,101.893349 C188.584506,101.893349 197.792971,111.101814 197.792971,122.461031 L197.792971,177.225288 C197.792971,188.584506 188.584506,197.792971 177.225288,197.792971 L122.461031,197.792971 C111.101814,197.792971 101.893349,188.584506 101.893349,177.225288 L101.893349,122.461031 C101.893349,111.101814 111.101814,101.893349 122.461031,101.893349 Z M149.84316,167.824339 C159.773891,167.824339 167.824339,159.773891 167.824339,149.84316 C167.824339,139.912429 159.773891,131.86198 149.84316,131.86198 C139.912429,131.86198 131.86198,139.912429 131.86198,149.84316 C131.86198,159.773891 139.912429,167.824339 149.84316,167.824339 Z" id="Combined-Shape"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -1,36 +0,0 @@
// Mixins
// --------------------------------------------------
// Utilities
@import "mixins/hide-text.less";
@import "mixins/opacity.less";
@import "mixins/image.less";
@import "mixins/labels.less";
@import "mixins/reset-filter.less";
@import "mixins/resize.less";
@import "mixins/responsive-visibility.less";
@import "mixins/size.less";
@import "mixins/tab-focus.less";
@import "mixins/reset-text.less";
@import "mixins/text-emphasis.less";
@import "mixins/text-overflow.less";
@import "mixins/vendor-prefixes.less";
// Components
@import "mixins/alerts.less";
@import "mixins/buttons.less";
@import "mixins/panels.less";
@import "mixins/pagination.less";
@import "mixins/list-group.less";
@import "mixins/nav-divider.less";
@import "mixins/forms.less";
@import "mixins/progress-bar.less";
@import "mixins/table-row.less";
// Skins
@import "mixins/background-variant.less";
@import "mixins/border-radius.less";
@import "mixins/gradients.less";
// Layout
@import "mixins/clearfix.less";
@import "mixins/center-block.less";
@import "mixins/nav-vertical-align.less";
@import "mixins/grid-framework.less";
@import "mixins/grid.less";

View File

@ -1,14 +0,0 @@
// Alerts
.alert-variant(@background; @border; @text-color) {
background-color: @background;
border-color: @border;
color: @text-color;
hr {
border-top-color: darken(@border, 5%);
}
.alert-link {
color: darken(@text-color, 10%);
}
}

View File

@ -1,9 +0,0 @@
// Contextual backgrounds
.bg-variant(@color) {
background-color: @color;
a&:hover,
a&:focus {
background-color: darken(@color, 10%);
}
}

View File

@ -1,21 +0,0 @@
// Single side border-radius
.border-top-radius(@radius) {
border-top-right-radius: @radius;
border-top-left-radius: @radius;
}
.border-right-radius(@radius) {
border-bottom-right-radius: @radius;
border-top-right-radius: @radius;
}
.border-bottom-radius(@radius) {
border-bottom-right-radius: @radius;
border-bottom-left-radius: @radius;
}
.border-left-radius(@radius) {
border-bottom-left-radius: @radius;
border-top-left-radius: @radius;
}

View File

@ -1,73 +0,0 @@
// Button variants
//
// Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons
.button-variant(@color; @background; @border) {
color: @color;
background-color: @background;
border-color: @border;
transition: all ease 250ms;
&:focus,
&.focus {
color: @color;
background-color: darken(@background, 5%);
border-color: darken(@border, 5%);
transition: all ease 250ms;
}
&:hover {
color: @color;
background-color: darken(@background, 5%);
border-color: darken(@border, 5%);
transition: all ease 250ms;
}
&:active,
&.active,
.open > .dropdown-toggle& {
color: @color;
background-color: darken(@background, 5%);
border-color: darken(@border, 5%);
transition: all ease 250ms;
&:hover,
&:focus,
&.focus {
color: @color;
background-color: darken(@background, 15%);
border-color: darken(@border, 15%);
transition: all ease 250ms;
}
}
&:active,
&.active,
.open > .dropdown-toggle& {
background-image: none;
}
&.disabled,
&[disabled],
fieldset[disabled] & {
&,
&:hover,
&:focus,
&.focus,
&:active,
&.active {
background-color: @background;
border-color: @border;
}
}
.badge {
color: @background;
background-color: @color;
}
}
// Button sizes
.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
padding: @padding-vertical @padding-horizontal;
font-size: @font-size;
line-height: @line-height;
border-radius: @border-radius;
}

View File

@ -1,7 +0,0 @@
// Center-align a block level element
.center-block() {
display: block;
margin-left: auto;
margin-right: auto;
}

View File

@ -1,22 +0,0 @@
// Clearfix
//
// For modern browsers
// 1. The space content is one way to avoid an Opera bug when the
// contenteditable attribute is included anywhere else in the document.
// Otherwise it causes space to appear at the top and bottom of elements
// that are clearfixed.
// 2. The use of `table` rather than `block` is only necessary if using
// `:before` to contain the top-margins of child elements.
//
// Source: http://nicolasgallagher.com/micro-clearfix-hack/
.clearfix() {
&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}
}

View File

@ -1,83 +0,0 @@
// Form validation states
//
// Used in forms.less to generate the form validation CSS for warnings, errors,
// and successes.
.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {
// Color the label and help text
.help-block,
.control-label,
.radio,
.checkbox,
.radio-inline,
.checkbox-inline,
&.radio label,
&.checkbox label,
&.radio-inline label,
&.checkbox-inline label {
color: @text-color;
}
// Set the border and box shadow on specific inputs to match
.form-control {
border-color: @border-color;
.box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075)); // Redeclare so transitions work
&:focus {
border-color: darken(@border-color, 10%);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 3px rgba(@brand-primary, .5);
}
}
// Set validation states also for addons
.input-group-addon {
color: @text-color;
border-color: @border-color;
background-color: @background-color;
}
// Optional feedback icon
.form-control-feedback {
color: @text-color;
}
}
// Form control focus state
//
// Generate a customized focus state and for any input with the specified color,
// which defaults to the `@input-border-focus` variable.
//
// We highly encourage you to not customize the default value, but instead use
// this to tweak colors on an as-needed basis. This aesthetic change is based on
// WebKit's default styles, but applicable to a wider range of browsers. Its
// usability and accessibility should be taken into account with any change.
//
// Example usage: change the default blue border and shadow to white for better
// contrast against a dark gray background.
.form-control-focus(@color: @input-border-focus) {
@color-rgba: rgba(red(@color), green(@color), blue(@color), .6);
&:focus {
border-color: @color;
outline: 0;
.box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}");
}
}
// Form control sizing
//
// Relative text size, padding, and border-radii changes for form controls. For
// horizontal sizing, wrap controls in the predefined grid classes. `<select>`
// element gets special love because it's special, and that's a fact!
.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
height: @input-height;
padding: @padding-vertical @padding-horizontal;
font-size: @font-size;
line-height: @line-height;
border-radius: @border-radius;
select& {
height: @input-height;
line-height: @input-height;
}
textarea&,
select[multiple] & {
height: auto;
}
}

View File

@ -1,59 +0,0 @@
// Gradients
#gradient {
// Horizontal gradient, from left to right
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
// Color stops are not available in IE9 and below.
.horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+
background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12
background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
background-repeat: repeat-x;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)", argb(@start-color), argb(@end-color))); // IE9 and down
}
// Vertical gradient, from top to bottom
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
// Color stops are not available in IE9 and below.
.vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+
background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12
background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
background-repeat: repeat-x;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)", argb(@start-color), argb(@end-color))); // IE9 and down
}
.directional(@start-color: #555; @end-color: #333; @deg: 45deg) {
background-repeat: repeat-x;
background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+
background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12
background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
}
.horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);
background-repeat: no-repeat;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)", argb(@start-color), argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
}
.vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);
background-repeat: no-repeat;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)", argb(@start-color), argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
}
.radial(@inner-color: #555; @outer-color: #333) {
background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);
background-image: radial-gradient(circle, @inner-color, @outer-color);
background-repeat: no-repeat;
}
.striped(@color: rgba(255,255,255,.15); @angle: 45deg) {
background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
}
}

View File

@ -1,96 +0,0 @@
// Framework grid generation
//
// Used only by Bootstrap to generate the correct number of grid classes given
// any value of `@grid-columns`.
.make-grid-columns() {
// Common styles for all sizes of grid columns, widths 1-12
.col(@index) { // initial
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
.col((@index + 1), @item);
}
.col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
.col((@index + 1), ~"@{list}, @{item}");
}
.col(@index, @list) when (@index > @grid-columns) { // terminal
@{list} {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (@grid-gutter-width / 2);
padding-right: (@grid-gutter-width / 2);
}
}
.col(1); // kickstart it
}
.float-grid-columns(@class) {
.col(@index) { // initial
@item: ~".col-@{class}-@{index}";
.col((@index + 1), @item);
}
.col(@index, @list) when (@index =< @grid-columns) { // general
@item: ~".col-@{class}-@{index}";
.col((@index + 1), ~"@{list}, @{item}");
}
.col(@index, @list) when (@index > @grid-columns) { // terminal
@{list} {
float: left;
}
}
.col(1); // kickstart it
}
.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
.col-@{class}-@{index} {
width: percentage((@index / @grid-columns));
}
}
.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {
.col-@{class}-push-@{index} {
left: percentage((@index / @grid-columns));
}
}
.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {
.col-@{class}-push-0 {
left: auto;
}
}
.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {
.col-@{class}-pull-@{index} {
right: percentage((@index / @grid-columns));
}
}
.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {
.col-@{class}-pull-0 {
right: auto;
}
}
.calc-grid-column(@index, @class, @type) when (@type = offset) {
.col-@{class}-offset-@{index} {
margin-left: percentage((@index / @grid-columns));
}
}
// Basic looping in LESS
.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
.calc-grid-column(@index, @class, @type);
// next iteration
.loop-grid-columns((@index - 1), @class, @type);
}
// Create grid for specific class
.make-grid(@class) {
.float-grid-columns(@class);
.loop-grid-columns(@grid-columns, @class, width);
.loop-grid-columns(@grid-columns, @class, pull);
.loop-grid-columns(@grid-columns, @class, push);
.loop-grid-columns(@grid-columns, @class, offset);
}

View File

@ -1,134 +0,0 @@
// Grid system
//
// Generate semantic grid columns with these mixins.
// Centered container element
.container-fixed(@gutter: @grid-gutter-width) {
margin-right: auto;
margin-left: auto;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
&:extend(.clearfix all);
}
// Creates a wrapper for a series of columns
.make-row(@gutter: @grid-gutter-width) {
margin-left: (@gutter / -2);
margin-right: (@gutter / -2);
&:extend(.clearfix all);
}
// Generate the extra small columns
.make-xs-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
float: left;
width: percentage((@columns / @grid-columns));
min-height: 1px;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
}
.make-xs-column-offset(@columns) {
margin-left: percentage((@columns / @grid-columns));
}
.make-xs-column-push(@columns) {
left: percentage((@columns / @grid-columns));
}
.make-xs-column-pull(@columns) {
right: percentage((@columns / @grid-columns));
}
// Generate the small columns
.make-sm-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
min-height: 1px;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
@media (min-width: @screen-sm-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
.make-sm-column-offset(@columns) {
@media (min-width: @screen-sm-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-sm-column-push(@columns) {
@media (min-width: @screen-sm-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-sm-column-pull(@columns) {
@media (min-width: @screen-sm-min) {
right: percentage((@columns / @grid-columns));
}
}
// Generate the medium columns
.make-md-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
min-height: 1px;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
@media (min-width: @screen-md-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
.make-md-column-offset(@columns) {
@media (min-width: @screen-md-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-md-column-push(@columns) {
@media (min-width: @screen-md-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-md-column-pull(@columns) {
@media (min-width: @screen-md-min) {
right: percentage((@columns / @grid-columns));
}
}
// Generate the large columns
.make-lg-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
min-height: 1px;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
@media (min-width: @screen-lg-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
.make-lg-column-offset(@columns) {
@media (min-width: @screen-lg-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-lg-column-push(@columns) {
@media (min-width: @screen-lg-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-lg-column-pull(@columns) {
@media (min-width: @screen-lg-min) {
right: percentage((@columns / @grid-columns));
}
}

View File

@ -1,21 +0,0 @@
// CSS image replacement
//
// Heads up! v3 launched with only `.hide-text()`, but per our pattern for
// mixins being reused as classes with the same name, this doesn't hold up. As
// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.
//
// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
// Deprecated as of v3.0.1 (will be removed in v4)
.hide-text() {
font: ~"0/0" a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
// New mixin to use as of v3.0.1
.text-hide() {
.hide-text();
}

View File

@ -1,25 +0,0 @@
// Image Mixins
// - Responsive image
// - Retina image
// Responsive image
//
// Keep images from scaling beyond the width of their parents.
.img-responsive(@display: block) {
display: @display;
max-width: 100%; // Part 1: Set a maximum relative to the parent
height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
}
// Retina image
//
// Short retina mixin for setting background-image and -size. Note that the
// spelling of `min--moz-device-pixel-ratio` is intentional.
.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {
background-image: url("@{file-1x}");
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and ( min-device-pixel-ratio: 2), only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) {
background-image: url("@{file-2x}");
background-size: @width-1x @height-1x;
}
}

View File

@ -1,12 +0,0 @@
// Labels
.label-variant(@color) {
background-color: @color;
&[href] {
&:hover,
&:focus {
background-color: darken(@color, 10%);
}
}
}

View File

@ -1,30 +0,0 @@
// List Groups
.list-group-item-variant(@state; @background; @color) {
.list-group-item-@{state} {
color: @color;
background-color: @background;
a&,
button& {
color: @color;
.list-group-item-heading {
color: inherit;
}
&:hover,
&:focus {
color: @color;
background-color: darken(@background, 5%);
}
&.active,
&.active:hover,
&.active:focus {
color: #fff;
background-color: @color;
border-color: @color;
}
}
}
}

View File

@ -1,10 +0,0 @@
// Horizontal dividers
//
// Dividers (basically an hr) within dropdowns and nav lists
.nav-divider(@color: #e5e5e5) {
height: 1px;
margin: 2px 0;
overflow: hidden;
background-color: @color;
}

View File

@ -1,9 +0,0 @@
// Navbar vertical align
//
// Vertically center elements in the navbar.
// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
.navbar-vertical-align(@element-height) {
margin-top: ((@navbar-height - @element-height) / 2);
margin-bottom: ((@navbar-height - @element-height) / 2);
}

View File

@ -1,8 +0,0 @@
// Opacity
.opacity(@opacity) {
opacity: @opacity;
// IE8 filter
@opacity-ie: (@opacity * 100);
filter: ~"alpha(opacity=@{opacity-ie})";
}

View File

@ -1,24 +0,0 @@
// Pagination
.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
> li {
> a,
> span {
padding: @padding-vertical @padding-horizontal;
font-size: @font-size;
line-height: @line-height;
}
&:first-child {
> a,
> span {
.border-left-radius(@border-radius);
}
}
&:last-child {
> a,
> span {
.border-right-radius(@border-radius);
}
}
}
}

View File

@ -1,24 +0,0 @@
// Panels
.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {
border-color: @border;
& > .panel-heading {
color: @heading-text-color;
background-color: @heading-bg-color;
border-color: @heading-border;
+ .panel-collapse > .panel-body {
border-top-color: @border;
}
.badge {
color: @heading-bg-color;
background-color: @heading-text-color;
}
}
& > .panel-footer {
+ .panel-collapse > .panel-body {
border-bottom-color: @border;
}
}
}

View File

@ -1,10 +0,0 @@
// Progress bars
.progress-bar-variant(@color) {
background-color: @color;
// Deprecated parent class requirement as of v3.2.0
.progress-striped & {
#gradient > .striped();
}
}

View File

@ -1,8 +0,0 @@
// Reset filters for IE
//
// When you need to remove a gradient background, do not forget to use this to reset
// the IE filter for IE9 and below.
.reset-filter() {
filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
}

View File

@ -1,18 +0,0 @@
.reset-text() {
font-family: @font-family-base;
// We deliberately do NOT reset font-size.
font-style: normal;
font-weight: normal;
letter-spacing: normal;
line-break: auto;
line-height: @line-height-base;
text-align: left; // Fallback for where `start` is not supported
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
white-space: normal;
word-break: normal;
word-spacing: normal;
word-wrap: normal;
}

View File

@ -1,6 +0,0 @@
// Resize anything
.resizable(@direction) {
resize: @direction; // Options: horizontal, vertical, both
overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
}

View File

@ -1,21 +0,0 @@
// Responsive utilities
//
// More easily include all the states for responsive-utilities.less.
.responsive-visibility() {
display: block !important;
table& {
display: table !important;
}
tr& {
display: table-row !important;
}
th&,
td& {
display: table-cell !important;
}
}
.responsive-invisibility() {
display: none !important;
}

View File

@ -1,10 +0,0 @@
// Sizing shortcuts
.size(@width; @height) {
width: @width;
height: @height;
}
.square(@size) {
.size(@size; @size);
}

View File

@ -1,6 +0,0 @@
// WebKit-style focus
.tab-focus() {
outline: thin dotted;
outline-offset: 3px;
}

View File

@ -1,28 +0,0 @@
// Tables
.table-row-variant(@state; @background) {
// Exact selectors below required to override `.table-striped` and prevent
// inheritance to nested tables.
.table > thead > tr,
.table > tbody > tr,
.table > tfoot > tr {
> td.@{state},
> th.@{state},
&.@{state} > td,
&.@{state} > th {
background-color: @background;
}
}
// Hover states for `.table-hover`
// Note: this is not available for cells or rows within `thead` or `tfoot`.
.table-hover > tbody > tr {
> td.@{state}:hover,
> th.@{state}:hover,
&.@{state}:hover > td,
&:hover > .@{state},
&.@{state}:hover > th {
background-color: darken(@background, 5%);
}
}
}

View File

@ -1,9 +0,0 @@
// Typography
.text-emphasis-variant(@color) {
color: @color;
a&:hover,
a&:focus {
color: darken(@color, 5%);
}
}

View File

@ -1,8 +0,0 @@
// Text overflow
// Requires inline-block or block for proper styling
.text-overflow() {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@ -1,254 +0,0 @@
// Vendor Prefixes
//
// All vendor mixins are deprecated as of v3.2.0 due to the introduction of
// Autoprefixer in our Gruntfile. They will be removed in v4.
// - Animations
// - Backface visibility
// - Box shadow
// - Box sizing
// - Content columns
// - Hyphens
// - Placeholder text
// - Transformations
// - Transitions
// - User Select
// Animations
.animation(@animation) {
-webkit-animation: @animation;
-o-animation: @animation;
animation: @animation;
}
.animation-name(@name) {
-webkit-animation-name: @name;
animation-name: @name;
}
.animation-duration(@duration) {
-webkit-animation-duration: @duration;
animation-duration: @duration;
}
.animation-timing-function(@timing-function) {
-webkit-animation-timing-function: @timing-function;
animation-timing-function: @timing-function;
}
.animation-delay(@delay) {
-webkit-animation-delay: @delay;
animation-delay: @delay;
}
.animation-iteration-count(@iteration-count) {
-webkit-animation-iteration-count: @iteration-count;
animation-iteration-count: @iteration-count;
}
.animation-direction(@direction) {
-webkit-animation-direction: @direction;
animation-direction: @direction;
}
.animation-fill-mode(@fill-mode) {
-webkit-animation-fill-mode: @fill-mode;
animation-fill-mode: @fill-mode;
}
// Backface visibility
// Prevent browsers from flickering when using CSS 3D transforms.
// Default value is `visible`, but can be changed to `hidden`
.backface-visibility(@visibility) {
-webkit-backface-visibility: @visibility;
-moz-backface-visibility: @visibility;
backface-visibility: @visibility;
}
// Drop shadows
//
// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
// supported browsers that have box shadow capabilities now support it.
.box-shadow(@shadow) {
-webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
box-shadow: @shadow;
}
// Box sizing
.box-sizing(@boxmodel) {
-webkit-box-sizing: @boxmodel;
-moz-box-sizing: @boxmodel;
box-sizing: @boxmodel;
}
// CSS3 Content Columns
.content-columns(@column-count; @column-gap: @grid-gutter-width) {
-webkit-column-count: @column-count;
-moz-column-count: @column-count;
column-count: @column-count;
-webkit-column-gap: @column-gap;
-moz-column-gap: @column-gap;
column-gap: @column-gap;
}
// Optional hyphenation
.hyphens(@mode: auto) {
word-wrap: break-word;
-webkit-hyphens: @mode;
-moz-hyphens: @mode;
-ms-hyphens: @mode; // IE10+
-o-hyphens: @mode;
hyphens: @mode;
}
// Placeholder text
.placeholder(@color: @input-color-placeholder) {
// Firefox
&::-moz-placeholder {
color: @color;
opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
}
&:-ms-input-placeholder {
color: @color;
}
// Internet Explorer 10+
&::-webkit-input-placeholder {
color: @color;
}
// Safari and Chrome
}
// Transformations
.scale(@ratio) {
-webkit-transform: scale(@ratio);
-ms-transform: scale(@ratio); // IE9 only
-o-transform: scale(@ratio);
transform: scale(@ratio);
}
.scale(@ratioX; @ratioY) {
-webkit-transform: scale(@ratioX, @ratioY);
-ms-transform: scale(@ratioX, @ratioY); // IE9 only
-o-transform: scale(@ratioX, @ratioY);
transform: scale(@ratioX, @ratioY);
}
.scaleX(@ratio) {
-webkit-transform: scaleX(@ratio);
-ms-transform: scaleX(@ratio); // IE9 only
-o-transform: scaleX(@ratio);
transform: scaleX(@ratio);
}
.scaleY(@ratio) {
-webkit-transform: scaleY(@ratio);
-ms-transform: scaleY(@ratio); // IE9 only
-o-transform: scaleY(@ratio);
transform: scaleY(@ratio);
}
.skew(@x; @y) {
-webkit-transform: skewX(@x) skewY(@y);
-ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
-o-transform: skewX(@x) skewY(@y);
transform: skewX(@x) skewY(@y);
}
.translate(@x; @y) {
-webkit-transform: translate(@x, @y);
-ms-transform: translate(@x, @y); // IE9 only
-o-transform: translate(@x, @y);
transform: translate(@x, @y);
}
.translate3d(@x; @y; @z) {
-webkit-transform: translate3d(@x, @y, @z);
transform: translate3d(@x, @y, @z);
}
.rotate(@degrees) {
-webkit-transform: rotate(@degrees);
-ms-transform: rotate(@degrees); // IE9 only
-o-transform: rotate(@degrees);
transform: rotate(@degrees);
}
.rotateX(@degrees) {
-webkit-transform: rotateX(@degrees);
-ms-transform: rotateX(@degrees); // IE9 only
-o-transform: rotateX(@degrees);
transform: rotateX(@degrees);
}
.rotateY(@degrees) {
-webkit-transform: rotateY(@degrees);
-ms-transform: rotateY(@degrees); // IE9 only
-o-transform: rotateY(@degrees);
transform: rotateY(@degrees);
}
.perspective(@perspective) {
-webkit-perspective: @perspective;
-moz-perspective: @perspective;
perspective: @perspective;
}
.perspective-origin(@perspective) {
-webkit-perspective-origin: @perspective;
-moz-perspective-origin: @perspective;
perspective-origin: @perspective;
}
.transform-origin(@origin) {
-webkit-transform-origin: @origin;
-moz-transform-origin: @origin;
-ms-transform-origin: @origin; // IE9 only
transform-origin: @origin;
}
// Transitions
.transition(@transition) {
-webkit-transition: @transition;
-o-transition: @transition;
transition: @transition;
}
.transition-property(@transition-property) {
-webkit-transition-property: @transition-property;
transition-property: @transition-property;
}
.transition-delay(@transition-delay) {
-webkit-transition-delay: @transition-delay;
transition-delay: @transition-delay;
}
.transition-duration(@transition-duration) {
-webkit-transition-duration: @transition-duration;
transition-duration: @transition-duration;
}
.transition-timing-function(@timing-function) {
-webkit-transition-timing-function: @timing-function;
transition-timing-function: @timing-function;
}
.transition-transform(@transition) {
-webkit-transition: -webkit-transform @transition;
-moz-transition: -moz-transform @transition;
-o-transition: -o-transform @transition;
transition: transform @transition;
}
// User select
// For selecting text on the page
.user-select(@select) {
-webkit-user-select: @select;
-moz-user-select: @select;
-ms-user-select: @select; // IE10+
user-select: @select;
}

View File

@ -1,373 +0,0 @@
img {
max-width: 100%;
height: auto;
}
textarea {
resize: vertical;
}
// anouncement bars
.announcement {
padding: 3px 10px;
text-align: center;
font-weight: 300;
color: white;
display: block;
background-color: @brand-primary;
a {
text-decoration: underline;
color: white;
transition: 250ms all ease;
}
&:hover,
&:focus {
transition: 250ms all ease;
color: darken(white, 5%);
text-decoration: none;
background-color: darken(@brand-primary, 5%);
}
strong {
font-weight: 400;
}
}
.annoucement-warning {
background-color: @brand-danger;
&:hover,
&:focus {
background-color: darken(@brand-danger, 5%);
a,
a:hover {
text-decoration: none;
}
}
}
.annoucement-danger {
background-color: @brand-danger;
a:hover,
a:focus {
color: darken(white, 5%);
a,
a:hover {
text-decoration: none;
}
}
}
// address icenticons
.address-identicon-container {
padding-left: 0;
padding-top: @space-md;
text-align: left;
@media screen and (max-width: @grid-float-breakpoint) {
padding-left: @space-lg;
padding-right: @space-lg;
padding-top: 0;
}
}
.address-identicon-container-right {
padding-right: 0;
padding-top: @space-md;
text-align: right;
.addressIdenticon {
float: right;
}
@media screen and (max-width: @grid-float-breakpoint) {
padding-left: @space-lg;
padding-right: @space-lg;
padding-top: 0;
}
}
.address-identicon-container-offline {
padding: 0;
margin-left: -15px;
}
.addressIdenticon {
width: 4rem;
height: 4rem;
background-size: cover;
background-repeat: no-repeat;
border-radius: 50%;
box-shadow: inset rgba(255, 255, 255, 0.5) 0 2px 2px,
inset rgba(0, 0, 0, 0.6) 0 -1px 8px;
}
.addressIdenticon.med {
width: 3rem;
height: 3rem;
}
.addressIdenticon.small {
width: 2rem;
height: 2rem;
}
.addressIdenticon.inline {
display: inline-block;
}
.addressIdenticon.float {
float: left;
margin-right: @space-sm;
}
// helpers
.wrap {
word-wrap: break-word;
}
.bigger-on-mobile.form-control[readonly] {
height: 60px;
@media screen and (max-width: 767px) {
height: 100px;
}
}
// help page
#paneHelp {
h3 {
margin-top: 2em;
}
}
// monospace things
.mono,
.form-control,
#accountAddress,
#accountBalance,
#accountBalanceUsd,
#accountBalanceEur,
#accountBalanceBtc,
#accountBalancePopMB-0,
#accountBalancePopMB-2,
#accountAddressMainTbl-1 {
font-family: @font-family-monospace;
font-weight: normal;
letter-spacing: .02em;
}
// QR Code on Offline Transactions Page
.offline-qrcode {
margin-top: -150px;
max-width: 300px;
@media screen and (max-width: 942px) {
margin-top: -78px;
}
@media screen and (max-width: 769px) {
margin-top: 0;
}
}
// collapsable containers
.collapse-container {
h2,
h4 {
cursor: pointer;
}
.collapse-button {
float: left;
font-weight: 500;
user-select: none;
padding: 10px;
margin: -10px -35px;
font-size: 24px;
line-height: 1.6;
}
}
// help collapsable containers
.help .collapse-container {
margin: 40px 0;
.collapse-button {
margin: -10px -30px;
font-size: 20px;
line-height: 1;
}
}
// little x image next to custom tokens
.token-remove {
width: @font-size-small;
height: @font-size-small;
position: absolute;
left: 18px;
cursor: pointer;
}
.node-remove {
width: 16px;
height: 16px;
position: absolute;
right: 6px;
top: 8px;
}
.m-addresses td:first-child {
max-width: 50px;
min-width: 50px;
}
.m-addresses td:last-child {
text-align: right;
}
h2 a.isActive {
color: #333;
cursor: default;
&:hover,
&:active {
color: #333;
cursor: default;
}
}
.item {
margin: 6px 0;
}
.output.well {
padding: @space-sm @space;
margin-top: -@space/2;
p {
margin: @space-sm 0;
}
}
label small {
color: @gray-light;
}
.write-address {
.col-xs-1 {
padding: 0;
}
.col-xs-11 {
padding-right: 10px;
}
}
.write-boolean label {
display: block;
}
.decrypt-drtv {
padding: @space 0;
label.radio {
padding: 0 @space-lg;
}
}
.qr-code {
max-width: 17rem;
margin: auto;
}
.qr-pkey-container {
position: relative;
}
.qr-overlay {
background-color: black;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.contracts {
h4 + .dropdown,
h4 + .dropdown .btn {
margin-top: 0;
}
a.isActive {
color: @text-color;
}
.dropdown-toggle {
display: block;
text-align: left;
white-space: normal;
.caret {
position: absolute;
right: @space;
top: 1.25rem;
}
}
.dropdown-menu-left {
font-size: @font-size-small;
left: auto;
right: 0;
min-width: 37rem;
small {
float: right;
}
}
}
.view-wallet-content {
@media screen and (min-width: @grid-float-breakpoint) {
padding-left: @space*3;
}
h5 {
margin-bottom: @space-xs;
}
a.isActive {
color: @text-color;
}
}
#selectedTypeLedger ol {
padding-left: 1rem;
}
.loading-wrap {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: fadeOut(black, 30%);
z-index: 999;
text-align: center;
.loading {
position: absolute;
text-align: center;
top: 40%;
left: 50%;
transform: translate(-50%, -60%);
}
img {
border-radius: 50%;
}
h1 {
animation: opacity 2000ms infinite ease-in-out;
color: white;
}
@keyframes opacity {
from,
to {
opacity: 0;
}
50% {
opacity: 1;
}
}
}
.embedded-logo {
height: auto;
width: 100%;
max-width: 290px;
padding: .5rem 0;
}
.ens-response {
color: @gray;
}

View File

@ -1,28 +0,0 @@
#etherWalletPopUp {
padding: 10px;
position: relative;
min-width: 346px;
.back-icon {
position: absolute;
left: 5px;
top: 5px;
&:hover,
&:active {
outline: 0;
}
}
}
.quicksend-address {
font-family: @font-family-monospace;
max-width: 170px;
word-wrap: break-word;
font-size: 12px;
font-weight: 300;
display: block;
}
.chrome-tokens span {
display: inline-block;
}

View File

@ -1,7 +0,0 @@
@import 'etherwallet-variables.less';
// Core variables and mixins
@import 'bootstrap/mixins.less';
// Utility classes
@import 'etherwallet-custom.less';
@import 'etherwallet-ext-custom.less';
@import 'etherwallet-utilities.less';

View File

@ -1,92 +0,0 @@
/* Custom Utilities */
.text-navy {
color: @ether-navy;
}
.text-gray-lighter {
color: @gray-lighter;
}
.text-blue {
color: @ether-blue;
}
.text-white {
color: #fff;
}
.bg-navy {
background: @ether-navy;
}
.bg-gray-lighter {
background-color: @gray-lighter;
}
.bg-blue {
background-color: @ether-blue;
}
.bg-white {
background-color: #fff;
}
.text-serif {
font-family: @font-family-serif;
}
.text-sans-serif {
font-family: @font-family-sans-serif;
}
.pad-v-sm {
padding-top: .5em;
padding-bottom: .5em;
}
.pad-v-md {
padding-top: 1em;
padding-bottom: 1em;
}
.pad-v-lg {
padding-top: 1.5em;
padding-bottom: 1.5em;
}
.pad-v-xl {
padding-top: 2em;
padding-bottom: 2em;
}
.marg-v-sm {
margin-top: .5em;
margin-bottom: .5em;
}
.marg-v-md {
margin-top: 1em;
margin-bottom: 1em;
}
.marg-v-lg {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
.marg-v-xl {
margin-top: 2em;
margin-bottom: 2em;
}
.img-fill {
width: 100%;
height: auto;
max-width: 100%;
}
.no-scroll {
height: 100%;
overflow: hidden;
}

View File

@ -1,362 +0,0 @@
// Colors
@ether-navy: #163151;
@ether-blue: #0e97c0;
@space-xs: 0.25rem;
@space-sm: 0.5rem;
@space-md: 0.75rem;
@space: 1rem;
@space-lg: 1.5rem;
@space-xl: 2rem;
@gray-base: #000;
@gray-darker: lighten(@gray-base, 13.5%);
@gray-dark: lighten(@gray-base, 20%);
@gray: #737373;
@gray-light: #9a9a9a;
@gray-lighter: #ececec;
@gray-lightest: #fafafa;
@brand-primary: @ether-blue;
@brand-success: #5dba5a;
@brand-info: @ether-navy;
@brand-warning: #ff9800;
@brand-danger: #ea4b40;
@body-bg: #fff;
@text-color: @gray-dark;
@link-color: @brand-primary;
@link-hover-color: darken(@link-color, 5%);
@link-hover-decoration: none;
@transition: 500ms all ease-in-out;
// Typography
@font-family-sans-serif: 'Lato', sans-serif;
@font-family-serif: Georgia, 'Times New Roman', Times, serif;
@font-family-monospace: 'Roboto Mono', Menlo, Monaco, Consolas, 'Courier New', monospace;
@font-family-base: @font-family-sans-serif;
@base: 15;
@font-size-pixels: @base+px;
@font-size-pixels-xl: @base+1px; // for xl screens
@font-size-pixels-sm: @base+px; // for small screens
@font-size-large-bump: 2.25rem; // 33.75
@font-size-large: 1.9rem; // 28.5
@font-size-medium-bump: 1.5rem; // 22.5
@font-size-medium: 1.3rem; // 19.5
@font-size-bump-more: 1.15rem; // 17.25
@font-size-bump: 1.07rem; // 16.05
@font-size-base: 1rem; // 15
@font-size-small: 0.92rem; // 13.8
@font-size-xs: 0.8rem; // 12
@font-size-h1: @font-size-large-bump;
@font-size-h2: @font-size-large;
@font-size-h3: @font-size-medium-bump;
@font-size-h4: @font-size-medium;
@font-size-h5: @font-size-bump-more;
@font-size-h6: @font-size-bump;
@line-height-base: 1.4;
@line-height-computed: 1.4;
@headings-font-family: inherit;
@headings-font-weight: 700;
@headings-line-height: 1.2;
@headings-color: inherit;
// Spacing
@padding-base-vertical: @space*.6;
@padding-base-horizontal: @space;
@padding-large-vertical: @space-md;
@padding-large-horizontal: @space-xl;
@padding-small-vertical: 0.1rem;
@padding-small-horizontal: @space-sm;
@padding-xs-vertical: @space-xs;
@padding-xs-horizontal: 0.2rem;
@line-height-large: 1.2;
@line-height-small: 1.5;
@border-radius: 2px;
@component-active-color: #fff;
@component-active-bg: @brand-primary;
@caret-width-base: @space-xs;
@caret-width-large: @space-xs;
// Tables
@table-cell-padding: @space-sm;
@table-condensed-cell-padding: @space-xs;
@table-bg: transparent;
@table-bg-accent: #f9f9f9;
@table-bg-hover: @gray-lightest;
@table-bg-active: @table-bg-hover;
@table-border-color: #ddd;
// Buttons
@btn-font-weight: normal;
@btn-default-color: #333;
@btn-default-bg: #ececec;
@btn-default-border: @gray-lighter;
@btn-primary-color: #fff;
@btn-primary-bg: @brand-primary;
@btn-primary-border: darken(@btn-primary-bg, 5%);
@btn-success-color: #fff;
@btn-success-bg: @brand-success;
@btn-success-border: darken(@btn-success-bg, 5%);
@btn-info-color: #fff;
@btn-info-bg: @brand-info;
@btn-info-border: darken(@btn-info-bg, 5%);
@btn-warning-color: #fff;
@btn-warning-bg: @brand-warning;
@btn-warning-border: darken(@btn-warning-bg, 5%);
@btn-danger-color: #fff;
@btn-danger-bg: @brand-danger;
@btn-danger-border: darken(@btn-danger-bg, 5%);
@btn-link-disabled-color: @gray-light;
// Forms
@input-bg: #fff;
@input-bg-disabled: @gray-lightest;
@input-color: @gray;
@input-border: @gray-lighter;
@input-border-focus: @brand-primary;
@input-color-placeholder: darken(@gray-lighter, 10%);
@input-height-base: 2.55rem;
@input-height-large: 4rem;
@input-height-small: 2rem;
@form-group-margin-bottom: @space-sm;
@legend-color: @gray-dark;
@legend-border-color: #e5e5e5;
@input-group-addon-bg: @gray-lighter;
@input-group-addon-border-color: @input-border;
@cursor-disabled: default;
@dropdown-bg: #fff;
@dropdown-border: rgba(0, 0, 0, 0.15);
@dropdown-fallback-border: @gray-lighter;
@dropdown-divider-bg: #e5e5e5;
@dropdown-link-color: @ether-navy;
@dropdown-link-hover-color: @ether-blue;
@dropdown-link-hover-bg: @gray-lightest;
@dropdown-link-active-color: @component-active-color;
@dropdown-link-active-bg: @component-active-bg;
@dropdown-link-disabled-color: @gray-light;
@dropdown-header-color: @gray-light;
@dropdown-caret-color: #000;
@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;
@screen-xs: 32rem;
@screen-xs-min: @screen-xs;
@screen-sm: 51.2rem;
@screen-sm-min: @screen-sm;
@screen-md: 66.133333333rem;
@screen-md-min: @screen-md;
@screen-lg: 80rem;
@screen-lg-min: @screen-lg;
@screen-xl: 94rem;
@screen-xl-min: @screen-xl;
@screen-xs-max: (@screen-sm-min - 1);
@screen-sm-max: (@screen-md-min - 1);
@screen-md-max: (@screen-lg-min - 1);
@screen-lg-max: (@screen-xl-min - 1);
@grid-columns: 12;
@grid-gutter-width: 3rem;
@grid-float-breakpoint: @screen-sm-min;
@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
@cont-padding: 5%;
@cont-padding-lg: 7.5%;
@container-tablet: (@screen-sm + @grid-gutter-width);
@container-sm: @container-tablet;
@container-desktop: (@screen-md + @grid-gutter-width);
@container-md: @container-desktop;
@container-large-desktop: (@screen-lg + @grid-gutter-width);
@container-lg: @container-large-desktop;
@state-success-text: darken(@brand-success, 10%);
@state-success-bg: #dff0d8;
@state-success-border: darken(spin(@state-success-bg, -10), 5%);
@state-info-text: darken(@brand-info, 10%);
@state-info-bg: #d9edf7;
@state-info-border: darken(spin(@state-info-bg, -10), 7%);
@state-warning-text: darken(@brand-warning, 10%);
@state-warning-bg: #fcf8e3;
@state-warning-border: darken(spin(@state-warning-bg, -10), 5%);
@state-danger-text: darken(@brand-danger, 10%);
@state-danger-bg: #f2dede;
@state-danger-border: darken(spin(@state-danger-bg, -10), 5%);
@tooltip-max-width: 200px;
@tooltip-color: #fff;
@tooltip-bg: #000;
@tooltip-opacity: 0.9;
@tooltip-arrow-width: @space-sm;
@tooltip-arrow-color: @tooltip-bg;
@label-default-bg: @gray-light;
@label-primary-bg: @brand-primary;
@label-success-bg: @brand-success;
@label-info-bg: @brand-info;
@label-warning-bg: @brand-warning;
@label-danger-bg: @brand-danger;
@label-color: #fff;
@label-link-hover-color: #fff;
@modal-inner-padding: @space*1.5;
@modal-title-padding: @space;
@modal-title-line-height: @line-height-base;
@modal-content-bg: #fff;
@modal-content-border-color: rgba(0, 0, 0, 0.2);
@modal-content-fallback-border-color: #999;
@modal-backdrop-bg: #000;
@modal-backdrop-opacity: 0.5;
@modal-header-border-color: #e5e5e5;
@modal-footer-border-color: @modal-header-border-color;
@modal-lg: 70rem;
@modal-md: 50rem;
@modal-sm: 30rem;
@alert-border-radius: @border-radius;
@alert-link-font-weight: bold;
@alert-success-bg: @brand-success;
@alert-success-text: white;
@alert-success-border: @alert-success-bg;
@alert-info-bg: @brand-primary;
@alert-info-text: white;
@alert-info-border: @alert-info-bg;
@alert-warning-bg: @brand-warning;
@alert-warning-text: white;
@alert-warning-border: @alert-warning-bg;
@alert-danger-bg: @brand-danger;
@alert-danger-text: white;
@alert-danger-border: @alert-danger-bg;
@progress-bg: @gray-lightest;
@progress-bar-color: #fff;
@progress-border-radius: @border-radius;
@progress-bar-bg: @brand-primary;
@progress-bar-success-bg: @brand-success;
@progress-bar-warning-bg: @brand-warning;
@progress-bar-danger-bg: @brand-danger;
@progress-bar-info-bg: @brand-info;
@list-group-bg: #fff;
@list-group-border: #ddd;
@list-group-border-radius: @border-radius;
@list-group-hover-bg: @gray-lightest;
@list-group-active-color: @component-active-color;
@list-group-active-bg: @component-active-bg;
@list-group-active-border: @list-group-active-bg;
@list-group-active-text-color: lighten(@list-group-active-bg, 40%);
@list-group-disabled-color: @gray-light;
@list-group-disabled-bg: @gray-lighter;
@list-group-disabled-text-color: @list-group-disabled-color;
@list-group-link-color: #555;
@list-group-link-hover-color: @list-group-link-color;
@list-group-link-heading-color: #333;
@thumbnail-padding: 4px;
@thumbnail-bg: @body-bg;
@thumbnail-border: #ddd;
@thumbnail-border-radius: @border-radius;
@thumbnail-caption-color: @text-color;
@thumbnail-caption-padding: 9px;
@well-bg: @gray-lightest;
@well-border: darken(@well-bg, 7%);
@badge-font-weight: bold;
@badge-line-height: 1;
@badge-border-radius: 10px;
@close-font-weight: bold;
@close-color: #000;
@close-text-shadow: 0 1px 0 #fff;
@code-color: #c7254e;
@code-bg: #f9f2f4;
@kbd-color: #fff;
@kbd-bg: #333;
@pre-bg: @gray-lightest;
@pre-color: @gray-dark;
@pre-border-color: @gray-lighter;
@pre-scrollable-max-height: 340px;
@component-offset-horizontal: 180px;
@text-muted: @gray-light;
@abbr-border-color: @gray-light;
@headings-small-color: inherit;
@blockquote-small-color: @gray-light;
@blockquote-font-size: (@font-size-base * 1.25);
@blockquote-border-color: @gray-lighter;
@page-header-border-color: @gray-lighter;
@dl-horizontal-offset: @component-offset-horizontal;
@hr-border: @gray-lighter;

View File

@ -1,6 +1,8 @@
import React from 'react';
import { AddressFieldFactory } from './AddressFieldFactory';
import { donationAddressMap } from 'config';
import translate from 'translations';
import { Input } from 'components/ui';
interface Props {
isReadOnly?: boolean;
@ -9,16 +11,20 @@ interface Props {
export const AddressField: React.SFC<Props> = ({ isReadOnly }) => (
<AddressFieldFactory
withProps={({ currentTo, isValid, onChange, readOnly }) => (
<React.Fragment>
<input
className={`form-control ${isValid ? 'is-valid' : 'is-invalid'}`}
type="text"
value={currentTo.raw}
placeholder={donationAddressMap.ETH}
readOnly={!!(isReadOnly || readOnly)}
onChange={onChange}
/>
</React.Fragment>
<div className="input-group-wrapper">
<label className="input-group">
<div className="input-group-header">{translate('SEND_ADDR_SHORT')}</div>
<Input
className={`input-group-input ${isValid ? '' : 'invalid'}`}
type="text"
value={currentTo.raw}
placeholder={donationAddressMap.ETH}
readOnly={!!(isReadOnly || readOnly)}
spellCheck={false}
onChange={onChange}
/>
</label>
</div>
)}
/>
);

View File

@ -1,6 +1,5 @@
import React, { Component } from 'react';
import { Identicon, Spinner } from 'components/ui';
import translate from 'translations';
import { Query } from 'components/renderCbs';
import { ICurrentTo, getCurrentTo, isValidCurrentTo } from 'selectors/transaction';
import { connect } from 'react-redux';
@ -49,7 +48,6 @@ class AddressInputFactoryClass extends Component<Props> {
return (
<div className="row form-group">
<div className="col-xs-11">
<label>{translate('SEND_addr')}:</label>
<Query
params={['readOnly']}
withQuery={({ readOnly }) =>

View File

@ -1,66 +0,0 @@
import React from 'react';
import './index.scss';
const LS_KEY = 'acknowledged-alpha';
interface State {
isFading: boolean;
hasAcknowledged: boolean;
}
export default class AlphaAgreement extends React.PureComponent<{}, State> {
public state = {
hasAcknowledged: !!localStorage.getItem(LS_KEY),
isFading: false
};
public render() {
if (this.state.hasAcknowledged) {
return null;
}
const isFading = this.state.isFading ? 'is-fading' : '';
return (
<div className={`AlphaAgreement ${isFading}`}>
<div className="AlphaAgreement-content">
<h2>This is an Unstable Version of MyCrypto</h2>
<p>
You are about to access a beta version of MyCrypto that is currently in development. In
its current state, it should only be used for testing, not for important transactions.
</p>
<p>
Any wallets you generate should not hold a significant value, and any transactions you
make should be for small amounts. MyCrypto does not claim responsibility for any issues
that happen while using the beta version.
</p>
<p>Are you sure you would like to continue?</p>
<div className="AlphaAgreement-content-buttons">
<button className="AlphaAgreement-content-buttons-btn is-reject" onClick={this.reject}>
No, take me to prod
</button>
<button
className="AlphaAgreement-content-buttons-btn is-continue"
onClick={this.doContinue}
>
Yes, continue to beta
</button>
</div>
</div>
</div>
);
}
private doContinue = () => {
localStorage.setItem(LS_KEY, 'true');
this.setState({ isFading: true });
setTimeout(() => {
this.setState({ hasAcknowledged: true });
}, 1000);
};
private reject = () => {
window.location.assign('https://mycrypto.com');
};
}

View File

@ -1,7 +1,8 @@
import React from 'react';
import { AmountFieldFactory } from './AmountFieldFactory';
import { UnitDropDown } from 'components';
import translate, { translateRaw } from 'translations';
import translate from 'translations';
import { Input } from 'components/ui';
interface Props {
hasUnitDropdown?: boolean;
@ -16,25 +17,28 @@ export const AmountField: React.SFC<Props> = ({
}) => (
<AmountFieldFactory
withProps={({ currentValue: { raw }, isValid, onChange, readOnly }) => (
<React.Fragment>
<label>{translate('SEND_amount')}</label>
<div className="input-group">
<input
className={`form-control ${
isAmountValid(raw, customValidator, isValid) ? 'is-valid' : 'is-invalid'
<div className="input-group-wrapper">
<label className="input-group input-group-inline">
<div className="input-group-header">{translate('SEND_AMOUNT_SHORT')}</div>
<Input
className={`input-group-input ${
isAmountValid(raw, customValidator, isValid) ? '' : 'invalid'
}`}
type="number"
placeholder={translateRaw('SEND_amount_short')}
placeholder={'1'}
value={raw}
readOnly={!!readOnly}
onChange={onChange}
/>
{hasUnitDropdown && <UnitDropDown showAllTokens={showAllTokens} />}
</div>
</React.Fragment>
</label>
</div>
)}
/>
);
const isAmountValid = (raw, customValidator, isValid) =>
customValidator ? customValidator(raw) : isValid;
const isAmountValid = (
raw: string,
customValidator: ((rawAmount: string) => boolean) | undefined,
isValid: boolean
) => (customValidator ? customValidator(raw) : isValid);

View File

@ -2,6 +2,28 @@
@import 'common/sass/mixins';
.AccountInfo {
&-copy {
display: inline-block;
cursor: pointer;
color: $text-color;
font-size: $font-size-xs;
opacity: 0.5;
transition: $transition;
&:hover{
opacity: 1;
}
&.is-copied{
color: $brand-success;
opacity: 1;
}
.fa {
margin-right: $space-xs;
}
}
&-section {
margin-top: $space * 1.5;
@ -63,6 +85,7 @@
}
&-addr {
margin-top: -$space-xs;
word-wrap: break-word;
@include mono;
}

View File

@ -1,14 +1,16 @@
import { Identicon, UnitDisplay } from 'components/ui';
import { IWallet, Balance, TrezorWallet, LedgerWallet } from 'libs/wallet';
import React from 'react';
import { connect } from 'react-redux';
import { toChecksumAddress } from 'ethereumjs-util';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { Identicon, UnitDisplay, Address, NewTabLink } from 'components/ui';
import { IWallet, Balance, TrezorWallet, LedgerWallet } from 'libs/wallet';
import translate from 'translations';
import './AccountInfo.scss';
import Spinner from 'components/ui/Spinner';
import { getNetworkConfig, getOffline } from 'selectors/config';
import { AppState } from 'reducers';
import { connect } from 'react-redux';
import { NetworkConfig } from 'types/network';
import { TSetAccountBalance, setAccountBalance } from 'actions/wallet';
import './AccountInfo.scss';
interface OwnProps {
wallet: IWallet;
@ -24,6 +26,7 @@ interface State {
showLongBalance: boolean;
address: string;
confirmAddr: boolean;
copied: boolean;
}
interface DispatchProps {
@ -36,11 +39,12 @@ class AccountInfo extends React.Component<Props, State> {
public state = {
showLongBalance: false,
address: '',
confirmAddr: false
confirmAddr: false,
copied: false
};
public async setAddressFromWallet() {
const address = await this.props.wallet.getAddressString();
public setAddressFromWallet() {
const address = this.props.wallet.getAddressString();
if (address !== this.state.address) {
this.setState({ address });
}
@ -69,6 +73,17 @@ class AccountInfo extends React.Component<Props, State> {
});
};
public onCopy = () => {
this.setState(state => {
return {
copied: !state.copied
};
});
setTimeout(() => {
this.setState({ copied: false });
}, 2000);
};
public render() {
const { network, balance, isOffline } = this.props;
const { address, showLongBalance, confirmAddr } = this.state;
@ -83,13 +98,24 @@ class AccountInfo extends React.Component<Props, State> {
const wallet = this.props.wallet as LedgerWallet | TrezorWallet;
return (
<div className="AccountInfo">
<h5 className="AccountInfo-section-header">{translate('sidebar_AccountAddr')}</h5>
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_ACCOUNTADDR')}</h5>
<div className="AccountInfo-section AccountInfo-address-section">
<div className="AccountInfo-address-icon">
<Identicon address={address} size="100%" />
</div>
<div className="AccountInfo-address-wrapper">
<div className="AccountInfo-address-addr">{address}</div>
<div className="AccountInfo-address-addr">
<Address address={address} />
</div>
<CopyToClipboard onCopy={this.onCopy} text={toChecksumAddress(address)}>
<div
className={`AccountInfo-copy ${this.state.copied ? 'is-copied' : ''}`}
title="Copy To clipboard"
>
<i className="fa fa-copy" />
<span>{this.state.copied ? 'copied!' : 'copy address'}</span>
</div>
</CopyToClipboard>
</div>
</div>
@ -108,7 +134,9 @@ class AccountInfo extends React.Component<Props, State> {
});
}}
>
{confirmAddr ? null : 'Display address on ' + wallet.getWalletType()}
{confirmAddr
? null
: translate('SIDEBAR_DISPLAY_ADDR', { $wallet: wallet.getWalletType() })}
</a>
{confirmAddr ? (
<span className="AccountInfo-address-confirm">
@ -119,7 +147,7 @@ class AccountInfo extends React.Component<Props, State> {
)}
<div className="AccountInfo-section">
<h5 className="AccountInfo-section-header">{translate('sidebar_AccountBal')}</h5>
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_ACCOUNTBAL')}</h5>
<ul className="AccountInfo-list">
<li className="AccountInfo-list-item AccountInfo-balance">
<span
@ -134,17 +162,21 @@ class AccountInfo extends React.Component<Props, State> {
symbol={balance.wei ? network.name : null}
/>
</span>
{balance.isPending ? (
<Spinner />
) : (
!isOffline && (
<button
className="AccountInfo-section-refresh"
onClick={this.props.setAccountBalance}
>
<i className="fa fa-refresh" />
</button>
)
{balance.wei && (
<React.Fragment>
{balance.isPending ? (
<Spinner />
) : (
!isOffline && (
<button
className="AccountInfo-section-refresh"
onClick={this.props.setAccountBalance}
>
<i className="fa fa-refresh" />
</button>
)
)}
</React.Fragment>
)}
</li>
</ul>
@ -152,28 +184,20 @@ class AccountInfo extends React.Component<Props, State> {
{(!!blockExplorer || !!tokenExplorer) && (
<div className="AccountInfo-section">
<h5 className="AccountInfo-section-header">{translate('sidebar_TransHistory')}</h5>
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_TRANSHISTORY')}</h5>
<ul className="AccountInfo-list">
{!!blockExplorer && (
<li className="AccountInfo-list-item">
<a
href={blockExplorer.addressUrl(address)}
target="_blank"
rel="noopener noreferrer"
>
<NewTabLink href={blockExplorer.addressUrl(address)}>
{`${network.name} (${blockExplorer.origin})`}
</a>
</NewTabLink>
</li>
)}
{!!tokenExplorer && (
<li className="AccountInfo-list-item">
<a
href={tokenExplorer.address(address)}
target="_blank"
rel="noopener noreferrer"
>
<NewTabLink href={tokenExplorer.address(address)}>
{`Tokens (${tokenExplorer.name})`}
</a>
</NewTabLink>
</li>
)}
</ul>

View File

@ -41,7 +41,6 @@
flex-wrap: nowrap;
align-items: center;
&-fiat-symbol {
height: 18px;
width: 18px;
margin-right: 0.5rem;
text-align: center;

View File

@ -8,7 +8,6 @@ import { chain, flatMap } from 'lodash';
import { TokenBalance, getShownTokenBalances } from 'selectors/wallet';
import { Balance } from 'libs/wallet';
import './EquivalentValues.scss';
import { Wei } from 'libs/units';
import { AppState } from 'reducers';
import { getNetworkConfig, getOffline } from 'selectors/config';
import { connect } from 'react-redux';
@ -16,6 +15,7 @@ import btcIco from 'assets/images/bitcoin.png';
import ethIco from 'assets/images/ether.png';
import repIco from 'assets/images/augur.png';
import { NetworkConfig } from 'types/network';
import BN from 'bn.js';
interface AllValue {
symbol: string;
@ -51,6 +51,14 @@ interface DispatchProps {
fetchCCRates: TFetchCCRatesRequested;
}
interface FiatSymbols {
[key: string]: string;
}
interface Rates {
[rate: string]: number;
}
type Props = StateProps & DispatchProps;
class EquivalentValues extends React.Component<Props, State> {
@ -81,11 +89,12 @@ class EquivalentValues extends React.Component<Props, State> {
}
public componentWillReceiveProps(nextProps: Props) {
const { balance, tokenBalances, isOffline } = this.props;
const { balance, tokenBalances, isOffline, network } = this.props;
if (
nextProps.balance !== balance ||
nextProps.tokenBalances !== tokenBalances ||
nextProps.isOffline !== isOffline
nextProps.isOffline !== isOffline ||
nextProps.network.unit !== network.unit
) {
const defaultOption = this.defaultOption(
nextProps.balance,
@ -109,7 +118,7 @@ class EquivalentValues extends React.Component<Props, State> {
}
}
public selectOption = equivalentValues => {
public selectOption = (equivalentValues: Option) => {
this.setState({ equivalentValues });
};
@ -119,28 +128,38 @@ class EquivalentValues extends React.Component<Props, State> {
const isFetching =
!balance || balance.isPending || !tokenBalances || Object.keys(rates).length === 0;
const pairRates = this.generateValues(equivalentValues.label, equivalentValues.value);
const fiatSymbols = {
const fiatSymbols: FiatSymbols = {
USD: '$',
EUR: '€',
GBP: '£',
CHF: ' '
};
const coinAndTokenSymbols = {
const coinAndTokenSymbols: any = {
BTC: btcIco,
ETH: ethIco,
REP: repIco
};
interface ValueProps {
className: string;
rate: string;
value: BN | null;
symbol?: string;
icon?: string;
key?: number | string;
}
const Value = ({ className = '', rate, value, symbol = '', icon = '' }) => (
<div className={`EquivalentValues-values-currency ${className}`}>
<img src={icon} />
{!!symbol && <span className="EquivalentValues-values-currency-fiat-symbol">{symbol}</span>}
<span className="EquivalentValues-values-currency-label">{rate}</span>{' '}
const Value = (props: ValueProps) => (
<div className={`EquivalentValues-values-currency ${props.className}`}>
<img src={props.icon} />
{!!props.symbol && (
<span className="EquivalentValues-values-currency-fiat-symbol">{props.symbol}</span>
)}
<span className="EquivalentValues-values-currency-label">{props.rate}</span>{' '}
<span className="EquivalentValues-values-currency-value">
<UnitDisplay
unit={'ether'}
value={value}
displayShortBalance={rateSymbols.isFiat(rate) ? 2 : 3}
value={props.value}
displayShortBalance={rateSymbols.isFiat(props.rate) ? 2 : 3}
checkOffline={true}
/>
</span>
@ -150,13 +169,13 @@ class EquivalentValues extends React.Component<Props, State> {
return (
<div className="EquivalentValues">
<div className="EquivalentValues-header">
<h5 className="EquivalentValues-title">{translate('sidebar_Equiv')}</h5>
<h5 className="EquivalentValues-title">{translate('SIDEBAR_EQUIV')}</h5>
<Select
name="equivalentValues"
// TODO: Update type
value={equivalentValues as any}
options={options as any}
onChange={this.selectOption}
onChange={this.selectOption as any}
clearable={false}
searchable={false}
/>
@ -164,13 +183,11 @@ class EquivalentValues extends React.Component<Props, State> {
{isOffline ? (
<div className="EquivalentValues-offline well well-sm">
Equivalent values are unavailable offline
{translate('EQUIV_VALS_OFFLINE')}
</div>
) : network.isTestnet ? (
<div className="text-center">
<h5 style={{ color: 'red' }}>
On test network, equivalent values will not be displayed.
</h5>
<h5 style={{ color: 'red' }}>{translate('EQUIV_VALS_TESTNET')}</h5>
</div>
) : ratesError ? (
<h5>{ratesError}</h5>
@ -209,7 +226,7 @@ class EquivalentValues extends React.Component<Props, State> {
)}
</React.Fragment>
) : (
<p>Sorry, equivalent values are not supported for this unit.</p>
<p>{translate('EQUIV_VALS_UNSUPPORTED_UNIT')}</p>
)}
</div>
)}
@ -223,7 +240,7 @@ class EquivalentValues extends React.Component<Props, State> {
const allRates = Object.values(balance).map(
value => !!rates[value.symbol] && rates[value.symbol]
);
const allEquivalentValues = allRates.map((rateType, i) => {
const allEquivalentValues = allRates.map((rateType: any, i) => {
return {
symbol: Object.keys(rates)[i],
equivalentValues: [
@ -259,9 +276,9 @@ class EquivalentValues extends React.Component<Props, State> {
// return equivalent value (unit * rate * balance)
private handleValues(unit: string, balance: Balance['wei']) {
const { rates } = this.props;
const ratesObj = { ...rates[unit] };
const ratesObj: Rates = { ...rates[unit] };
return Object.keys(ratesObj).map(key => {
const value = (balance as Wei).muln(ratesObj[key]);
const value = balance!.muln(ratesObj[key]);
return { rate: key, value };
});
}
@ -288,7 +305,8 @@ class EquivalentValues extends React.Component<Props, State> {
const currencies = tokenBalances
.filter(tk => !tk.balance.isZero())
.map(tk => tk.symbol)
.sort();
.sort()
.concat([props.network.unit]);
// If it's the same currencies as we have, skip it
if (this.requestedCurrencies && currencies.join() === this.requestedCurrencies.join()) {

View File

@ -1,17 +0,0 @@
import React from 'react';
import { Link } from 'react-router-dom';
import BityLogo from 'assets/images/logo-bity-white.svg';
export const Bity: React.SFC = () => (
<Link className="Promos-promo Promos-Bity" target="_blank" rel="noopener noreferrer" to="/swap">
<div className="Promos-promo-inner">
<div className="Promos-promo-text">
<p>Its now easier to get more ETH</p>
<h5>Swap BTC &lt;-&gt; ETH</h5>
</div>
<div className="Promos-promo-images">
<img src={BityLogo} />
</div>
</div>
</Link>
);

View File

@ -1,12 +1,15 @@
import React from 'react';
import CoinbaseLogo from 'assets/images/logo-coinbase.svg';
import { NewTabLink } from 'components/ui';
export const Coinbase: React.SFC = () => (
<a
className="Promos-promo Promos-Coinbase"
target="_blank"
rel="noopener noreferrer"
href="https://buy.coinbase.com?code=60c05061-3a76-57be-b1cd-a7afa97bcb8c&address=0xA7DeFf12461661212734dB35AdE9aE7d987D648c&crypto_currency=ETH&currency=USD"
interface Props {
address: string;
}
export const Coinbase: React.SFC<Props> = ({ address }) => (
<NewTabLink
className="Promos-promo Promos--coinbase"
href={`https://buy.coinbase.com?code=60c05061-3a76-57be-b1cd-a7afa97bcb8c&address=${address}&crypto_currency=ETH&currency=USD`}
>
<div className="Promos-promo-inner">
<div className="Promos-promo-text">
@ -14,8 +17,8 @@ export const Coinbase: React.SFC = () => (
<h5 key="2">Buy ETH with USD</h5>
</div>
<div className="Promos-promo-images">
<img src={CoinbaseLogo} />
<img src={CoinbaseLogo} alt="Coinbase logo" />
</div>
</div>
</a>
</NewTabLink>
);

View File

@ -5,17 +5,14 @@ import ledgerLogo from 'assets/images/logo-ledger.svg';
import trezorLogo from 'assets/images/logo-trezor.svg';
export const HardwareWallets: React.SFC = () => (
<HelpLink
className="Promos-promo Promos-HardwareWallets"
article={HELP_ARTICLE.PROTECT_YOUR_FUNDS}
>
<HelpLink className="Promos-promo Promos--hardware" article={HELP_ARTICLE.PROTECT_YOUR_FUNDS}>
<div className="Promos-promo-inner">
<div className="Promos-promo-text">
<h6>Learn more about protecting your funds.</h6>
</div>
<div className="Promos-promo-images">
<img src={ledgerLogo} />
<img src={trezorLogo} />
<img src={ledgerLogo} alt="Ledger Logo" />
<img src={trezorLogo} alt="Trezor Logo" />
</div>
</div>
</HelpLink>

View File

@ -0,0 +1,20 @@
import React from 'react';
import { Link } from 'react-router-dom';
import ShapeshiftLogo from 'assets/images/logo-shapeshift.svg';
export const Shapeshift: React.SFC = () => (
<Link className="Promos-promo Promos--shapeshift" to="/swap">
<div className="Promos-promo-inner">
<div className="Promos-promo-text">
<h5>
Exchange Coins
<br />
& Tokens with
</h5>
</div>
<div className="Promos-promo-images">
<img src={ShapeshiftLogo} alt="Shapeshift Logo" />
</div>
</div>
</Link>
);

View File

@ -1,3 +1,3 @@
export * from './HardwareWallets';
export * from './Coinbase';
export * from './Bity';
export * from './Shapeshift';

View File

@ -9,18 +9,6 @@
overflow: hidden;
}
&-Bity {
background-color: #006e79;
}
&-Coinbase {
background-color: #2b71b1;
}
&-HardwareWallets {
background-color: #6e9a3e;
}
&-promo {
position: relative;
height: inherit;
@ -42,19 +30,18 @@
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 50%;
left: 0;
width: 100%;
transform: translateY(-50%);
}
&-text,
&-images {
padding: 0 $space-sm;
padding: 0 $space;
}
&-text {
flex: 1;
flex: 5;
padding-right: $space-xs;
max-width: 220px;
p,
h4,
@ -73,15 +60,15 @@
}
&-images {
padding: 0 $space * 1.5;
flex: 3;
max-width: 108px;
padding-left: $space-xs;
img {
display: block;
margin: 0 auto;
width: 100%;
max-width: 96px;
height: auto;
padding: $space-xs;
}
}
}
@ -98,7 +85,6 @@
height: 12px;
border: 3px solid $gray-lightest;
border-radius: 100%;
outline: none;
opacity: 0.6;
&.is-active {
@ -106,6 +92,23 @@
}
}
}
// Per-promo customizations
&--shapeshift {
background-color: #263a52;
.Promos-promo-images {
max-width: 130px;
}
}
&--coinbase {
background-color: #2b71b1;
}
&--hardware {
background-color: #6e9a3e;
}
}
.carousel-exit {

View File

@ -1,22 +1,30 @@
import React from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import { HardwareWallets, Coinbase, Bity } from './PromoComponents';
import { HardwareWallets, Coinbase, Shapeshift } from './PromoComponents';
import './Promos.scss';
import { connect } from 'react-redux';
import { AppState } from '../../reducers';
const promos = [HardwareWallets, Coinbase, Bity];
const CarouselAnimation = ({ children, ...props }) => (
const CarouselAnimation = ({ children, ...props }: any) => (
<CSSTransition {...props} timeout={300} classNames="carousel">
{children}
</CSSTransition>
);
// Don't change Coinbase index
const promos = [HardwareWallets, Coinbase, Shapeshift];
interface State {
activePromo: number;
}
export default class Promos extends React.PureComponent<{}, State> {
interface StateProps {
wallet: AppState['wallet']['inst'];
}
class PromosClass extends React.PureComponent<StateProps, State> {
public timer: any = null;
public promos = [HardwareWallets, Coinbase, Shapeshift];
public state = {
activePromo: parseInt(String(Math.random() * promos.length), 10)
@ -30,17 +38,27 @@ export default class Promos extends React.PureComponent<{}, State> {
clearInterval(this.timer);
}
public getPromo() {
const { activePromo } = this.state;
const { wallet } = this.props;
if (activePromo === 1) {
if (wallet) {
return <Coinbase address={wallet.getAddressString()} />;
} else {
return <Shapeshift />;
}
} else {
return promos[activePromo];
}
}
public render() {
const { activePromo } = this.state;
return (
<div className="Promos">
<TransitionGroup className="Promos-promo-wrapper">
{promos
.filter(i => {
return i === promos[activePromo];
})
.map(promo => <CarouselAnimation key={Math.random()}>{promo}</CarouselAnimation>)}
<CarouselAnimation key={Math.random()}>{this.getPromo()}</CarouselAnimation>
</TransitionGroup>
<div className="Promos-nav">
{promos.map((_, index) => {
@ -68,3 +86,11 @@ export default class Promos extends React.PureComponent<{}, State> {
this.setState({ activePromo });
};
}
function mapStateToProps(state: AppState): StateProps {
return {
wallet: state.wallet.inst
};
}
export default connect(mapStateToProps, {})(PromosClass);

View File

@ -1,4 +1,4 @@
@import "common/sass/variables";
@import 'common/sass/variables';
.AddCustom {
&-field {
@ -11,23 +11,20 @@
&-buttons {
padding-top: 10px;
display: flex;
justify-content: center;
flex-wrap: wrap;
&-help {
text-align: center;
display: block;
font-size: 13px;
margin-bottom: 10px;
}
&-btn {
margin-right: 10px;
&.btn-primary {
width: 120px;
}
&.btn-default {
width: 110px;
}
padding: 0.5rem 1.5rem;
margin: 0.25rem 0.5rem;
}
}
}

View File

@ -1,9 +1,8 @@
import React from 'react';
import classnames from 'classnames';
import { HELP_ARTICLE } from 'config';
import { isPositiveIntegerOrZero, isValidETHAddress } from 'libs/validators';
import translate from 'translations';
import { HelpLink } from 'components/ui';
import translate, { translateRaw } from 'translations';
import { HelpLink, Input } from 'components/ui';
import './AddCustomTokenForm.scss';
import { Token } from 'types/network';
@ -42,24 +41,23 @@ export default class AddCustomTokenForm extends React.PureComponent<Props, State
public render() {
const { address, symbol, decimal } = this.state;
const inputClasses = 'AddCustom-field-input form-control input-sm';
const errors = this.getErrors();
const fields = [
{
name: 'symbol',
value: symbol,
label: translate('TOKEN_Symbol')
label: translateRaw('TOKEN_SYMBOL')
},
{
name: 'address',
value: address,
label: translate('TOKEN_Addr')
label: translateRaw('TOKEN_ADDR')
},
{
name: 'decimal',
value: decimal,
label: translate('TOKEN_Dec')
label: translateRaw('TOKEN_DEC')
}
];
@ -68,12 +66,11 @@ export default class AddCustomTokenForm extends React.PureComponent<Props, State
{fields.map(field => {
return (
<label className="AddCustom-field form-group" key={field.name}>
<span className="AddCustom-field-label">{field.label}</span>
<input
className={classnames(
inputClasses,
errors[field.name] ? 'is-invalid' : field.value ? 'is-valid' : ''
)}
<div className="input-group-header">{field.label}</div>
<Input
className={`${
errors[field.name] ? 'invalid' : field.value ? 'valid' : ''
} input-group-input-small`}
type="text"
name={field.name}
value={field.value}
@ -86,21 +83,21 @@ export default class AddCustomTokenForm extends React.PureComponent<Props, State
);
})}
<HelpLink article={HELP_ARTICLE.ADDING_NEW_TOKENS} className="AddCustom-buttons-help">
{translate('ADD_CUSTOM_TKN_HELP')}
</HelpLink>
<div className="AddCustom-buttons">
<HelpLink article={HELP_ARTICLE.ADDING_NEW_TOKENS} className="AddCustom-buttons-help">
{translate('Need help? Learn how to add custom tokens.')}
</HelpLink>
<button
className="AddCustom-buttons-btn btn btn-primary btn-sm"
disabled={!this.isValid()}
>
{translate('x_Save')}
</button>
<button
className="AddCustom-buttons-btn btn btn-sm btn-default"
onClick={this.props.toggleForm}
>
{translate('x_Cancel')}
{translate('ACTION_2')}
</button>
<button
className="AddCustom-buttons-btn btn btn-primary btn-sm"
disabled={!this.isValid()}
>
{translate('X_SAVE')}
</button>
</div>
</form>

View File

@ -15,19 +15,23 @@ interface Props {
onRemoveCustomToken(symbol: string): any;
}
interface TrackedTokens {
[symbol: string]: boolean;
}
interface State {
trackedTokens: { [symbol: string]: boolean };
showCustomTokenForm: boolean;
}
export default class TokenBalances extends React.PureComponent<Props, State> {
public state = {
public state: State = {
trackedTokens: {},
showCustomTokenForm: false
};
public componentWillReceiveProps(nextProps: Props) {
if (nextProps.tokenBalances !== this.props.tokenBalances) {
const trackedTokens = nextProps.tokenBalances.reduce((prev, t) => {
const trackedTokens = nextProps.tokenBalances.reduce<TrackedTokens>((prev, t) => {
prev[t.symbol] = !t.balance.isZero();
return prev;
}, {});
@ -46,11 +50,9 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
bottom = (
<div className="TokenBalances-buttons">
<button className="btn btn-primary btn-block" onClick={this.handleSetWalletTokens}>
<span>{translate('x_Save')}</span>
<span>{translate('X_SAVE')}</span>
</button>
<p className="TokenBalances-buttons-help">
{translate('Missing tokens? You can add custom tokens next.')}
</p>
<p className="TokenBalances-buttons-help">{translate('PROMPT_ADD_CUSTOM_TKN')}</p>
</div>
);
} else if (showCustomTokenForm) {
@ -67,10 +69,10 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
bottom = (
<div className="TokenBalances-buttons">
<button className="btn btn-default btn-xs" onClick={this.toggleShowCustomTokenForm}>
<span>{translate('SEND_custom')}</span>
</button>{' '}
<span>{translate('SEND_CUSTOM')}</span>
</button>
<button className="btn btn-default btn-xs" onClick={this.props.scanWalletForTokens}>
<span>Scan for New Tokens</span>
<span>{translate('SCAN_TOKENS')}</span>
</button>
</div>
);
@ -101,7 +103,7 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
</tbody>
</table>
) : (
<div className="well well-sm text-center">No tokens found</div>
<div className="well well-sm text-center">{translate('SCAN_TOKENS_FAIL_NO_TOKENS')}</div>
)}
{bottom}
</div>

View File

@ -54,6 +54,7 @@ export default class TokenRow extends React.PureComponent<Props, State> {
{!!custom && (
<img
src={removeIcon}
alt="Remove"
className="TokenRow-symbol-remove"
title="Remove Token"
onClick={this.onRemove}

View File

@ -1,4 +1,4 @@
@import "common/sass/variables";
@import 'common/sass/variables';
.TokenBalances {
&-title {
@ -34,6 +34,12 @@
}
&-buttons {
display: flex;
flex-wrap: wrap;
justify-content: center;
& > &-btn {
margin: 0.25rem 0.5rem;
}
&-help {
padding-top: 10px;
text-align: center;

View File

@ -74,7 +74,7 @@ class TokenBalances extends React.Component<Props> {
className="TokenBalances-scan btn btn-primary btn-block"
onClick={this.scanWalletForTokens}
>
{translate('Scan for my Tokens')}
{translate('SCAN_TOKENS')}
</button>
);
} else {
@ -95,7 +95,7 @@ class TokenBalances extends React.Component<Props> {
return (
<section className="TokenBalances">
<h5 className="TokenBalances-title">{translate('sidebar_TokenBal')}</h5>
<h5 className="TokenBalances-title">{translate('SIDEBAR_TOKENBAL')}</h5>
{content}
</section>
);

View File

@ -1,43 +1,49 @@
@import "common/sass/variables";
@import "common/sass/mixins";
@import 'common/sass/variables';
@import 'common/sass/mixins';
.AlphaAgreement {
.BetaAgreement {
@include cover-message;
background: $brand-info;
&-content {
h2 {
text-align: center;
}
&-buttons {
padding-top: 20px;
&-btn {
display: block;
width: 100%;
max-width: 240px;
max-width: 280px;
margin: 0 auto;
border: none;
padding: 0;
outline: none;
transition: $transition;
&.is-reject {
&.is-continue {
height: 60px;
line-height: 60px;
font-size: 22px;
background: rgba(#fff, 0.96);
color: $gray;
color: $gray-dark;
border-radius: 4px;
margin-bottom: 20px;
&:hover {
background: #fff;
color: $gray-darker;
}
}
&.is-continue {
&.is-reject {
background: none;
color: #fff;
opacity: 0.7;
&:hover {
text-decoration: underline;
opacity: 1;
}
}
}
@ -51,7 +57,7 @@
background: #fff;
transition: all 500ms ease 400ms;
.AlphaAgreement-content {
.BetaAgreement-content {
opacity: 0;
transform: translateY(15px);
transition: all 500ms ease;

Some files were not shown because too many files have changed in this diff Show More