Merge branch 'master' into feature/#2038-new-network-selector

* master: (180 commits)
  make block difficulty params optional
  feat: document eth rpc api mimicking endpoints
  feat: add eth_getLogs rpc endpoint
  Update CHANGELOG.md
  eth classic and sokol logos fix
  sokol and eth classic logo fix
  fix parity test
  Update CHANGELOG.md
  Update _footer.html.eex
  fix tests
  fix config
  increase request idle timeout
  Added additional chains, wobserver info
  fix test
  fix tests
  add CHANGELOG entry
  mix format
  use milliseconds in cache
  fix tests
  fix test
  ...

# Conflicts:
#	CHANGELOG.md
#	apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex
#	apps/block_scout_web/priv/gettext/default.pot
#	apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
pull/2263/head
Gabriel Rodriguez Alsina 6 years ago
commit 2386fff82b
  1. 53
      CHANGELOG.md
  2. 2
      README.md
  3. 10
      apps/block_scout_web/assets/css/_mixins.scss
  4. 1
      apps/block_scout_web/assets/css/components/_address-overview.scss
  5. 8
      apps/block_scout_web/assets/css/components/_api.scss
  6. 4
      apps/block_scout_web/assets/css/components/_badge.scss
  7. 24
      apps/block_scout_web/assets/css/components/_btn_dropdown_line.scss
  8. 2
      apps/block_scout_web/assets/css/components/_button.scss
  9. 3
      apps/block_scout_web/assets/css/components/_card.scss
  10. 39
      apps/block_scout_web/assets/css/components/_dashboard-banner.scss
  11. 37
      apps/block_scout_web/assets/css/components/_dropdown.scss
  12. 22
      apps/block_scout_web/assets/css/components/_footer.scss
  13. 11
      apps/block_scout_web/assets/css/components/_log-search.scss
  14. 14
      apps/block_scout_web/assets/css/components/_modal.scss
  15. 20
      apps/block_scout_web/assets/css/components/_modal_status.scss
  16. 17
      apps/block_scout_web/assets/css/components/_navbar.scss
  17. 9
      apps/block_scout_web/assets/css/components/_pagination_container.scss
  18. 135
      apps/block_scout_web/assets/css/components/_tile.scss
  19. 2
      apps/block_scout_web/assets/css/components/_tooltip.scss
  20. 20
      apps/block_scout_web/assets/css/components/_verify_other_explorers.scss
  21. 8
      apps/block_scout_web/assets/css/theme/_base_variables.scss
  22. 53
      apps/block_scout_web/assets/css/theme/_dai_variables.scss
  23. 67
      apps/block_scout_web/assets/css/theme/_ethereum_classic_variables.scss
  24. 29
      apps/block_scout_web/assets/css/theme/_ethereum_variables.scss
  25. 60
      apps/block_scout_web/assets/css/theme/_goerli_variables.scss
  26. 55
      apps/block_scout_web/assets/css/theme/_kovan_variables.scss
  27. 77
      apps/block_scout_web/assets/css/theme/_lukso_variables.scss
  28. 56
      apps/block_scout_web/assets/css/theme/_neutral_variables.scss
  29. 39
      apps/block_scout_web/assets/css/theme/_poa_variables.scss
  30. 29
      apps/block_scout_web/assets/css/theme/_posdao_variables.scss
  31. 49
      apps/block_scout_web/assets/css/theme/_rinkeby_variables.scss
  32. 29
      apps/block_scout_web/assets/css/theme/_ropsten_variables.scss
  33. 53
      apps/block_scout_web/assets/css/theme/_rsk_variables.scss
  34. 56
      apps/block_scout_web/assets/css/theme/_sokol_variables.scss
  35. 3
      apps/block_scout_web/assets/css/theme/_variables.scss
  36. 1
      apps/block_scout_web/assets/js/lib/currency.js
  37. 4
      apps/block_scout_web/assets/static/images/blockscout_logo.svg
  38. 5
      apps/block_scout_web/assets/static/images/classic_ethereum_logo.svg
  39. 7
      apps/block_scout_web/assets/static/images/dai_logo.svg
  40. BIN
      apps/block_scout_web/assets/static/images/errors-img/goerli-page-not-found.png
  41. BIN
      apps/block_scout_web/assets/static/images/errors-img/goerli-page-not-found@2x.png
  42. BIN
      apps/block_scout_web/assets/static/images/errors-img/lukso-block-not-found.png
  43. BIN
      apps/block_scout_web/assets/static/images/errors-img/lukso-block-not-found@2x.png
  44. BIN
      apps/block_scout_web/assets/static/images/errors-img/lukso-page-not-found.png
  45. BIN
      apps/block_scout_web/assets/static/images/errors-img/lukso-page-not-found@2x.png
  46. BIN
      apps/block_scout_web/assets/static/images/errors-img/lukso-tx-not-found.png
  47. BIN
      apps/block_scout_web/assets/static/images/errors-img/lukso-tx-not-found@2x.png
  48. BIN
      apps/block_scout_web/assets/static/images/goerli_logo.png
  49. BIN
      apps/block_scout_web/assets/static/images/posdao_logo.png
  50. BIN
      apps/block_scout_web/assets/static/images/posdao_logo_footer.png
  51. 21
      apps/block_scout_web/assets/static/images/posdao_logo_footer.svg
  52. 48
      apps/block_scout_web/assets/static/images/rsk_logo.svg
  53. 4
      apps/block_scout_web/assets/static/images/sokol_logo.svg
  54. 5
      apps/block_scout_web/config/config.exs
  55. 10
      apps/block_scout_web/config/dev.exs
  56. 7
      apps/block_scout_web/lib/block_scout_web/channels/reward_channel.ex
  57. 5
      apps/block_scout_web/lib/block_scout_web/controller.ex
  58. 2
      apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex
  59. 43
      apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/address_controller.ex
  60. 355
      apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/eth_controller.ex
  61. 7
      apps/block_scout_web/lib/block_scout_web/controllers/api_docs_controller.ex
  62. 16
      apps/block_scout_web/lib/block_scout_web/controllers/chain/market_history_chart_controller.ex
  63. 8
      apps/block_scout_web/lib/block_scout_web/controllers/page_not_found_controller.ex
  64. 8
      apps/block_scout_web/lib/block_scout_web/controllers/pending_transaction_controller.ex
  65. 50
      apps/block_scout_web/lib/block_scout_web/etherscan.ex
  66. 2
      apps/block_scout_web/lib/block_scout_web/notifier.ex
  67. 5
      apps/block_scout_web/lib/block_scout_web/router.ex
  68. 2
      apps/block_scout_web/lib/block_scout_web/templates/address/_tile.html.eex
  69. 4
      apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex
  70. 7
      apps/block_scout_web/lib/block_scout_web/templates/address_decompiled_contract/index.html.eex
  71. 34
      apps/block_scout_web/lib/block_scout_web/templates/api_docs/eth_rpc.html.eex
  72. 10
      apps/block_scout_web/lib/block_scout_web/templates/block/overview.html.eex
  73. 29
      apps/block_scout_web/lib/block_scout_web/templates/common_components/_icon_question_modal.html.eex
  74. 22
      apps/block_scout_web/lib/block_scout_web/templates/common_components/_modal_status.html.eex
  75. 4
      apps/block_scout_web/lib/block_scout_web/templates/layout/_footer.html.eex
  76. 7
      apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex
  77. 4
      apps/block_scout_web/lib/block_scout_web/templates/page_not_found/index.html.eex
  78. 4
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex
  79. 37
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  80. 6
      apps/block_scout_web/lib/block_scout_web/views/address_decompiled_contract_view.ex
  81. 6
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/address_view.ex
  82. 36
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/eth_rpc_view.ex
  83. 13
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/eth_view.ex
  84. 5
      apps/block_scout_web/lib/block_scout_web/views/page_not_found.ex
  85. 88
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  86. 12
      apps/block_scout_web/lib/block_scout_web/views/wei_helpers.ex
  87. 119
      apps/block_scout_web/priv/gettext/default.pot
  88. 118
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  89. 6
      apps/block_scout_web/test/block_scout_web/channels/exchange_rate_channel_test.exs
  90. 485
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/eth_controller_test.exs
  91. 7
      apps/block_scout_web/test/block_scout_web/controllers/block_controller_test.exs
  92. 2
      apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs
  93. 9
      apps/block_scout_web/test/block_scout_web/controllers/pending_transaction_controller_test.exs
  94. 3
      apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs
  95. 8
      apps/block_scout_web/test/block_scout_web/views/address_decompiled_contract_view_test.exs
  96. 24
      apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs
  97. 13
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex
  98. 6
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/block.ex
  99. 35
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth/call.ex
  100. 6
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/fetched_beneficiaries.ex
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,8 +1,52 @@
## Current
### Features
- [#2182](https://github.com/poanetwork/blockscout/pull/2182) - add market history cache
- [#2109](https://github.com/poanetwork/blockscout/pull/2109) - use bigger updates instead of `Multi` transactions in BlocksTransactionsMismatch
- [#2075](https://github.com/poanetwork/blockscout/pull/2075) - add blocks cache
- [#2151](https://github.com/poanetwork/blockscout/pull/2151) - hide dropdown menu then other networks list is empty
- [#2146](https://github.com/poanetwork/blockscout/pull/2146) - feat: add eth_getLogs rpc endpoint
### Fixes
- [#2201](https://github.com/poanetwork/blockscout/pull/2201) - footer columns fix
- [#2179](https://github.com/poanetwork/blockscout/pull/2179) - fix docker build error
- [#2165](https://github.com/poanetwork/blockscout/pull/2165) - sort blocks by timestamp when calculating average block time
- [#2175](https://github.com/poanetwork/blockscout/pull/2175) - fix coinmarketcap response errors
- [#2164](https://github.com/poanetwork/blockscout/pull/2164) - fix large numbers in balance view card
- [#2155](https://github.com/poanetwork/blockscout/pull/2155) - fix pending transaction query
- [#2183](https://github.com/poanetwork/blockscout/pull/2183) - tile content aligning for mobile resolution fix, dai logo fix
- [#2162](https://github.com/poanetwork/blockscout/pull/2162) - contract creation tile color changed
- [#2144](https://github.com/poanetwork/blockscout/pull/2144) - 'page not found' images path fixed for goerli
- [#2142](https://github.com/poanetwork/blockscout/pull/2142) - Removed posdao theme and logo, added 'page not found' image for goerli
- [#2138](https://github.com/poanetwork/blockscout/pull/2138) - badge colors issue, api titles issue
- [#2129](https://github.com/poanetwork/blockscout/pull/2129) - Fix for width of explorer elements
- [#2121](https://github.com/poanetwork/blockscout/pull/2121) - Binding of 404 page
- [#2120](https://github.com/poanetwork/blockscout/pull/2120) - footer links and socials focus color issue
- [#2113](https://github.com/poanetwork/blockscout/pull/2113) - renewed logos for rsk, dai, blockscout; themes color changes for lukso; error images for lukso
- [#2112](https://github.com/poanetwork/blockscout/pull/2112) - themes color improvements, dropdown color issue
- [#2110](https://github.com/poanetwork/blockscout/pull/2110) - themes colors issues, ui issues
- [#2103](https://github.com/poanetwork/blockscout/pull/2103) - ui issues for all themes
- [#2090](https://github.com/poanetwork/blockscout/pull/2090) - updated some ETC theme colors
- [#2096](https://github.com/poanetwork/blockscout/pull/2096) - RSK theme fixes
- [#2093](https://github.com/poanetwork/blockscout/pull/2093) - detect token transfer type for deprecated erc721 spec
- [#2111](https://github.com/poanetwork/blockscout/pull/2111) - improve address transaction controller
- [#2108](https://github.com/poanetwork/blockscout/pull/2108) - fix uncle fetching without full transactions
- [#2128](https://github.com/poanetwork/blockscout/pull/2128) - add new function clause for uncle errors
- [#2123](https://github.com/poanetwork/blockscout/pull/2123) - fix coins percentage view
- [#2119](https://github.com/poanetwork/blockscout/pull/2119) - fix map logging
- [#2130](https://github.com/poanetwork/blockscout/pull/2130) - fix navigation
- [#2148](https://github.com/poanetwork/blockscout/pull/2148) - filter pending logs
- [#2147](https://github.com/poanetwork/blockscout/pull/2147) - add rsk format of checksum
- [#2149](https://github.com/poanetwork/blockscout/pull/2149) - remove pending transaction count
- [#2177](https://github.com/poanetwork/blockscout/pull/2177) - remove duplicate entries from UncleBlock's Fetcher
- [#2169](https://github.com/poanetwork/blockscout/pull/2169) - add more validator reward types for xDai
- [#2173](https://github.com/poanetwork/blockscout/pull/2173) - handle correctly empty transactions
- [#2174](https://github.com/poanetwork/blockscout/pull/2174) - fix reward channel joining
- [#2186](https://github.com/poanetwork/blockscout/pull/2186) - fix net version test
- [#2167](https://github.com/poanetwork/blockscout/pull/2168) - feat: document eth rpc api mimicking endpoints
### Chore
- [#2127](https://github.com/poanetwork/blockscout/pull/2127) - use previouse chromedriver version
- [#2118](https://github.com/poanetwork/blockscout/pull/2118) - show only the last decompiled contract
### Chore
@ -10,6 +54,7 @@
### Features
- [#2044](https://github.com/poanetwork/blockscout/pull/2044) - New network selector.
- [#2091](https://github.com/poanetwork/blockscout/pull/2091) - Added "Question" modal.
- [#1963](https://github.com/poanetwork/blockscout/pull/1963), [#1959](https://github.com/poanetwork/blockscout/pull/1959), [#1948](https://github.com/poanetwork/blockscout/pull/1948), [#1936](https://github.com/poanetwork/blockscout/pull/1936), [#1925](https://github.com/poanetwork/blockscout/pull/1925), [#1922](https://github.com/poanetwork/blockscout/pull/1922), [#1903](https://github.com/poanetwork/blockscout/pull/1903), [#1874](https://github.com/poanetwork/blockscout/pull/1874), [#1895](https://github.com/poanetwork/blockscout/pull/1895), [#2031](https://github.com/poanetwork/blockscout/pull/2031), [#2073](https://github.com/poanetwork/blockscout/pull/2073), [#2074](https://github.com/poanetwork/blockscout/pull/2074), - added new themes and logos for poa, eth, rinkeby, goerli, ropsten, kovan, sokol, xdai, etc, rsk and default theme
- [#1726](https://github.com/poanetwork/blockscout/pull/2071) - Updated styles for the new smart contract page.
- [#2081](https://github.com/poanetwork/blockscout/pull/2081) - Tooltip for 'more' button, explorers logos added
@ -17,7 +62,6 @@
- [#1928](https://github.com/poanetwork/blockscout/pull/1928) - pagination styles were updated
- [#1940](https://github.com/poanetwork/blockscout/pull/1940) - qr modal button and background issue
- [#1907](https://github.com/poanetwork/blockscout/pull/1907) - dropdown color bug fix (lukso theme) and tooltip color bug fix
- [#2197](https://github.com/poanetwork/blockscout/pull/2197) - search network input functionality, add to favorites functionality, removed 'Show More Networks' button
- [#1859](https://github.com/poanetwork/blockscout/pull/1859) - feat: show raw transaction traces
- [#1941](https://github.com/poanetwork/blockscout/pull/1941) - feat: add on demand fetching and stale attr to rpc
- [#1957](https://github.com/poanetwork/blockscout/pull/1957) - Calculate stakes ratio before insert pools
@ -32,8 +76,11 @@
- [#2037](https://github.com/poanetwork/blockscout/pull/2037) - add address logs search functionality
- [#2012](https://github.com/poanetwork/blockscout/pull/2012) - make all pages pagination async
- [#2064](https://github.com/poanetwork/blockscout/pull/2064) - feat: add fields to tx apis, small cleanups
- [#2100](https://github.com/poanetwork/blockscout/pull/2100) - feat: eth_get_balance rpc endpoint
### Fixes
- [#2099](https://github.com/poanetwork/blockscout/pull/2099) - logs search input width
- [#2098](https://github.com/poanetwork/blockscout/pull/2098) - nav dropdown issue, logo size issue
- [#2082](https://github.com/poanetwork/blockscout/pull/2082) - dropdown styles, tooltip gap fix, 404 page added
- [#2077](https://github.com/poanetwork/blockscout/pull/2077) - ui issues
- [#2072](https://github.com/poanetwork/blockscout/pull/2072) - Fixed checkmarks not showing correctly in tabs.
@ -67,6 +114,8 @@
- [#2014](https://github.com/poanetwork/blockscout/pull/2014) - fix: use better queries for listLogs endpoint
- [#2027](https://github.com/poanetwork/blockscout/pull/2027) - fix: `BlocksTransactionsMismatch` ignoring blocks without transactions
- [#2070](https://github.com/poanetwork/blockscout/pull/2070) - reduce `max_concurrency` of `BlocksTransactionsMismatch` fetcher
- [#2083](https://github.com/poanetwork/blockscout/pull/2083) - allow total_difficuly to be nil
- [#2086](https://github.com/poanetwork/blockscout/pull/2086) - fix geth's staticcall without output
### Chore

@ -54,6 +54,8 @@ Currently available block explorers (i.e. Etherscan and Etherchain) are closed s
| [xDai Chain](https://blockscout.com/poa/dai) | | [SafeChain](https://explorer.safechain.io) |
| | | [SpringChain](https://explorer.springrole.com/) |
| | | [Kotti Testnet](https://kottiexplorer.ethernode.io/) |
| | | [Loom](http://plasma-blockexplorer.dappchains.com/) |
| | | [Tenda](https://tenda.network) |
### Visual Interface

@ -73,6 +73,7 @@
}
@mixin btn-full($bg-color: $primary, $text-color: #fff) {
-webkit-appearance: none !important;
align-items: center;
background-color: $bg-color;
border-radius: 2px;
@ -87,7 +88,7 @@
outline: none;
padding: 0 15px;
text-decoration: none;
transition: all 0.15s;
transition: $transition-cont;
white-space: nowrap;
width: fit-content;
@ -121,6 +122,7 @@
}
@mixin btn-line($bg-color: #fff, $text-color: $secondary) {
-webkit-appearance: none !important;
align-items: center;
background-color: $bg-color;
border-radius: 2px;
@ -135,9 +137,10 @@
outline: none;
padding: 0 15px;
text-decoration: none;
transition: all 0.15s;
transition: $transition-cont;
white-space: nowrap;
width: fit-content;
font-weight: 400;
&:hover {
background-color: $text-color;
@ -180,7 +183,7 @@
display: flex;
height: $dimensions;
justify-content: center;
transition: all 0.15s;
transition: $transition-cont;
width: $dimensions;
svg {
@ -191,6 +194,7 @@
path {
fill: $color;
transition: $transition-cont;
}
&:hover {

@ -70,6 +70,7 @@
font-weight: 200;
line-height: 1.2;
margin: 0 0 12px;
font-weight: 400;
small {
font-size: 11px;

@ -1,7 +1,7 @@
$api-text-monospace-color: $primary !default;
$api-text-monospace-color: $secondary !default;
$api-text-monospace-background: rgba($api-text-monospace-color, 0.1) !default;
$api-anchors-list-background-color: #f6f7f9 !default;
$api-doc-list-item-title-color: $primary !default;
$api-doc-list-item-title-color: #333 !default;
$api-doc-list-item-view-more-color: $api-doc-list-item-title-color !default;
.api-text-monospace {
@ -89,8 +89,8 @@ $api-doc-list-item-view-more-color: $api-doc-list-item-title-color !default;
.api-doc-list-item-title {
color: $api-doc-list-item-title-color;
font-size: 17px;
font-weight: 700;
font-size: 15px;
font-weight: 400;
line-height: 1.2;
margin: 0 0 15px;
}

@ -2,8 +2,8 @@ $badge-success-color: #15bba6 !default;
$badge-success-background-color: rgba($badge-success-color, 0.1) !default;
$badge-danger-color: #ed9966 !default;
$badge-danger-background-color: rgba($badge-danger-color, 0.1) !default;
$badge-neutral-color: #333 !default;
$badge-neutral-background-color: #e9e9e9 !default;
$badge-neutral-color: $secondary !default;
$badge-neutral-background-color: rgba($secondary, .1) !default;
.badge {
color: $white;

@ -1,13 +1,17 @@
$btn-dropdown-line-bg: #fff !default;
$btn-dropdown-line-color: $primary !default;
$btn-dropdown-line-color: #e2e5ec !default;
$btn-dropdown-line-color-hover: #f5f6fa !default;
$btn-dropdown-line-font: #333;
.btn-dropdown-line {
@include btn-line($btn-dropdown-line-bg, $btn-dropdown-line-color);
outline: none !important;
color: #333;
border-color: #e2e5ec;
&:hover {
background-color: transparent;
color: #333;
}
}
@include btn-line($btn-dropdown-line-bg, $btn-dropdown-line-color);
border-color: $btn-dropdown-line-color;
color: $btn-dropdown-line-font;
outline: none !important;
&:hover {
background-color: $btn-dropdown-line-color-hover;
border-color: $btn-dropdown-line-color;
color: $btn-dropdown-line-font;
}
}

@ -10,7 +10,7 @@ $button-secondary-color: $secondary !default;
padding: 10px 16px;
text-align: center;
text-decoration: none;
transition: all 0.25s;
transition: $transition-cont;
white-space: nowrap;
&-primary {

@ -176,9 +176,10 @@ $card-tab-icon-color-active: #20b760 !default;
height: 70px;
padding: 0 25px;
text-align: center;
transition: $transition-cont;
&:hover {
background-color: rgba($card-tab-active, .1);
background-color: rgba($card-tab-active, .15);
color: $card-tab-active;
text-decoration: none;
}

@ -16,30 +16,15 @@ $dashboard-banner-chart-axis-font-color: $dashboard-stats-item-value-color !defa
.dashboard-banner-container {
@include gradient-container();
margin-bottom: 3rem;
overflow: hidden;
padding: 0;
position: relative;
&::after {
background-color: $dashboard-banner-network-plain-container-background-color;
bottom: 0;
content: "";
display: block;
height: $dashboard-banner-network-plain-container-height;
left: 70%;
position: absolute;
right: 0;
@include media-breakpoint-down(md) {
display: none;
}
}
}
.dashboard-banner {
display: flex;
justify-content: space-between;
margin-bottom: 3rem;
position: relative;
z-index: 9;
@ -148,6 +133,7 @@ $dashboard-banner-chart-axis-font-color: $dashboard-stats-item-value-color !defa
max-width: 100%;
padding: 30px 0 30px 60px;
width: 750px;
position: relative;
@include media-breakpoint-down(md) {
border-top-right-radius: 10px;
@ -158,11 +144,30 @@ $dashboard-banner-chart-axis-font-color: $dashboard-stats-item-value-color !defa
max-width: 100%;
padding: 20px 0 20px 20px;
width: 250px;
box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.2);
}
@include media-breakpoint-down(sm) {
width: 100%;
}
&::after {
background-color: $dashboard-banner-network-plain-container-background-color;
bottom: 0;
content: "";
display: block;
height: $dashboard-banner-network-plain-container-height;
left: 0;
position: absolute;
width: 9999px;
z-index: -1;
box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.2);
border-top-left-radius: 10px;
@include media-breakpoint-down(md) {
display: none;
}
}
}
.dashboard-banner-network-stats {

@ -1,13 +1,17 @@
$dropdown-menu-item-color: #333 !default;
$dropdown-menu-item-hover-color: $secondary !default;
$dropdown-menu-item-hover-background: rgba($secondary, .1) !default;
// These styles extend the default Bootstrap styles
.dropdown-menu {
border-radius: 0 0 8px 8px !important;
border: none;
border-bottom: 1px solid #e2e5ec;
border-left: 1px solid #e2e5ec;
border-radius: 0 0 2px 2px !important;
border-right: 1px solid #e2e5ec;
border-top: none;
box-shadow: $box-shadow;
padding: 0;
width: 100%;
border-left: 1px solid #e2e5ec;
border-right: 1px solid #e2e5ec;
border-bottom: 1px solid #e2e5ec;
&.right {
left: auto;
@ -27,11 +31,18 @@
}
.dropdown-item {
color: $dropdown-menu-item-color;
font-size: 12px;
padding: 10px 20px;
transition: $transition-cont;
&:hover {
color: #fff;
& {
&.active,
&:hover,
&:focus {
background-color: $dropdown-menu-item-hover-background;
color: $dropdown-menu-item-hover-color;
}
}
&:first-child {
@ -40,8 +51,8 @@
}
&:last-child {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
&.header {
@ -55,16 +66,16 @@
font-weight: 700;
}
}
&.active {
background-color: $secondary;
}
&.division {
border-top: 1px solid $base-border-color;
}
}
.navbar .dropdown-menu {
border: none;
}
.dropdown-search-icon {
color: $gray-300;
left: 8px;

@ -4,7 +4,7 @@ $footer-text-color: rgba(#fff, 0.7) !default;
$footer-link-color: $footer-text-color !default;
$footer-item-disc-color: $primary !default;
$footer-social-icon-color: $footer-text-color !default;
$footer-logo-height: 2rem !default;
$footer-logo-height: 28px !default;
$footer-logo-width: auto !default;
.footer {
@ -26,7 +26,7 @@ $footer-logo-width: auto !default;
}
.footer-logo {
height: $footer-logo-height;
max-height: $footer-logo-height;
width: $footer-logo-width;
}
@ -46,9 +46,14 @@ $footer-logo-width: auto !default;
font-size: 22px;
margin-right: 15px;
text-decoration: none;
transition: $transition-cont;
&:hover {
color: $footer-social-icon-color;
color: #fff;
}
&:focus {
color: darken($footer-text-color, 5);
}
&:last-child {
@ -91,6 +96,17 @@ $footer-logo-width: auto !default;
line-height: 2.5;
padding: 0;
a {
transition: $transition-cont;
&:hover {
text-decoration: none;
color: #fff;
}
&:focus {
color: darken($footer-text-color, 5);
}
}
&::before {
background-color: $footer-item-disc-color;
border-radius: 50%;

@ -12,8 +12,10 @@
.logs-search {
display: flex;
position: relative;
flex: 2;
@media (max-width: 599px) {
margin-bottom: 30px;
width: 100%;
}
}
@ -27,6 +29,7 @@
font-family: Nunito, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 12px;
font-weight: 600;
-webkit-appearance: none;
}
.logs-search-input {
@ -34,8 +37,10 @@
display: inline-flex;
flex-grow: 2;
min-width: 160px;
font-weight: 300 !important;
&::placeholder {
color: #a3a9b5;
color: #a3a9b5;
font-weight: 300 !important;
}
}
@ -57,8 +62,8 @@
transition: .1s ease-in;
position: absolute;
top: 0;
left: 136px;
right: 59px;
&:hover {
color: #333;
}
}
}

@ -46,4 +46,18 @@ $modal-gray-background: #f6f7f9 !default;
.modal-content {
border-radius: $modal-border-radius;
position: relative;
.btn-primary {
box-shadow: none !important;
background-color: $btn-line-color;
border: 1px solid $btn-line-color;
&:hover {
background-color: $btn-line-color;
border-color: $btn-line-color;
}
&:focus,
&:active {
background-color: darken($btn-line-color, 10%) !important;
border-color: darken($btn-line-color, 10%) !important;
}
}
}

@ -1,6 +1,7 @@
$modal-status-graph-error: #ff0d51 !default;
$modal-status-graph-warning: #ff8502 !default;
$modal-status-graph-success: $primary !default;
$modal-status-graph-question: #329ae9 !default;
.modal-status {
max-width: 100%;
@ -32,6 +33,10 @@ $modal-status-graph-success: $primary !default;
background-color: $modal-status-graph-success;
}
&-question {
background-color: $modal-status-graph-question;
}
svg {
margin-top: 15px;
}
@ -62,3 +67,18 @@ $modal-status-graph-success: $primary !default;
margin: 0 0 25px;
text-align: center;
}
.modal-status-button-wrapper {
display: flex;
justify-content: space-between;
width: 100%;
.btn-line {
flex-grow: 1;
margin-right: 20px;
&:last-child {
margin-right: 0;
}
}
}

@ -1,16 +1,16 @@
// Default variables
$header-background-color: #fff !default;
$header-links-color: #a3a9b5 !default;
$header-links-color: #828ba0 !default;
$header-links-color-active: #333 !default;
$header-icon-color: $header-links-color !default;
$header-icon-color-hover: #333 !default;
$header-icon-border-color-hover: $primary !default;
$header-icon-color-hover: $secondary !default;
$header-icon-border-color-hover: $secondary !default;
$header-toggler-icon: "data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{transparentize($primary, 0.5)}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E" !default;
$header-textfield-text-color: $header-links-color !default;
$header-textfield-background-color: #f5f6fa !default;
$header-textfield-magnifier-color: $header-links-color !default;
$header-link-horizontal-padding: 0.71rem;
$navbar-logo-height: 1.5em !default;
$navbar-logo-height: 28px !default;
$navbar-logo-width: auto !default;
.navbar.navbar-primary {
@ -30,6 +30,7 @@ $navbar-logo-width: auto !default;
display: flex;
font-size: 14px;
position: relative;
transition: $transition-cont;
&:before {
background-color: $header-icon-border-color-hover;
@ -42,7 +43,7 @@ $navbar-logo-width: auto !default;
position: absolute;
top: -10px;
transform: translateX(-50%);
transition: all 0.2s ease;
transition: $transition-cont;
width: calc(
100% - #{$header-link-horizontal-padding} - #{$header-link-horizontal-padding}
);
@ -77,12 +78,16 @@ $navbar-logo-width: auto !default;
path {
fill: $header-icon-color;
transition: $transition-cont;
}
}
}
.nav-item-networks {
margin-left: auto;
.nav-link:before {
display: none;
}
}
}
@ -208,7 +213,7 @@ $navbar-logo-width: auto !default;
}
.navbar-logo {
height: $navbar-logo-height;
max-height: $navbar-logo-height;
width: $navbar-logo-width;
}

@ -17,6 +17,10 @@ $pagination-page-link-color-active: #fff !default;
display: flex;
justify-content: space-between;
&[disabled] {
display: none;
}
@include media-breakpoint-down(sm) {
flex-direction: column;
}
@ -109,5 +113,10 @@ $pagination-page-link-color-active: #fff !default;
}
}
}
}
.logs-topbar .pagination-container {
@media (min-width: 600px) {
margin-left: 80px;
}
}

@ -4,7 +4,7 @@ $tile-type-reorg-color: $purple !default;
$tile-type-emission-reward-color: $lilac !default;
$tile-type-transaction-color: $blue !default;
$tile-type-contract-call-color: $green !default;
$tile-type-contract-creation-color: $pink !default;
$tile-type-contract-creation-color: $dark-purple !default;
$tile-type-token-transfer-color: $orange !default;
$tile-type-unique-token-color: $orange !default;
$tile-type-unique-token-image-color: $orange !default;
@ -14,6 +14,8 @@ $tile-type-progress-bar-color: $primary !default;
$tile-status-error-reason: #ff7986 !default;
$tile-status-awaiting-internal-transactions: $warning !default;
$tile-padding: 1rem;
$tile-title-color: #333 !default;
$tile-body-a-color: #5959d8 !default;
@mixin generate-tile-block($prefix, $color, $label-color: false) {
&#{ $prefix } {
@ -23,8 +25,7 @@ $tile-padding: 1rem;
a {
@if ($label-color) {
color: $label-color;
}
@else {
} @else {
color: $color;
}
}
@ -33,19 +34,13 @@ $tile-padding: 1rem;
.tile-label {
@if ($label-color) {
color: $label-color;
}
@else {
} @else {
color: $color;
}
}
.tile-status-label {
@if ($label-color) {
color: $label-color;
}
@else {
color: $color;
}
color: inherit;
}
.tile-transaction-type-block {
@ -60,20 +55,6 @@ $tile-padding: 1rem;
/*********************************************************************/
.tile-title {
color: #333;
font-size: 12px;
&-hash {
font-weight: 300;
}
&-lg {
color: $body-color;
font-size: 16px;
}
}
.tile-label {
font-size: 12px;
font-weight: 700;
@ -123,6 +104,18 @@ $tile-padding: 1rem;
padding: 0 5px;
}
.tile-transaction-type-block {
.tile-status-label {
padding: 0;
}
}
.tile-bottom {
@media (max-width: 767px) {
justify-content: flex-start !important;
}
}
.tile-bottom-contents {
background-color: #f6f7f9;
font-size: 12px;
@ -154,7 +147,6 @@ $tile-padding: 1rem;
}
.tile-function-response {
span.function-response-item {
display: block;
margin-left: 1rem;
@ -167,7 +159,6 @@ $tile-padding: 1rem;
p {
margin: 0;
}
}
.tile-image {
@ -176,6 +167,29 @@ $tile-padding: 1rem;
}
.tile {
span[data-address-hash] {
color: $tile-body-a-color;
}
.tile-body {
a {
color: $tile-body-a-color;
}
}
.tile-title {
color: $tile-title-color;
font-size: 12px;
&-hash {
font-weight: 300;
}
&-lg {
color: $body-color;
font-size: 16px;
}
}
border-radius: 4px;
border: 1px solid $border-color;
color: $text-muted;
@ -184,20 +198,57 @@ $tile-padding: 1rem;
line-height: 1.4rem;
padding: $tile-padding;
@include generate-tile-block('.tile-type-block', $tile-type-block-color, darken($tile-type-block-color, 20%));
@include generate-tile-block('.tile-type-uncle', $tile-type-uncle-color);
@include generate-tile-block('.tile-type-reorg', $tile-type-reorg-color);
@include generate-tile-block('.tile-type-emission-reward', $tile-type-emission-reward-color);
@include generate-tile-block('.tile-type-transaction', $tile-type-transaction-color);
@include generate-tile-block('.tile-type-contract-call', $tile-type-contract-call-color);
@include generate-tile-block('.tile-type-contract-creation', $tile-type-contract-creation-color);
@include generate-tile-block('.tile-type-token-transfer', $tile-type-token-transfer-color);
@include generate-tile-block('.tile-type-unique-token', $tile-type-unique-token-color);
@include generate-tile-block('.tile-type-unique-token-image', $tile-type-unique-token-image-color);
@include generate-tile-block('.tile-type-internal-transaction', $tile-type-internal-transaction-color);
@include generate-tile-block('.tile-type-api-documentation', $tile-type-api-documentation-color);
@include generate-tile-block('[class*="status--error"]', $tile-status-error-reason);
@include generate-tile-block('.tile-status--awaiting-internal-transactions', $tile-status-awaiting-internal-transactions);
@include generate-tile-block(
".tile-type-block",
$tile-type-block-color,
darken($tile-type-block-color, 20%)
);
@include generate-tile-block(".tile-type-uncle", $tile-type-uncle-color);
@include generate-tile-block(".tile-type-reorg", $tile-type-reorg-color);
@include generate-tile-block(
".tile-type-emission-reward",
$tile-type-emission-reward-color
);
@include generate-tile-block(
".tile-type-transaction",
$tile-type-transaction-color
);
@include generate-tile-block(
".tile-type-contract-call",
$tile-type-contract-call-color
);
@include generate-tile-block(
".tile-type-contract-creation",
$tile-type-contract-creation-color
);
@include generate-tile-block(
".tile-type-token-transfer",
$tile-type-token-transfer-color
);
@include generate-tile-block(
".tile-type-unique-token",
$tile-type-unique-token-color
);
@include generate-tile-block(
".tile-type-unique-token-image",
$tile-type-unique-token-image-color
);
@include generate-tile-block(
".tile-type-internal-transaction",
$tile-type-internal-transaction-color
);
@include generate-tile-block(
".tile-type-api-documentation",
$tile-type-api-documentation-color
);
@include generate-tile-block(
'[class*="status--error"]',
$tile-status-error-reason
);
@include generate-tile-block(
".tile-status--awaiting-internal-transactions",
$tile-status-awaiting-internal-transactions
);
&.n-p {
padding: 0;
@ -273,4 +324,4 @@ $tile-padding: 1rem;
border-radius: 2px;
}
}
}
}

@ -1,4 +1,4 @@
$tooltip-background-color: $primary !default;
$tooltip-background-color: $btn-line-color !default;
$tooltip-color: #fff !default;
.tooltip {

@ -18,9 +18,13 @@
line-height: 1.25;
display: inline-flex;
margin-bottom: 12px;
@media (min-width: 1200px) {
width: 100%;
@media (min-width: 768px) {
margin-right: 10px;
}
@media (min-width: 1200px) {
margin-bottom: 0;
width: auto;
}
}
}
@ -31,6 +35,8 @@
flex-grow: 2;
@media (min-width: 768px) {
flex-direction: row;
position: relative;
padding-right: 44px;
}
}
@ -41,6 +47,7 @@
flex-grow: 2;
@media (min-width: 768px) {
margin-top: 0;
max-width: 188px;
}
@media (min-width: 1200px) {
min-width: 145px;
@ -76,7 +83,7 @@
}
.exp-content {
padding: 6px 9px 4px 9px;
padding: 6px 9px 5px 9px;
h3, div {
font-size: 10px;
line-height: 1;
@ -117,7 +124,7 @@
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid $secondary;
border: 1px solid $btn-line-color;
border-radius: 2px;
margin-top: 10px;
transition: .1s ease-in;
@ -125,12 +132,15 @@
@media (min-width: 768px) {
margin-left: 10px;
margin-top: 0;
position: absolute;
top: 0;
right: 0;
}
svg path {
fill: $secondary;
fill: $btn-line-color;
}
&:hover {
background-color: $secondary;
background-color: $btn-line-color;
svg path {
fill: #fff;
}

@ -3,13 +3,17 @@
// Variables should follow the `$component-state-property-size` formula for
// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.
$dashboard-line-color-price: #8286a9 !default;
$base-border-color: #e2e5ec !default;
$common-container-margin: 50px !default;
// stylelint-disable
$white: #fff !default;
$gray-100: #f8f9fa !default;
$gray-200: #e9ecef !default;
$gray-300: #dee2e6 !default;
$gray-400: #ced4da !default;
$gray-500: #adb5bd !default;
$gray-500: #828ba0 !default;
$gray-600: #cdcdcc !default;
$gray-700: #495057 !default;
$gray-800: #343a40 !default;
@ -43,6 +47,7 @@ $yellow: #ffc107 !default;
$green: #20b760 !default;
$teal: #009097 !default;
$cyan: #90e1d8 !default;
$dark-purple: #923dc3;
$colors: () !default;
$colors: map-merge(
@ -240,6 +245,7 @@ $caret-width: 0.3em !default;
$transition-base: all 0.2s ease-in-out !default;
$transition-fade: opacity 0.15s linear !default;
$transition-collapse: height 0.35s ease !default;
$transition-cont: all 0.4s ease-in-out !default;
// Fonts
//

@ -1,22 +1,25 @@
// general
$primary: #17314f;
$secondary: #69b9d7;
$tertiary: #15bba6;
$additional-font: #ffffff;
$secondary: #15bba6;
$tertiary: #93d7ff;
$additional-font: #fff;
// footer
$footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: #909dab;
$footer-item-disc-color: $tertiary;
$footer-text-color: #96bde8;
$footer-item-disc-color: $secondary;
.footer-logo { filter: brightness(0) invert(1); }
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-line-color-market: $secondary;
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: $footer-text-color;
$dashboard-stats-item-label-color: $footer-text-color;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
@ -29,22 +32,34 @@ $dashboard-banner-network-plain-container-background-color: #20446e; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $secondary; // top border on hover
$header-icon-color-hover: $secondary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $secondary !important; } // dropdown item on hover
// buttons
$btn-line-bg: #fff; // button bg
$btn-line-color: $primary; // button border and font color && hover bg color
$btn-copy-color: $primary; // btn copy
$btn-qr-color: $primary; // btn qr-code
$btn-line-color: $secondary; // button border and font color && hover bg color
$btn-copy-color: $secondary; // btn copy
$btn-qr-color: $secondary; // btn qr-code
//links & tile
.tile a { color: $tertiary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $primary;
} // tab active bg
$tile-body-a-color: $secondary;
$tile-type-block-color: $secondary;
$tile-type-progress-bar-color: $secondary;
a.tile-title { color: $secondary !important; }
// card
$card-background-1: #1b395c;
$card-tab-active: $tertiary;
$card-background-1: $secondary;
$card-tab-active: $secondary;
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}
// Badges
$badge-neutral-color: #20446e;
$badge-neutral-background-color: rgba(#20446e, .1);
$api-text-monospace-color: #20446e;

@ -9,42 +9,69 @@ $footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: $additional-font;
$footer-item-disc-color: $tertiary;
.footer-logo { filter: brightness(0) invert(1); }
$footer-social-icon-color: #5959d8;
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-line-color-price: $secondary;
$dashboard-line-color-market: $tertiary;
$dashboard-banner-gradient-start: #1b1b39;
$dashboard-banner-gradient-end: #27275f;
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: $additional-font;
$dashboard-stats-item-label-color: $additional-font;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
$dashboard-banner-gradient-start: $primary; // gradient begin
$dashboard-banner-gradient-end: lighten($primary, 5); // gradient end
$dashboard-banner-network-plain-container-background-color: #2d2d69; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $tertiary; // top border on hover
$header-icon-color-hover: $tertiary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $tertiary !important; } // dropdown item on hover
// buttons
$btn-line-bg: #fff; // button bg
$btn-line-color: #27275e; // button border and font color && hover bg color
$btn-copy-color: #27275e; // btn copy
$btn-qr-color: #27275e; // btn qr-code
$btn-line-color: $tertiary; // button border and font color && hover bg color
$btn-copy-color: $tertiary; // btn copy
$btn-qr-color: $tertiary; // btn qr-code
//links & tile
.tile a { color: $tertiary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid #27275e;
} // tab active bg
$tile-body-a-color: $tertiary;
$tile-type-block-color: $tertiary;
$tile-type-progress-bar-color: $tertiary;
a.tile-title { color: $tertiary !important; }
// card
$card-background-1: $tertiary;
$card-tab-active: $tertiary;
// ETC theme's idiosyncrasies
.layout-container {
.navbar {
box-shadow: 0 0 30px 0 rgba(21, 53, 80, 0.12);
}
.dropdown-item:hover,
.dropdown-item.active,
.dropdown-item:focus {
background-color: rgba($tertiary, .1) !important;
color: $tertiary !important;
}
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
.footer-logo {
filter: brightness(0) invert(1);
}
}
// Badges
$badge-neutral-color: $tertiary;
$badge-neutral-background-color: rgba($tertiary, .1);
$api-text-monospace-color: $tertiary;

@ -10,13 +10,15 @@ $footer-title-color: #fff;
$footer-text-color: #89cae6;
$footer-item-disc-color: $secondary;
.footer-logo { filter: brightness(0) invert(1); }
.footer-social-icons .footer-social-icon { color: $secondary; }
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: #89cae6;
$dashboard-stats-item-label-color: #89cae6;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
@ -29,9 +31,6 @@ $dashboard-banner-network-plain-container-background-color: #1c476c; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $secondary; // top border on hover
$header-icon-color-hover: $secondary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $secondary !important; } // dropdown item on hover
// buttons
$btn-line-bg: #fff; // button bg
@ -40,11 +39,21 @@ $btn-copy-color: $secondary; // btn copy
$btn-qr-color: $secondary; // btn qr-code
//links & tile
.tile a { color: $secondary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $secondary;
} // tab active bg
$tile-body-a-color: $secondary;
$tile-type-block-color: $secondary;
$tile-type-progress-bar-color: $secondary;
a.tile-title { color: $secondary !important; }
// card
$card-background-1: $secondary;
$card-tab-active: $secondary;
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}

@ -3,6 +3,7 @@ $primary: #2b2b2b;
$secondary: #eac247;
$tertiary: #929292;
$additional-font: #ffffff;
$sub-accent-color: #a46f30;
// footer
$footer-background-color: $primary;
@ -12,11 +13,14 @@ $footer-item-disc-color: $secondary;
.footer-logo { filter: brightness(0) invert(1); }
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-line-color-price: $secondary;
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-line-color-market: $tertiary;
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: $tertiary;
$dashboard-stats-item-label-color: $tertiary;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
@ -29,22 +33,48 @@ $dashboard-banner-network-plain-container-background-color: #424242; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $secondary; // top border on hover
$header-icon-color-hover: $secondary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $secondary !important; } // dropdown item on hover
$dropdown-menu-item-hover-color: $sub-accent-color !default;
$dropdown-menu-item-hover-background: rgba($sub-accent-color, .1) !default;
$header-icon-color-hover: $sub-accent-color;
$header-icon-border-color-hover: $sub-accent-color;
// buttons
$btn-line-bg: #fff; // button bg
$btn-line-color: #424242; // button border and font color && hover bg color
$btn-copy-color: #424242; // btn copy
$btn-qr-color: #424242; // btn qr-code
$btn-line-color: $sub-accent-color; // button border and font color && hover bg color
$btn-copy-color: $sub-accent-color; // btn copy
$btn-qr-color: $sub-accent-color; // btn qr-code
//links & tile
.tile a { color: #a46f30 !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $secondary;
} // tab active bg
$tile-body-a-color: $sub-accent-color;
$tile-type-block-color: $sub-accent-color;
$tile-type-progress-bar-color: $sub-accent-color;
a.tile-title { color: $sub-accent-color !important; }
// card
$card-background-1: $secondary;
$card-tab-active: $secondary;
$card-background-1: $sub-accent-color;
$card-tab-active: $sub-accent-color;
// dropdown
.dropdown-item {
&:hover,
&:active,
&.active {
background-color: rgba($sub-accent-color, .1) !important;
color: $sub-accent-color !important;
}
}
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}
// Badges
$badge-neutral-color: $sub-accent-color;
$badge-neutral-background-color: rgba($sub-accent-color, .1);
$api-text-monospace-color: $sub-accent-color;

@ -7,16 +7,17 @@ $additional-font: #99fff9;
// footer
$footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: $secondary;
$footer-item-disc-color: $secondary;
$footer-text-color: $additional-font;
$footer-item-disc-color: $additional-font;
.footer-logo { filter: brightness(0) invert(1); }
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: $additional-font;
$dashboard-stats-item-label-color: $additional-font;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
@ -29,9 +30,8 @@ $dashboard-banner-network-plain-container-background-color: #1a323b; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $tertiary; // top border on hover
$header-icon-color-hover: $tertiary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $tertiary !important; } // dropdown item on hover
$header-icon-border-color-hover: $tertiary;
$header-icon-color-hover: $tertiary;
// buttons
$btn-line-bg: #fff; // button bg
@ -40,11 +40,38 @@ $btn-copy-color: $tertiary; // btn copy
$btn-qr-color: $tertiary; // btn qr-code
//links & tile
.tile a { color: $tertiary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $tertiary;
} // tab active bg
$tile-body-a-color: $tertiary;
$tile-type-block-color: $tertiary;
$tile-type-progress-bar-color: $tertiary;
a.tile-title { color: $tertiary !important; }
// card
$card-background-1: $primary;
$card-tab-active: $primary;
$card-background-1: $tertiary;
$card-tab-active: $tertiary;
// dropdown
.dropdown-item {
&:hover,
&:active,
&.active {
background-color: rgba($tertiary, .1) !important;
color: $tertiary !important;
}
}
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}
// Badges
$badge-success-color: #15bba6;
$badge-success-background-color: rgba(#15bba6, .1);
$badge-neutral-color: $tertiary;
$badge-neutral-background-color: rgba($tertiary, .1);
$api-text-monospace-color: $tertiary;

@ -1,40 +1,53 @@
// general
$primary: #1d3154;
$secondary: #fdcec4;
$tertiary: #00ff00;
$tertiary: #a96c55;
$additional-font: #a1ded1;
$common-link-color: #2e4d84;
$dashboard-banner-gradient-start: #fdb8aa;
$dashboard-banner-gradient-end: #fdcec4;
$dashboard-stats-item-label-color: $primary;
$dashboard-stats-item-value-color: $primary;
$dashboard-stats-item-border-color: $primary;
$header-links-color-active: #333;
.dropdown-item:hover, .dropdown-item:focus { background-color: $primary !important; }
$tile-type-block-color: $secondary;
$navbar-logo-height: 18px;
$navbar-logo-width: 100px;
$tile-body-a-color: $tertiary;
$tile-type-block-color: $tertiary;
$tile-type-progress-bar-color: $tertiary;
a.tile-title { color: $tertiary !important; }
// footer
$footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: $secondary;
$footer-item-disc-color: $secondary;
$footer-link-color: $secondary;
$footer-social-icon-color: $secondary;
$footer-text-color: #fff;
$footer-logo-height: 18px;
$footer-logo-width: 100px;
$btn-line-color: $primary;
.footer-logo {
filter: brightness(0) invert(1);
}
$dashboard-stats-item-color: $primary;
$dashboard-stats-item-border-color: $primary;
$stakes-stats-item-color: $primary;
$stakes-stats-item-border-color: $primary;
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$card-background-1: $secondary;
$card-background-1-text-color: $primary;
$dashboard-banner-chart-legend-label-color: $primary;
$dashboard-stats-item-label-color: $primary;
$dashboard-banner-chart-legend-value-color: $primary; // chart labels
$dashboard-stats-item-value-color: $primary; // stat values
$dashboard-stats-item-border-color: $primary; // stat border
$dashboard-banner-gradient-start: $secondary; // gradient begin
$dashboard-banner-gradient-end: $secondary; // gradient end
$dashboard-banner-network-plain-container-background-color: $secondary; // stats bg
// navigation
$header-icon-border-color-hover: $primary; // top border on hover
$header-icon-color-hover: $primary; // nav icon on hover
$dropdown-menu-item-hover-color: $primary !default;
$dropdown-menu-item-hover-background: rgba($primary, .1) !default;
// buttons
$btn-line-bg: #fff; // button bg
$btn-line-color: $primary; // button border and font color && hover bg color
$btn-copy-color: $primary; // btn copy
$btn-qr-color: $primary; // btn qr-code
// card
$card-background-1: $primary;
$card-tab-active: $primary;
$dashboard-banner-network-stats-static-image: "/images/lukso_dashboard_image.png";
@ -56,6 +69,7 @@ $dashboard-banner-network-plain-container-height: 150px;
margin: 0;
padding: 0;
width: 100%;
box-shadow: none;
@include media-breakpoint-down(lg) {
height: auto;
@ -91,6 +105,7 @@ $dashboard-banner-network-plain-container-height: 150px;
margin: 0 0 0 auto;
order: 150;
width: 301px;
box-shadow: none;
@include media-breakpoint-down(lg) {
display: none;
@ -126,5 +141,13 @@ $dashboard-banner-network-plain-container-height: 150px;
}
}
}
&:after {
box-shadow: none;
}
}
}
// Badges
$badge-neutral-color: $tertiary;
$badge-neutral-background-color: rgba($tertiary, .1);
$api-text-monospace-color: $tertiary;

@ -1,12 +1,3 @@
// $primary: #262d62;
// $secondary: #687bf6;
// $tertiary: #687bf6;
$dashboard-line-color-price: #8286a9 !default;
$base-border-color: #e2e5ec !default;
$common-container-margin: 50px !default;
// general
$primary: #5c34a2;
$secondary: #87e1a9;
@ -23,9 +14,10 @@ $footer-item-disc-color: $secondary;
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: #dcc8ff;
$dashboard-stats-item-label-color: $dashboard-banner-chart-legend-label-color;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
@ -33,14 +25,15 @@ $dashboard-banner-gradient-start: $primary; // gradient begin
$dashboard-banner-gradient-end: lighten($primary, 5); // gradient end
$dashboard-banner-network-plain-container-background-color: #865bd4; // stats bg
$dashboard-banner-network-plain-container-background-color: #8258cd; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $primary; // top border on hover
$header-icon-color-hover: $primary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $primary !important; } // dropdown item on hover
$dropdown-menu-item-hover-color: $primary !default;
$dropdown-menu-item-hover-background: rgba($primary, .1) !default;
$header-icon-color-hover: $primary;
$header-icon-border-color-hover: $primary;
// buttons
$btn-line-bg: #fff; // button bg
@ -49,23 +42,26 @@ $btn-copy-color: $primary; // btn copy
$btn-qr-color: $primary; // btn qr-code
//links & tile
.tile a { color: $primary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $primary;
} // tab active bg
$tile-body-a-color: $primary;
$tile-type-block-color: $primary;
$tile-type-progress-bar-color: $primary;
a.tile-title { color: $primary !important; }
// card
$card-background-1: $primary;
$card-tab-active: $primary;
.footer {
.tooltip {
.tooltip-inner {
background-color: darken($footer-background-color, 10) !important;
}
.arrow::before {
border-top-color: darken($footer-background-color, 10) !important;
border-bottom-color: darken($footer-background-color, 10) !important;
}
}
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}
// Badges
$badge-neutral-color: $primary;
$badge-neutral-background-color: rgba($primary, .1);
$api-text-monospace-color: $primary;

@ -14,9 +14,10 @@ $footer-item-disc-color: $secondary;
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: #dcc8ff;
$dashboard-stats-item-label-color: $dashboard-banner-chart-legend-label-color;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
@ -24,14 +25,15 @@ $dashboard-banner-gradient-start: $primary; // gradient begin
$dashboard-banner-gradient-end: lighten($primary, 5); // gradient end
$dashboard-banner-network-plain-container-background-color: #865bd4; // stats bg
$dashboard-banner-network-plain-container-background-color: #8258cd; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $primary; // top border on hover
$header-icon-color-hover: $primary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $primary !important; } // dropdown item on hover
$dropdown-menu-item-hover-color: $primary !default;
$dropdown-menu-item-hover-background: rgba($primary, .1) !default;
$header-icon-color-hover: $primary;
$header-icon-border-color-hover: $primary;
// buttons
$btn-line-bg: #fff; // button bg
@ -40,11 +42,26 @@ $btn-copy-color: $primary; // btn copy
$btn-qr-color: $primary; // btn qr-code
//links & tile
.tile a { color: $primary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $primary;
} // tab active bg
$tile-body-a-color: $primary;
$tile-type-block-color: $primary;
$tile-type-progress-bar-color: $primary;
a.tile-title { color: $primary !important; }
// card
$card-background-1: $primary;
$card-tab-active: $primary;
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}
// Badges
$badge-neutral-color: $primary;
$badge-neutral-background-color: rgba($primary, .1);
$api-text-monospace-color: $primary;

@ -1,29 +0,0 @@
$primary: #15bba6;
$secondary: #17314f;
$tertiary: #00ff00;
$header-links-color-active: #333;
$dashboard-banner-gradient-start: $secondary;
$dashboard-banner-gradient-end: #1e4168;
$dashboard-line-color-market: $primary;
$tile-type-block-border-color: $secondary;
$tile-type-block-color: #333;
$footer-background-color: #173250;
$footer-text-color: #909dac;
$navbar-logo-height: auto;
$navbar-logo-width: 100px;
$footer-logo-height: auto;
$footer-logo-width: 100px;
$card-background-1: $secondary;
$card-background-1-text-color: #fff;
$btn-copy-color: $secondary;
$btn-qr-color: $secondary;
$btn-dropdown-line-color: $secondary;

@ -1,22 +1,24 @@
// general
$primary: #193653;
$secondary: #49a2ee;
$tertiary: #41c3a9;
$additional-font: #a3ceff;
$primary: #153550;
$secondary: #38a9f5;
$tertiary: #76f1ff;
$additional-font: #89cae6;
// footer
$footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: $additional-font;
$footer-item-disc-color: $additional-font;
$footer-text-color: #89cae6;
$footer-item-disc-color: $secondary;
.footer-logo { filter: brightness(0) invert(1); }
.footer-social-icons .footer-social-icon { color: $secondary; }
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: #89cae6;
$dashboard-stats-item-label-color: #89cae6;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $tertiary; // stat border
@ -24,27 +26,34 @@ $dashboard-banner-gradient-start: $primary; // gradient begin
$dashboard-banner-gradient-end: lighten($primary, 5); // gradient end
$dashboard-banner-network-plain-container-background-color: #244468; // stats bg
$dashboard-banner-network-plain-container-background-color: #1c476c; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $tertiary; // top border on hover
$header-icon-color-hover: $tertiary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $tertiary !important; } // dropdown item on hover
// buttons
$btn-line-bg: #fff; // button bg
$btn-line-color: $tertiary; // button border and font color && hover bg color
$btn-copy-color: $tertiary; // btn copy
$btn-qr-color: $tertiary; // btn qr-code
$btn-line-color: $secondary; // button border and font color && hover bg color
$btn-copy-color: $secondary; // btn copy
$btn-qr-color: $secondary; // btn qr-code
//links & tile
.tile a { color: $tertiary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $tertiary;
} // tab active bg
$tile-body-a-color: $secondary;
$tile-type-block-color: $secondary;
$tile-type-progress-bar-color: $secondary;
a.tile-title { color: $secondary !important; }
// card
$card-background-1: $secondary;
$card-tab-active: $secondary;
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}

@ -10,13 +10,15 @@ $footer-title-color: #fff;
$footer-text-color: #89cae6;
$footer-item-disc-color: $secondary;
.footer-logo { filter: brightness(0) invert(1); }
.footer-social-icons .footer-social-icon { color: $secondary; }
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: #89cae6;
$dashboard-stats-item-label-color: #89cae6;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $tertiary; // stat border
@ -29,9 +31,6 @@ $dashboard-banner-network-plain-container-background-color: #1c476c; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $secondary; // top border on hover
$header-icon-color-hover: $secondary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $secondary !important; } // dropdown item on hover
// buttons
$btn-line-bg: #fff; // button bg
@ -40,11 +39,21 @@ $btn-copy-color: $secondary; // btn copy
$btn-qr-color: $secondary; // btn qr-code
//links & tile
.tile a { color: $secondary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $secondary;
} // tab active bg
$tile-body-a-color: $secondary;
$tile-type-block-color: $secondary;
$tile-type-progress-bar-color: $secondary;
a.tile-title { color: $secondary !important; }
// card
$card-background-1: $secondary;
$card-tab-active: $secondary;
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}

@ -4,34 +4,34 @@ $secondary: #27ac8d;
$tertiary: #e39a54;
$additional-font: #a1ded1;
$tile-body-a-color: $secondary;
$tile-type-block-color: $secondary;
$tile-type-progress-bar-color: $secondary;
a.tile-title { color: $secondary !important; }
// footer
$footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: $additional-font;
$footer-item-disc-color: $secondary;
.footer-logo { filter: brightness(0) invert(1); }
$footer-social-icon-color: $secondary;
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: $additional-font;
$dashboard-stats-item-label-color: $additional-font;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
$dashboard-banner-gradient-start: $primary; // gradient begin
$dashboard-banner-gradient-end: lighten($primary, 5); // gradient end
$dashboard-banner-gradient-end: #193039; // gradient end
$dashboard-banner-network-plain-container-background-color: #1a323b; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $secondary; // top border on hover
$header-icon-color-hover: $secondary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $secondary !important; } // dropdown item on hover
// buttons
$btn-line-bg: #fff; // button bg
@ -39,12 +39,29 @@ $btn-line-color: $secondary; // button border and font color && hover bg color
$btn-copy-color: $secondary; // btn copy
$btn-qr-color: $secondary; // btn qr-code
//links & tile
.tile a { color: $secondary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $secondary;
} // tab active bg
// card
$card-background-1: $secondary;
$card-tab-active: $secondary;
$card-tab-active: $secondary;
// ETC theme's idiosyncrasies
.layout-container {
.navbar {
box-shadow: 0 0 30px 0 rgba(21, 53, 80, 0.12);
}
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
.footer-logo {
filter: brightness(0) invert(1);
}
}
// Badges
$badge-neutral-color: #1a323b;
$badge-neutral-background-color: rgba(#1a323b, .1);

@ -3,21 +3,26 @@ $primary: #093731;
$secondary: #40bfb2;
$tertiary: #25c9ff;
$additional-font: #93e8dd;
$sub-accent-color: #1c9f90;
// footer
$footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: #93e8dd;
$footer-item-disc-color: $secondary;
$footer-text-color: $additional-font;
$footer-item-disc-color: $additional-font;
.footer-logo { filter: brightness(0) invert(1); }
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-line-color-price: $secondary;
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-line-color-market: $tertiary;
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-banner-chart-legend-label-color: $additional-font;
$dashboard-stats-item-label-color: $additional-font;
$dashboard-banner-chart-legend-value-color: #fff; // chart labels
$dashboard-stats-item-value-color: #fff; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
@ -30,22 +35,41 @@ $dashboard-banner-network-plain-container-background-color: #0e534a; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $secondary; // top border on hover
$header-icon-color-hover: $secondary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $secondary !important; } // dropdown item on hover
$dropdown-menu-item-hover-color: $sub-accent-color !default;
$dropdown-menu-item-hover-background: rgba($sub-accent-color, .1) !default;
$header-icon-color-hover: $sub-accent-color;
$header-icon-border-color-hover: $sub-accent-color;
// Logo Size
$footer-logo-height: 20px;
$navbar-logo-height: 20px;
// buttons
$btn-line-bg: #fff; // button bg
$btn-line-color: #1c9f90; // button border and font color && hover bg color
$btn-copy-color: #1c9f90; // btn copy
$btn-qr-color: #1c9f90; // btn qr-code
$btn-line-color: $sub-accent-color; // button border and font color && hover bg color
$btn-copy-color: $sub-accent-color; // btn copy
$btn-qr-color: $sub-accent-color; // btn qr-code
//links & tile
.tile a { color: $secondary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $secondary;
} // tab active bg
$tile-body-a-color: $sub-accent-color;
$tile-type-block-color: $sub-accent-color;
$tile-type-progress-bar-color: $sub-accent-color;
a.tile-title { color: $sub-accent-color !important; }
// card
$card-background-1: $secondary;
$card-tab-active: $secondary;
$card-background-1: $sub-accent-color;
$card-tab-active: $sub-accent-color;
.layout-container {
.dashboard-banner-container {
background-image: linear-gradient(
to bottom,
$dashboard-banner-gradient-start,
$dashboard-banner-gradient-end
);
}
}
// Badges
$badge-neutral-color: $tertiary;
$badge-neutral-background-color: rgba($tertiary, .1);

@ -19,6 +19,7 @@
// @import "sokol_variables";
// @import "tobalaba_variables";
// @import "tomochain_variables";
// @import "rsk_variables";
// responsive breakpoints
$breakpoint-xs: 320px;
@ -27,4 +28,4 @@ $breakpoint-md: 768px;
$breakpoint-lg: 992px;
$breakpoint-xl: 1024px;
$breakpoint-xxl: 1280px;
$breakpoint-xxxl: 1366px;
$breakpoint-xxxl: 1366px;

@ -18,6 +18,7 @@ function formatCurrencyValue (value, symbol) {
if (value < 0.000001) return `${window.localized['Less than']} ${symbol}0.000001`
if (value < 1) return `${symbol}${numeral(value).format('0.000000')}`
if (value < 100000) return `${symbol}${numeral(value).format('0,0.00')}`
if (value > 1000000000) return `${symbol}${numeral(value).format('0.000e+0')}`
return `${symbol}${numeral(value).format('0,0')}`
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

@ -1,21 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="111" height="36">
<defs>
<linearGradient id="a" x1="0%" x2="0%" y1="100%" y2="0%">
<stop offset="0%" stop-color="#FFF" stop-opacity="0"/>
<stop offset="100%" stop-color="#FFF"/>
</linearGradient>
<linearGradient id="b" x1="0%" x2="86.603%" y1="50%" y2="0%">
<stop offset="0%" stop-color="#FFF"/>
<stop offset="100%" stop-color="#FFF" stop-opacity="0"/>
</linearGradient>
</defs>
<path fill="#FFF" fill-rule="evenodd" d="M16.001 36L.005 26.999V8.998L16.001-.003l15.996 9.001v18.001L16.001 36zm10.074-23.52L15.994 6.83 5.912 12.48v11.301l10.082 5.65 10.081-5.65V12.48z" opacity=".4"/>
<path fill="none" d="M0 8.934l5.914 3.688v10.499L0 19.433V8.934z" opacity=".6"/>
<path fill="url(#a)" d="M0 8.934l5.914 3.688v10.499L0 19.433V8.934z"/>
<path fill="none" d="M31.992 8.934l-5.915 3.688v10.499l5.915-3.688V8.934z" opacity=".6"/>
<path fill="url(#a)" d="M31.992 8.934l-5.915 3.688v10.499l5.915-3.688V8.934z"/>
<path fill="none" d="M15.861 29.431l10.216-5.541v6.569L15.861 36v-6.569z" opacity=".6"/>
<path fill="url(#b)" d="M15.861 29.431l10.216-5.541v6.569L15.861 36v-6.569z"/>
<path fill="#FFF" fill-rule="evenodd" d="M16.494 25.007l-6.505-3.504v-7.007l6.505-3.504L23 14.496v7.007l-6.506 3.504z" opacity=".8"/>
<path fill="#FFF" fill-rule="evenodd" d="M16.987 17.727l6.014-3.74v7.281l-6.014 3.74v-7.281zM109.56 21.291c-.437.875-1.058 1.547-1.864 2.016-.805.47-1.752.704-2.84.704-1.098 0-2.05-.234-2.856-.704-.805-.469-1.426-1.141-1.864-2.016-.437-.874-.656-1.898-.656-3.072 0-1.173.216-2.194.648-3.064a4.664 4.664 0 0 1 1.864-2.008c.811-.469 1.766-.704 2.864-.704 1.099 0 2.051.235 2.856.704.806.47 1.424 1.139 1.856 2.008.432.87.648 1.891.648 3.064 0 1.174-.218 2.198-.656 3.072zm-2.28-6.136c-.581-.709-1.389-1.064-2.424-1.064-1.045 0-1.858.355-2.44 1.064-.581.71-.872 1.731-.872 3.064 0 1.334.291 2.358.872 3.072.582.715 1.395 1.072 2.44 1.072 1.035 0 1.843-.357 2.424-1.072.582-.714.872-1.738.872-3.072 0-1.333-.29-2.354-.872-3.064zm-9.624 8.776a.91.91 0 0 1-.48-.136.91.91 0 0 1-.352-.424l-.96-2.144h-5.632l-.96 2.144a.898.898 0 0 1-.352.424.932.932 0 0 1-.496.136c-.245 0-.469-.085-.672-.256a.787.787 0 0 1-.304-.624c0-.138.032-.277.096-.416l4.416-9.488c.096-.213.243-.376.44-.488.198-.112.408-.168.632-.168.224 0 .435.056.632.168.198.112.344.275.44.488l4.432 9.488a.989.989 0 0 1 .096.416.791.791 0 0 1-.296.624 1.007 1.007 0 0 1-.68.256zm-4.608-9.056l-2.112 4.752h4.224l-2.112-4.752zm-12.352 8.992h-3.168c-.309 0-.552-.085-.728-.256-.176-.17-.264-.41-.264-.72v-9.328c0-.309.088-.549.264-.72.176-.17.419-.256.728-.256h3.168c1.846 0 3.278.494 4.296 1.48 1.019.987 1.528 2.371 1.528 4.152 0 1.792-.509 3.182-1.528 4.168-1.018.987-2.45 1.48-4.296 1.48zm-.128-9.6H78.6v7.92h1.968c2.592 0 3.888-1.322 3.888-3.968 0-2.634-1.296-3.952-3.888-3.952zm-10.079 3.152c.949.214 1.72.451 2.312.712.592.262 1.045.595 1.36 1 .314.406.472.912.472 1.52a2.9 2.9 0 0 1-.552 1.752c-.368.507-.886.902-1.552 1.184-.667.283-1.432.424-2.296.424a8.061 8.061 0 0 1-2.328-.328c-.731-.218-1.326-.514-1.784-.888-.246-.181-.368-.437-.368-.768a.9.9 0 0 1 .2-.584c.133-.165.29-.248.472-.248.192 0 .41.075.656.224.458.331.938.571 1.44.72a5.79 5.79 0 0 0 1.664.224c.778 0 1.376-.136 1.792-.408.416-.272.624-.669.624-1.192 0-.405-.195-.717-.584-.936-.39-.218-1.038-.429-1.944-.632-.939-.202-1.702-.437-2.288-.704-.587-.266-1.03-.608-1.328-1.024-.299-.416-.448-.944-.448-1.584 0-.661.186-1.253.56-1.776.373-.522.893-.93 1.56-1.224.666-.293 1.416-.44 2.248-.44 1.525 0 2.768.406 3.728 1.216.138.118.237.232.296.344a.919.919 0 0 1 .088.424.903.903 0 0 1-.2.584c-.134.166-.291.248-.472.248a.88.88 0 0 1-.296-.048 2.281 2.281 0 0 1-.36-.176 5.445 5.445 0 0 0-1.272-.712c-.411-.154-.915-.232-1.512-.232-.726 0-1.299.147-1.72.44-.422.294-.632.702-.632 1.224 0 .438.186.774.56 1.008.373.235 1.008.454 1.904.656zm-8.76 5.888c-.806.47-1.752.704-2.84.704-1.099 0-2.051-.234-2.856-.704-.806-.469-1.427-1.141-1.864-2.016-.438-.874-.656-1.898-.656-3.072 0-1.173.216-2.194.648-3.064a4.658 4.658 0 0 1 1.864-2.008c.81-.469 1.765-.704 2.864-.704 1.098 0 2.05.235 2.856.704a4.677 4.677 0 0 1 1.856 2.008c.432.87.648 1.891.648 3.064 0 1.174-.219 2.198-.656 3.072-.438.875-1.059 1.547-1.864 2.016zm-.416-8.152c-.582-.709-1.39-1.064-2.424-1.064-1.046 0-1.859.355-2.44 1.064-.582.71-.872 1.731-.872 3.064 0 1.334.29 2.358.872 3.072.581.715 1.394 1.072 2.44 1.072 1.034 0 1.842-.357 2.424-1.072.581-.714.872-1.738.872-3.072 0-1.333-.291-2.354-.872-3.064zm-13.032 4.328h-2.864v3.44c0 .32-.094.574-.28.76-.187.187-.44.28-.76.28-.31 0-.558-.093-.744-.28-.187-.186-.28-.44-.28-.76v-9.36c0-.309.088-.549.264-.72.176-.17.418-.256.728-.256h3.936c1.205 0 2.144.302 2.816.904.672.603 1.008 1.448 1.008 2.536s-.336 1.936-1.008 2.544c-.672.608-1.611.912-2.816.912zm-.256-5.296h-2.608v3.712h2.608c1.418 0 2.128-.618 2.128-1.856 0-1.237-.71-1.856-2.128-1.856z"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

@ -1,47 +1,3 @@
<svg id="_-e-logo_top_rsk" data-name="-e-logo_top_rsk" xmlns="http://www.w3.org/2000/svg" width="76.406" height="40" viewBox="0 0 76.406 40">
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c140 79.160451, 2017/05/06-01:08:21 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""/>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?></metadata>
<defs>
<style>
.cls-1 {
fill: #27aa8b;
}
.cls-1, .cls-2 {
fill-rule: evenodd;
}
.cls-2 {
fill: #27ac8d;
}
</style>
</defs>
<path id="Эллипс_1" data-name="Эллипс 1" class="cls-1" d="M103,11a4.03,4.03,0,1,1-3.952,4.03A3.991,3.991,0,0,1,103,11Zm0,31.944a4.028,4.028,0,1,1-3.954,4.028A3.992,3.992,0,0,1,103,42.944ZM88.955,19.056A4.028,4.028,0,1,1,85,23.083,3.992,3.992,0,0,1,88.955,19.056Zm0,15.833A4.028,4.028,0,1,1,85,38.917,3.992,3.992,0,0,1,88.955,34.889Zm28.091-15.833a4.028,4.028,0,1,1-3.954,4.028A3.991,3.991,0,0,1,117.045,19.056Zm0,15.833a4.028,4.028,0,1,1-3.954,4.028A3.991,3.991,0,0,1,117.045,34.889Zm-1.093-8.2h2.178v8.9h-2.178v-8.9Zm-28.082,0h2.178v8.9H87.87v-8.9Zm17.386-9.106,1.091-1.924,9.672,5.687-1.091,1.924Zm-4.3.067-1.092-1.931-9.679,5.707,1.092,1.931Zm-0.035,26.994-1.089,1.909-9.648-5.642L91.27,39Zm4.292-.067L106.3,46.5l9.656-5.662-1.09-1.916Zm-4.292-15.767-1.089,1.909L90.182,25.08l1.088-1.909Zm4.292-.067,1.089,1.916L115.955,25l-1.09-1.916Zm0.009,4.718,1.088-1.909,9.648,5.642-1.089,1.909Zm-4.293.067-1.089-1.916-9.655,5.662,1.089,1.916Zm0.978-16H104.1v8.882H101.9V17.529Zm0,16.941H104.1v8.9H101.9v-8.9ZM103,24.056s4.364,3.632,4.364,7.083S103,38.222,103,38.222s-4.364-3.632-4.364-7.083S103,24.056,103,24.056Zm0,2.639s2.727,2.279,2.727,4.444S103,35.583,103,35.583s-2.727-2.279-2.727-4.444S103,26.694,103,26.694Zm0,4.173a1.1,1.1,0,0,1,1.1,1.1v6.69a1.1,1.1,0,1,1-2.192,0v-6.69A1.1,1.1,0,0,1,103,30.868Zm-14.046-9.59a1.806,1.806,0,1,1-1.773,1.806A1.789,1.789,0,0,1,88.955,21.278ZM103,12.945a1.806,1.806,0,1,1-1.773,1.806A1.79,1.79,0,0,1,103,12.945Zm14.045,8.333a1.806,1.806,0,1,1-1.772,1.806A1.789,1.789,0,0,1,117.045,21.278Zm0,15.833a1.806,1.806,0,1,1-1.772,1.806A1.789,1.789,0,0,1,117.045,37.111ZM103,45.167a1.806,1.806,0,1,1-1.773,1.806A1.79,1.79,0,0,1,103,45.167ZM88.955,37.111a1.806,1.806,0,1,1-1.773,1.806A1.789,1.789,0,0,1,88.955,37.111Z" transform="translate(-85 -11)"/>
<path id="rsk" class="cls-2" d="M134.057,37.863V29.487l0.528-.216a16.858,16.858,0,0,1,3.528-1.056V25.6a11.416,11.416,0,0,0-4.08,1.7v-1.44h-2.592v12h2.616Zm14.424-11.712-0.744-.144a22.876,22.876,0,0,0-3.768-.384,5.371,5.371,0,0,0-3.228.912,3.183,3.183,0,0,0-1.26,2.76,3.029,3.029,0,0,0,.912,2.544,6.571,6.571,0,0,0,2.868,1.02,10.246,10.246,0,0,1,2.472.6,1.029,1.029,0,0,1,.516,1,1.1,1.1,0,0,1-.54,1.032,3.843,3.843,0,0,1-1.812.312,35.663,35.663,0,0,1-4.152-.384l-0.1,2.184,0.744,0.12a21.326,21.326,0,0,0,3.7.408,5.941,5.941,0,0,0,3.54-.888,3.22,3.22,0,0,0,1.212-2.784,3.412,3.412,0,0,0-.84-2.64,5.863,5.863,0,0,0-2.844-1.092,12.128,12.128,0,0,1-2.544-.612,0.932,0.932,0,0,1-.54-0.912,1.029,1.029,0,0,1,.492-0.948,3.661,3.661,0,0,1,1.764-.3,34.588,34.588,0,0,1,4.1.384Zm5.5,6.816,1.56-.168,2.928,5.064h2.952l-3.648-6.384,3.456-5.616H158.3l-2.832,4.68-1.488.144V20.871h-2.616V37.863h2.616v-4.9Z" transform="translate(-85 -11)"/>
<svg xmlns="http://www.w3.org/2000/svg" width="85" height="40">
<path fill="#27AA8B" fill-rule="evenodd" d="M84.986 28.636H80.95l-4.003-7.046-2.133.234v6.812h-3.576V4.995h3.576v13.657l2.035-.2 3.871-6.512h4.003l-4.725 7.814 4.988 8.882zm-22.229-9.934c1.826.323 3.122.83 3.888 1.519.765.69 1.148 1.915 1.148 3.673 0 1.759-.553 3.05-1.657 3.874-1.105.823-2.718 1.235-4.84 1.235-1.334 0-3.018-.189-5.052-.568l-1.018-.166.132-3.039c2.625.356 4.516.534 5.676.534 1.159 0 1.985-.144 2.477-.434.492-.289.738-.768.738-1.436 0-.667-.235-1.129-.705-1.385-.471-.256-1.597-.535-3.379-.835-1.784-.301-3.09-.773-3.921-1.419-.832-.646-1.247-1.825-1.247-3.54 0-1.714.574-2.994 1.722-3.84 1.149-.846 2.62-1.269 4.413-1.269 1.4 0 3.117.179 5.152.535l1.017.2-.066 3.039c-2.581-.356-4.451-.535-5.61-.535-1.16 0-1.964.14-2.412.418-.449.278-.673.718-.673 1.319s.246 1.024.739 1.268c.492.246 1.651.529 3.478.852zm-15.175-1.72v11.654h-3.577V11.94h3.544v2.004c1.859-1.224 3.718-2.015 5.578-2.371v3.64c-1.882.378-3.489.868-4.823 1.469l-.722.3zM36 27.917c0 2.224-1.77 4.027-3.955 4.027a3.9 3.9 0 0 1-2.747-1.138l-7.433 4.358c.053.262.09.53.09.808C21.955 38.197 20.184 40 18 40s-3.955-1.803-3.955-4.028c0-.283.038-.555.093-.82l-7.434-4.348a3.9 3.9 0 0 1-2.749 1.14C1.77 31.944 0 30.141 0 27.917a4.004 4.004 0 0 1 2.875-3.857v-8.12A4.004 4.004 0 0 1 0 12.083c0-2.224 1.77-4.027 3.955-4.027 1.175 0 2.219.532 2.943 1.361L14.22 5.1a4.098 4.098 0 0 1-.158-1.069C14.062 1.805 15.825 0 18 0c2.175 0 3.938 1.805 3.938 4.031 0 .315-.044.618-.111.912l7.382 4.341a3.905 3.905 0 0 1 2.836-1.228C34.23 8.056 36 9.859 36 12.083a4.004 4.004 0 0 1-2.875 3.857v8.12A4.004 4.004 0 0 1 36 27.917zm-7.781.967a4.062 4.062 0 0 1-.128-.967c0-.275.028-.543.079-.802l-6.743-3.944c-.685 1.21-1.613 2.281-2.333 3.019V32.12c.678.2 1.276.584 1.752 1.087l7.373-4.323zM18 19.875c.604 0 1.094.49 1.094 1.094v2.523c.759-.864 1.633-2.126 1.633-3.353 0-2.166-2.727-4.445-2.727-4.445s-2.727 2.279-2.727 4.445c0 1.227.874 2.489 1.633 3.353v-2.523c0-.604.49-1.094 1.094-1.094zm0 17.903c.979 0 1.773-.809 1.773-1.806s-.794-1.805-1.773-1.805c-.979 0-1.773.808-1.773 1.805 0 .997.794 1.806 1.773 1.806zm-2.842-4.576a3.968 3.968 0 0 1 1.748-1.082V26.19c-.697-.715-1.591-1.74-2.27-2.902L7.845 27.27c.034.212.064.425.064.647 0 .336-.052.658-.129.97l7.378 4.315zM2.182 27.917c0 .997.793 1.805 1.773 1.805.979 0 1.772-.808 1.772-1.805 0-.998-.793-1.806-1.772-1.806-.98 0-1.773.808-1.773 1.806zm1.773-17.639c-.98 0-1.773.808-1.773 1.805 0 .998.793 1.806 1.773 1.806.979 0 1.772-.808 1.772-1.806 0-.997-.793-1.805-1.772-1.805zm2.749 4.693a3.952 3.952 0 0 1-1.641.959v8.143c.72.221 1.36.63 1.846 1.191l6.872-4.029a4.74 4.74 0 0 1-.145-1.096c0-.345.054-.692.133-1.037l-7.065-4.131zm8.655-7.968l-7.514 4.43c.034.213.064.428.064.65 0 .337-.052.659-.129.971l6.825 3.992c.684-1.187 1.593-2.229 2.301-2.955V7.883a3.952 3.952 0 0 1-1.547-.88zM18 1.944c-.979 0-1.773.809-1.773 1.806S17.021 5.556 18 5.556c.979 0 1.773-.809 1.773-1.806S18.979 1.944 18 1.944zm10.179 9.301L20.774 6.89c-.46.469-1.04.804-1.68.995v6.206c.709.727 1.619 1.771 2.303 2.96l6.822-4a4.063 4.063 0 0 1-.128-.968c0-.288.032-.567.088-.838zm1.119 3.727l-7.064 4.142c.077.341.13.684.13 1.025 0 .321-.049.644-.117.966l6.93 4.053a3.953 3.953 0 0 1 1.76-1.086V15.93a3.943 3.943 0 0 1-1.639-.958zm4.52-2.889c0-.997-.793-1.805-1.773-1.805a1.75 1.75 0 0 0-1.364.665l-.294.519a1.83 1.83 0 0 0-.114.621c0 .998.793 1.806 1.772 1.806.98 0 1.773-.808 1.773-1.806zm-1.773 14.028c-.979 0-1.772.808-1.772 1.806 0 .997.793 1.805 1.772 1.805.98 0 1.773-.808 1.773-1.805 0-.998-.793-1.806-1.773-1.806z"/>
</svg>

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -1 +1,3 @@
<svg id="_-e-logo_top" data-name="-e-logo_top" xmlns="http://www.w3.org/2000/svg" width="96" height="19"><defs><style>.cls-1{fill:#40bfb2;fill-rule:evenodd}</style></defs><path id="_2" data-name="2" class="cls-1" d="M108.627 22h14.51a3.182 3.182 0 0 1 2.886 2.269l3.888 14.463A1.683 1.683 0 0 1 128.245 41h-14.509a3.183 3.183 0 0 1-2.887-2.269l-3.889-14.462A1.683 1.683 0 0 1 108.627 22zm-21.354 0A2.273 2.273 0 1 1 85 24.274 2.273 2.273 0 0 1 87.273 22zm-1.133 9.656A1.125 1.125 0 1 1 85 32.781a1.133 1.133 0 0 1 1.141-1.125zM85 24.266h25.609v8.516H85v-8.516zM87.281 22h23.031v2.266H87.281V22zM86 32h25v2H86v-2zm18.471-.075h6.259L113.166 41h-6.259zM98 25h5.521L105 31.009h-5.521zm-9 0h5.521L96 31.009h-5.525zm24 0h10.239l2.751 10h-10.24zm3 11.01h2.363L119 38h-2.362zm8.007 0h2.363L127 38h-2.362z" transform="translate(-85 -22)"/><path id="_3" data-name="3" class="cls-1" d="M141.538 37a4.271 4.271 0 0 0 2.554-.7 2.164 2.164 0 0 0 .968-1.839 1.96 1.96 0 0 0-1.269-1.993 9.24 9.24 0 0 0-1.925-.6 7.486 7.486 0 0 1-1.286-.372 1.588 1.588 0 0 1-.639-.435 1.012 1.012 0 0 1-.191-.643 1.2 1.2 0 0 1 .52-1.015 2.276 2.276 0 0 1 1.377-.381 3.092 3.092 0 0 1 1.132.181 5.827 5.827 0 0 1 .967.507 1.366 1.366 0 0 0 .657.308.45.45 0 0 0 .346-.163.573.573 0 0 0 .146-.4 1.179 1.179 0 0 0-.62-.906 4.12 4.12 0 0 0-1.177-.534 4.988 4.988 0 0 0-1.378-.19 4.3 4.3 0 0 0-1.761.344 2.944 2.944 0 0 0-1.213.942 2.27 2.27 0 0 0-.438 1.377 1.947 1.947 0 0 0 .692 1.58 5.439 5.439 0 0 0 2.3.924 9.919 9.919 0 0 1 1.441.389 1.662 1.662 0 0 1 .694.435.987.987 0 0 1 .2.643 1.107 1.107 0 0 1-.547 1 2.876 2.876 0 0 1-1.533.344 4.065 4.065 0 0 1-1.341-.19 6.079 6.079 0 0 1-1.086-.516 1.368 1.368 0 0 0-.639-.272.452.452 0 0 0-.355.154.562.562 0 0 0-.137.389.765.765 0 0 0 .137.462 1.786 1.786 0 0 0 .465.408 4.872 4.872 0 0 0 1.341.562 6.254 6.254 0 0 0 1.6.2zm10.641 0a4.3 4.3 0 0 0 2.211-.562 3.73 3.73 0 0 0 1.477-1.6 5.928 5.928 0 0 0 0-4.838 3.733 3.733 0 0 0-1.477-1.6 4.3 4.3 0 0 0-2.211-.562 4.248 4.248 0 0 0-2.2.562 3.737 3.737 0 0 0-1.468 1.6 5.928 5.928 0 0 0 0 4.838 3.735 3.735 0 0 0 1.468 1.6 4.246 4.246 0 0 0 2.2.562zm0-1.214a2.418 2.418 0 0 1-2-.87 3.915 3.915 0 0 1-.7-2.5 3.886 3.886 0 0 1 .707-2.491 2.7 2.7 0 0 1 3.986 0 3.88 3.88 0 0 1 .707 2.491 3.913 3.913 0 0 1-.7 2.51 2.43 2.43 0 0 1-2 .861zm14.731-.072l-3.83-3.414 3.493-3.189a.728.728 0 0 0 .249-.544.652.652 0 0 0-.195-.471.626.626 0 0 0-.461-.2.655.655 0 0 0-.479.217l-4.238 3.968v-7.352a.7.7 0 0 0-.2-.534.711.711 0 0 0-.5-.19.734.734 0 0 0-.523.19.692.692 0 0 0-.2.534v11.506a.691.691 0 0 0 .2.535.735.735 0 0 0 .523.19.712.712 0 0 0 .5-.19.7.7 0 0 0 .2-.535v-3.57l4.628 4.077a.741.741 0 0 0 .479.217.6.6 0 0 0 .452-.2.668.668 0 0 0 .186-.471.8.8 0 0 0-.284-.58zM173.158 37a4.275 4.275 0 0 0 2.2-.562 3.726 3.726 0 0 0 1.472-1.6 5.949 5.949 0 0 0 0-4.838 3.728 3.728 0 0 0-1.472-1.6 4.277 4.277 0 0 0-2.2-.562 4.222 4.222 0 0 0-2.194.562 3.739 3.739 0 0 0-1.463 1.6 5.938 5.938 0 0 0 0 4.838 3.737 3.737 0 0 0 1.463 1.6 4.22 4.22 0 0 0 2.194.562zm0-1.214a2.407 2.407 0 0 1-2-.87 3.927 3.927 0 0 1-.695-2.5 3.9 3.9 0 0 1 .7-2.491 2.686 2.686 0 0 1 3.974 0 3.9 3.9 0 0 1 .7 2.491 3.919 3.919 0 0 1-.695 2.51 2.418 2.418 0 0 1-2 .861zm7.116 1.178a.735.735 0 0 0 .515-.19.69.69 0 0 0 .211-.539V24.729a.69.69 0 0 0-.208-.534.734.734 0 0 0-.515-.19.759.759 0 0 0-.533.19.69.69 0 0 0-.207.534v11.506a.69.69 0 0 0 .207.535.76.76 0 0 0 .533.19z" transform="translate(-85 -22)"/><path id="_1" data-name="1" class="cls-1" d="M87.273 36.453A2.273 2.273 0 1 1 85 38.727a2.273 2.273 0 0 1 2.273-2.274zM86 36a1 1 0 1 1-1 1 1 1 0 0 1 1-1zm-1 1.5h1.5V39H85v-1.5zm2.5-1.5h14v5h-14v-5zm12.494.008h3.266L104.5 41h-3.267zM86 36h1.5v1.5H86V36z" transform="translate(-85 -22)"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="192" height="38">
<path fill="#40BFB2" fill-rule="evenodd" d="M191.578 29.54c-.277.253-.621.38-1.03.38-.433 0-.789-.127-1.065-.38-.278-.254-.416-.61-.416-1.069V5.458c0-.458.138-.815.416-1.069.276-.253.632-.38 1.065-.38.409 0 .753.127 1.03.38.276.254.415.611.415 1.069v23.013c0 .459-.139.815-.415 1.069zm-10.855-.671c-1.276.749-2.745 1.124-4.407 1.124-1.661 0-3.124-.375-4.389-1.124-1.264-.748-2.239-1.817-2.926-3.207-.686-1.389-1.029-3.002-1.029-4.838 0-1.836.343-3.448 1.029-4.838.687-1.389 1.662-2.458 2.926-3.207 1.265-.749 2.728-1.124 4.389-1.124 1.662 0 3.131.375 4.407 1.124 1.276.749 2.258 1.818 2.944 3.207.687 1.39 1.03 3.002 1.03 4.838 0 1.836-.343 3.449-1.03 4.838-.686 1.39-1.668 2.459-2.944 3.207zm-.433-13.028c-.939-1.171-2.264-1.758-3.974-1.758-1.71 0-3.034.587-3.973 1.758-.939 1.172-1.409 2.833-1.409 4.983 0 2.175.463 3.841 1.391 5.001.926 1.16 2.258 1.74 3.991 1.74 1.734 0 3.065-.574 3.992-1.722.927-1.147 1.391-2.82 1.391-5.019 0-2.15-.47-3.811-1.409-4.983zM163.111 29.92c-.307 0-.626-.145-.957-.435l-9.256-8.154v7.14c0 .459-.136.815-.408 1.069-.272.253-.609.38-1.011.38-.425 0-.774-.127-1.046-.38-.272-.254-.408-.61-.408-1.069V5.458c0-.458.136-.815.408-1.069.272-.253.621-.38 1.046-.38.402 0 .739.127 1.011.38.272.254.408.611.408 1.069v14.714l8.476-7.937c.283-.29.603-.435.957-.435.355 0 .662.134.922.399.26.266.39.58.39.942 0 .411-.165.774-.496 1.087l-6.986 6.379 7.66 6.813c.378.362.567.749.567 1.159 0 .363-.124.677-.372.943-.248.265-.55.398-.905.398zm-24.331-1.051c-1.281.749-2.754 1.124-4.421 1.124-1.667 0-3.135-.375-4.404-1.124-1.268-.748-2.246-1.817-2.935-3.207-.689-1.389-1.033-3.002-1.033-4.838 0-1.836.344-3.448 1.033-4.838.689-1.389 1.667-2.458 2.935-3.207 1.269-.749 2.737-1.124 4.404-1.124 1.667 0 3.14.375 4.421 1.124 1.28.749 2.265 1.818 2.953 3.207.689 1.39 1.033 3.002 1.033 4.838 0 1.836-.344 3.449-1.033 4.838-.688 1.39-1.673 2.459-2.953 3.207zm-.435-13.028c-.942-1.171-2.271-1.758-3.986-1.758-1.716 0-3.045.587-3.987 1.758-.942 1.172-1.413 2.833-1.413 4.983 0 2.175.465 3.841 1.395 5.001.93 1.16 2.265 1.74 4.005 1.74 1.739 0 3.074-.574 4.004-1.722.93-1.147 1.395-2.82 1.395-5.019 0-2.15-.471-3.811-1.413-4.983zm-27.186 3.153c.596.254 1.454.502 2.573.743 1.655.362 2.938.761 3.851 1.196.912.435 1.563.966 1.952 1.594.389.629.584 1.426.584 2.392 0 1.522-.645 2.749-1.934 3.678-1.29.931-2.993 1.396-5.109 1.396a12.49 12.49 0 0 1-3.194-.399c-1.01-.266-1.904-.64-2.682-1.123-.438-.29-.748-.562-.931-.816-.182-.254-.273-.561-.273-.924 0-.314.091-.573.273-.779a.91.91 0 0 1 .712-.308c.292 0 .717.181 1.277.543.73.435 1.454.78 2.172 1.033.717.254 1.611.381 2.682.381 1.314 0 2.336-.229 3.066-.689.729-.458 1.094-1.123 1.094-1.993 0-.531-.133-.96-.401-1.286-.268-.327-.73-.616-1.387-.87s-1.618-.513-2.883-.779c-2.141-.459-3.674-1.075-4.598-1.848-.925-.773-1.387-1.824-1.387-3.153 0-1.039.292-1.957.876-2.755.584-.797 1.392-1.425 2.427-1.884 1.033-.459 2.208-.689 3.522-.689.948 0 1.866.127 2.755.381a8.24 8.24 0 0 1 2.354 1.069c.827.58 1.241 1.184 1.241 1.812 0 .314-.098.58-.292.797a.9.9 0 0 1-.694.326c-.292 0-.73-.204-1.314-.616a11.668 11.668 0 0 0-1.934-1.014c-.608-.242-1.363-.363-2.262-.363-1.144 0-2.063.254-2.756.761-.693.508-1.04 1.184-1.04 2.03 0 .532.128.96.383 1.286.256.326.681.616 1.277.87zM86 38H44l-4-14H2c-1.965 0-2-2-2-2V4C0 .176 4 0 4 0h74c2.34 0 4 6 4 6l8 28s.047 4-4 4zM19.031 5.992H7.99l2.959 12.025h11.042l-2.96-12.025zm18.009 0H25.998l2.96 12.025h11.041L37.04 5.992zM63.27 31.99h4.724l-1.269-3.977h-4.724l1.269 3.977zM76.484 5.993H56.005l5.501 20.003h20.479L76.484 5.993zm6.255 22.02h-4.724l1.269 3.977h4.724l-1.269-3.977zM39 38H4c-3.883 0-4-4-4-4v-6h36l3 10z"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

@ -35,6 +35,11 @@ config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: t
# Configures the endpoint
config :block_scout_web, BlockScoutWeb.Endpoint,
instrumenters: [BlockScoutWeb.Prometheus.Instrumenter, SpandexPhoenix.Instrumenter],
http: [
protocol_options: [
idle_timeout: 90_000
]
],
url: [
host: "localhost",
path: System.get_env("NETWORK_PATH") || "/"

@ -15,8 +15,16 @@ port =
end
config :block_scout_web, BlockScoutWeb.Endpoint,
http: [port: port || 4000],
http: [
protocol_options: [
idle_timeout: 90_000
],
port: port || 4000
],
https: [
protocol_options: [
idle_timeout: 90_000
],
port: (port && port + 1) || 4001,
cipher_suite: :strong,
certfile: System.get_env("CERTFILE") || "priv/cert/selfsigned.pem",

@ -11,9 +11,10 @@ defmodule BlockScoutWeb.RewardChannel do
intercept(["new_reward"])
def join("rewards:" <> address_hash, _params, socket) do
{:ok, hash} = Chain.string_to_address_hash(address_hash)
{:ok, address} = Chain.hash_to_address(hash)
{:ok, %{}, assign(socket, :current_address, address)}
with {:ok, hash} <- Chain.string_to_address_hash(address_hash),
{:ok, address} <- Chain.hash_to_address(hash) do
{:ok, %{}, assign(socket, :current_address, address)}
end
end
def handle_out("new_reward", %{emission_funds: emission_funds, validator: validator}, socket) do

@ -12,8 +12,9 @@ defmodule BlockScoutWeb.Controller do
def not_found(conn) do
conn
|> put_status(:not_found)
|> put_view(BlockScoutWeb.ErrorView)
|> render("404.html")
|> put_view(BlockScoutWeb.PageNotFoundView)
|> render(:index)
|> halt()
end
def unprocessable_entity(conn) do

@ -28,7 +28,7 @@ defmodule BlockScoutWeb.AddressTransactionController do
def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{:ok, address} <- Chain.hash_to_address(address_hash, [:names], false) do
options =
@transaction_necessity_by_association
|> put_in([:necessity_by_association, :block], :required)

@ -20,6 +20,35 @@ defmodule BlockScoutWeb.API.RPC.AddressController do
|> render(:listaccounts, %{accounts: accounts})
end
def eth_get_balance(conn, params) do
with {:address_param, {:ok, address_param}} <- fetch_address(params),
{:block_param, {:ok, block}} <- {:block_param, fetch_block_param(params)},
{:format, {:ok, address_hash}} <- to_address_hash(address_param),
{:balance, {:ok, balance}} <- {:balance, Chain.get_balance_as_of_block(address_hash, block)} do
render(conn, :eth_get_balance, %{balance: Wei.hex_format(balance)})
else
{:address_param, :error} ->
conn
|> put_status(400)
|> render(:eth_get_balance_error, %{message: "Query parameter 'address' is required"})
{:format, :error} ->
conn
|> put_status(400)
|> render(:eth_get_balance_error, %{error: "Invalid address hash"})
{:block_param, :error} ->
conn
|> put_status(400)
|> render(:eth_get_balance_error, %{error: "Invalid block"})
{:balance, {:error, :not_found}} ->
conn
|> put_status(404)
|> render(:eth_get_balance_error, %{error: "Balance not found"})
end
end
def balance(conn, params, template \\ :balance) do
with {:address_param, {:ok, address_param}} <- fetch_address(params),
{:format, {:ok, address_hashes}} <- to_address_hashes(address_param) do
@ -217,6 +246,20 @@ defmodule BlockScoutWeb.API.RPC.AddressController do
{:required_params, result}
end
defp fetch_block_param(%{"block" => "latest"}), do: {:ok, :latest}
defp fetch_block_param(%{"block" => "earliest"}), do: {:ok, :earliest}
defp fetch_block_param(%{"block" => "pending"}), do: {:ok, :pending}
defp fetch_block_param(%{"block" => string_integer}) when is_bitstring(string_integer) do
case Integer.parse(string_integer) do
{integer, ""} -> {:ok, integer}
_ -> :error
end
end
defp fetch_block_param(%{"block" => _block}), do: :error
defp fetch_block_param(_), do: {:ok, :latest}
defp to_valid_format(params, :tokenbalance) do
result =
with {:ok, contract_address_hash} <- to_address_hash(params, "contractaddress"),

@ -0,0 +1,355 @@
defmodule BlockScoutWeb.API.RPC.EthController do
use BlockScoutWeb, :controller
alias Ecto.Type, as: EctoType
alias Explorer.{Chain, Repo}
alias Explorer.Chain.{Block, Data, Hash, Hash.Address, Wei}
alias Explorer.Etherscan.Logs
@methods %{
"eth_getBalance" => %{
action: :eth_get_balance,
notes: """
the `earliest` parameter will not work as expected currently, because genesis block balances
are not currently imported
"""
},
"eth_getLogs" => %{
action: :eth_get_logs,
notes: """
Will never return more than 1000 log entries.
"""
}
}
@index_to_word %{
0 => "first",
1 => "second",
2 => "third",
3 => "fourth"
}
def methods, do: @methods
def eth_request(%{body_params: %{"_json" => requests}} = conn, _) when is_list(requests) do
responses = responses(requests)
conn
|> put_status(200)
|> render("responses.json", %{responses: responses})
end
def eth_request(%{body_params: %{"_json" => request}} = conn, _) do
[response] = responses([request])
conn
|> put_status(200)
|> render("response.json", %{response: response})
end
def eth_request(conn, request) do
# In the case that the JSON body is sent up w/o a json content type,
# Phoenix encodes it as a single key value pair, with the value being
# nil and the body being the key (as in a CURL request w/ no content type header)
decoded_request =
with [{single_key, nil}] <- Map.to_list(request),
{:ok, decoded} <- Jason.decode(single_key) do
decoded
else
_ -> request
end
[response] = responses([decoded_request])
conn
|> put_status(200)
|> render("response.json", %{response: response})
end
def eth_get_balance(address_param, block_param \\ nil) do
with {:address, {:ok, address}} <- {:address, Chain.string_to_address_hash(address_param)},
{:block, {:ok, block}} <- {:block, block_param(block_param)},
{:balance, {:ok, balance}} <- {:balance, Chain.get_balance_as_of_block(address, block)} do
{:ok, Wei.hex_format(balance)}
else
{:address, :error} ->
{:error, "Query parameter 'address' is invalid"}
{:block, :error} ->
{:error, "Query parameter 'block' is invalid"}
{:balance, {:error, :not_found}} ->
{:error, "Balance not found"}
end
end
def eth_get_logs(filter_options) do
with {:ok, address_or_topic_params} <- address_or_topic_params(filter_options),
{:ok, from_block_param, to_block_param} <- logs_blocks_filter(filter_options),
{:ok, from_block} <- cast_block(from_block_param),
{:ok, to_block} <- cast_block(to_block_param) do
filter =
address_or_topic_params
|> Map.put(:from_block, from_block)
|> Map.put(:to_block, to_block)
|> Map.put(:allow_non_consensus, true)
{:ok, filter |> Logs.list_logs() |> Enum.map(&render_log/1)}
else
{:error, message} when is_bitstring(message) ->
{:error, message}
{:error, :empty} ->
{:ok, []}
_ ->
{:error, "Something went wrong."}
end
end
defp render_log(log) do
topics =
Enum.reject(
[log.first_topic, log.second_topic, log.third_topic, log.fourth_topic],
&is_nil/1
)
%{
"address" => to_string(log.address_hash),
"blockHash" => to_string(log.block_hash),
"blockNumber" => Integer.to_string(log.block_number, 16),
"data" => to_string(log.data),
"logIndex" => Integer.to_string(log.index, 16),
"removed" => log.block_consensus == false,
"topics" => topics,
"transactionHash" => to_string(log.transaction_hash),
"transactionIndex" => log.transaction_index,
"transactionLogIndex" => log.index,
"type" => "mined"
}
end
defp cast_block("0x" <> hexadecimal_digits = input) do
case Integer.parse(hexadecimal_digits, 16) do
{integer, ""} -> {:ok, integer}
_ -> {:error, input <> " is not a valid block number"}
end
end
defp cast_block(integer) when is_integer(integer), do: {:ok, integer}
defp cast_block(_), do: {:error, "invalid block number"}
defp address_or_topic_params(filter_options) do
address_param = Map.get(filter_options, "address")
topics_param = Map.get(filter_options, "topics")
with {:ok, address} <- validate_address(address_param),
{:ok, topics} <- validate_topics(topics_param) do
address_and_topics(address, topics)
end
end
defp address_and_topics(nil, nil), do: {:error, "Must supply one of address and topics"}
defp address_and_topics(address, nil), do: {:ok, %{address_hash: address}}
defp address_and_topics(nil, topics), do: {:ok, topics}
defp address_and_topics(address, topics), do: {:ok, Map.put(topics, :address_hash, address)}
defp validate_address(nil), do: {:ok, nil}
defp validate_address(address) do
case Address.cast(address) do
{:ok, address} -> {:ok, address}
:error -> {:error, "invalid address"}
end
end
defp validate_topics(nil), do: {:ok, nil}
defp validate_topics([]), do: []
defp validate_topics(topics) when is_list(topics) do
topics
|> Stream.with_index()
|> Enum.reduce({:ok, %{}}, fn {topic, index}, {:ok, acc} ->
case cast_topics(topic) do
{:ok, data} ->
with_filter = Map.put(acc, String.to_existing_atom("#{@index_to_word[index]}_topic"), data)
{:ok, add_operator(with_filter, index)}
:error ->
{:error, "invalid topics"}
end
end)
end
defp add_operator(filters, 0), do: filters
defp add_operator(filters, index) do
Map.put(filters, String.to_existing_atom("topic#{index - 1}_#{index}_opr"), "and")
end
defp cast_topics(topics) when is_list(topics) do
case EctoType.cast({:array, Data}, topics) do
{:ok, data} -> {:ok, Enum.map(data, &to_string/1)}
:error -> :error
end
end
defp cast_topics(topic) do
case Data.cast(topic) do
{:ok, data} -> {:ok, to_string(data)}
:error -> :error
end
end
defp responses(requests) do
Enum.map(requests, fn request ->
with {:id, {:ok, id}} <- {:id, Map.fetch(request, "id")},
{:request, {:ok, result}} <- {:request, do_eth_request(request)} do
format_success(result, id)
else
{:id, :error} -> format_error("id is a required field", 0)
{:request, {:error, message}} -> format_error(message, Map.get(request, "id"))
end
end)
end
defp logs_blocks_filter(filter_options) do
with {:filter, %{"blockHash" => block_hash_param}} <- {:filter, filter_options},
{:block_hash, {:ok, block_hash}} <- {:block_hash, Hash.Full.cast(block_hash_param)},
{:block, %{number: number}} <- {:block, Repo.get(Block, block_hash)} do
{:ok, number, number}
else
{:filter, filters} ->
from_block = Map.get(filters, "fromBlock", "latest")
to_block = Map.get(filters, "toBlock", "latest")
max_block_number =
if from_block == "latest" || to_block == "latest" do
max_consensus_block_number()
end
pending_block_number =
if from_block == "pending" || to_block == "pending" do
max_non_consensus_block_number(max_block_number)
end
if is_nil(pending_block_number) && from_block == "pending" && to_block == "pending" do
{:error, :empty}
else
to_block_numbers(from_block, to_block, max_block_number, pending_block_number)
end
{:block, _} ->
{:error, "Invalid Block Hash"}
{:block_hash, _} ->
{:error, "Invalid Block Hash"}
end
end
defp to_block_numbers(from_block, to_block, max_block_number, pending_block_number) do
actual_pending_block_number = pending_block_number || max_block_number
with {:ok, from} <-
to_block_number(from_block, max_block_number, actual_pending_block_number),
{:ok, to} <- to_block_number(to_block, max_block_number, actual_pending_block_number) do
{:ok, from, to}
end
end
defp to_block_number(integer, _, _) when is_integer(integer), do: {:ok, integer}
defp to_block_number("latest", max_block_number, _), do: {:ok, max_block_number || 0}
defp to_block_number("earliest", _, _), do: {:ok, 0}
defp to_block_number("pending", max_block_number, nil), do: {:ok, max_block_number || 0}
defp to_block_number("pending", _, pending), do: {:ok, pending}
defp to_block_number("0x" <> number, _, _) do
case Integer.parse(number, 16) do
{integer, ""} -> {:ok, integer}
_ -> {:error, "invalid block number"}
end
end
defp to_block_number(number, _, _) when is_bitstring(number) do
case Integer.parse(number, 16) do
{integer, ""} -> {:ok, integer}
_ -> {:error, "invalid block number"}
end
end
defp to_block_number(_, _, _), do: {:error, "invalid block number"}
defp max_non_consensus_block_number(max) do
case Chain.max_non_consensus_block_number(max) do
{:ok, number} -> number
_ -> nil
end
end
defp max_consensus_block_number do
case Chain.max_consensus_block_number() do
{:ok, number} -> number
_ -> nil
end
end
defp format_success(result, id) do
%{result: result, id: id}
end
defp format_error(message, id) do
%{error: message, id: id}
end
defp do_eth_request(%{"jsonrpc" => rpc_version}) when rpc_version != "2.0" do
{:error, "invalid rpc version"}
end
defp do_eth_request(%{"jsonrpc" => "2.0", "method" => method, "params" => params})
when is_list(params) do
with {:ok, action} <- get_action(method),
{:correct_arity, true} <-
{:correct_arity, :erlang.function_exported(__MODULE__, action, Enum.count(params))} do
apply(__MODULE__, action, params)
else
{:correct_arity, _} ->
{:error, "Incorrect number of params."}
_ ->
{:error, "Action not found."}
end
end
defp do_eth_request(%{"params" => _params, "method" => _}) do
{:error, "Invalid params. Params must be a list."}
end
defp do_eth_request(_) do
{:error, "Method, params, and jsonrpc, are all required parameters."}
end
defp get_action(action) do
case Map.get(@methods, action) do
%{action: action} ->
{:ok, action}
_ ->
:error
end
end
defp block_param("latest"), do: {:ok, :latest}
defp block_param("earliest"), do: {:ok, :earliest}
defp block_param("pending"), do: {:ok, :pending}
defp block_param(string_integer) when is_bitstring(string_integer) do
case Integer.parse(string_integer) do
{integer, ""} -> {:ok, integer}
_ -> :error
end
end
defp block_param(nil), do: {:ok, :latest}
defp block_param(_), do: :error
end

@ -1,6 +1,7 @@
defmodule BlockScoutWeb.APIDocsController do
use BlockScoutWeb, :controller
alias BlockScoutWeb.API.RPC.EthController
alias BlockScoutWeb.Etherscan
def index(conn, _params) do
@ -8,4 +9,10 @@ defmodule BlockScoutWeb.APIDocsController do
|> assign(:documentation, Etherscan.get_documentation())
|> render("index.html")
end
def eth_rpc(conn, _params) do
conn
|> assign(:documentation, EthController.methods())
|> render("eth_rpc.html")
end
end

@ -8,18 +8,20 @@ defmodule BlockScoutWeb.Chain.MarketHistoryChartController do
with true <- ajax?(conn) do
exchange_rate = Market.get_exchange_rate(Explorer.coin()) || Token.null()
recent_market_history = Market.fetch_recent_history()
market_history_data =
30
|> Market.fetch_recent_history()
|> case do
[today | the_rest] -> [%{today | closing_price: exchange_rate.usd_value} | the_rest]
data -> data
case recent_market_history do
[today | the_rest] ->
encode_market_history_data([%{today | closing_price: exchange_rate.usd_value} | the_rest])
data ->
encode_market_history_data(data)
end
|> encode_market_history_data()
json(conn, %{
history_data: market_history_data,
supply_data: available_supply(Chain.supply_for_days(30), exchange_rate)
supply_data: available_supply(Chain.supply_for_days(), exchange_rate)
})
else
_ -> unprocessable_entity(conn)

@ -0,0 +1,8 @@
defmodule BlockScoutWeb.PageNotFoundController do
use BlockScoutWeb, :controller
def index(conn, _params) do
conn
|> render("index.html")
end
end

@ -13,7 +13,8 @@ defmodule BlockScoutWeb.PendingTransactionController do
[
necessity_by_association: %{
[from_address: :names] => :optional,
[to_address: :names] => :optional
[to_address: :names] => :optional,
[created_contract_address: :names] => :optional
}
],
paging_options(params)
@ -51,10 +52,7 @@ defmodule BlockScoutWeb.PendingTransactionController do
end
def index(conn, _params) do
render(conn, "index.html",
current_path: current_path(conn),
pending_transaction_count: Chain.pending_transaction_count()
)
render(conn, "index.html", current_path: current_path(conn))
end
defp get_pending_transactions_and_next_page(options) do

@ -100,6 +100,12 @@ defmodule BlockScoutWeb.Etherscan do
"result" => []
}
@account_eth_get_balance_example_value %{
"jsonrpc" => "2.0",
"result" => "0x0234c8a3397aab58",
"id" => 1
}
@account_tokentx_example_value %{
"status" => "1",
"message" => "OK",
@ -1028,6 +1034,49 @@ defmodule BlockScoutWeb.Etherscan do
}
}
@account_eth_get_balance_action %{
name: "eth_get_balance",
description:
"Mimics Ethereum JSON RPC's eth_getBalance. Returns the balance as of the provided block (defaults to latest)",
required_params: [
%{
key: "address",
placeholder: "addressHash",
type: "string",
description: "The address of the account."
}
],
optional_params: [
%{
key: "block",
placeholder: "block",
type: "string",
description: """
Either the block number as a string, or one of latest, earliest or pending
latest will be the latest balance in a *consensus* block.
earliest will be the first recorded balance for the address.
pending will be the latest balance in consensus *or* nonconcensus blocks.
"""
}
],
responses: [
%{
code: "200",
description: "successful operation",
example_value: Jason.encode!(@account_eth_get_balance_example_value),
model: %{
name: "Result",
fields: %{
jsonrpc: @jsonrpc_version_type,
id: @id_type,
result: @hex_number_type
}
}
}
]
}
@account_balance_action %{
name: "balance",
description: """
@ -2203,6 +2252,7 @@ defmodule BlockScoutWeb.Etherscan do
@account_module %{
name: "account",
actions: [
@account_eth_get_balance_action,
@account_balance_action,
@account_balancemulti_action,
@account_txlist_action,

@ -37,7 +37,7 @@ defmodule BlockScoutWeb.Notifier do
exchange_rate = Market.get_exchange_rate(Explorer.coin()) || Token.null()
market_history_data =
case Market.fetch_recent_history(30) do
case Market.fetch_recent_history() do
[today | the_rest] -> [%{today | closing_price: exchange_rate.usd_value} | the_rest]
data -> data
end

@ -32,6 +32,8 @@ defmodule BlockScoutWeb.Router do
alias BlockScoutWeb.API.RPC
post("/eth_rpc", EthController, :eth_request)
forward("/", RPCTranslator, %{
"block" => RPC.BlockController,
"account" => RPC.AddressController,
@ -245,5 +247,8 @@ defmodule BlockScoutWeb.Router do
get("/chain_blocks", ChainController, :chain_blocks, as: :chain_blocks)
get("/api_docs", APIDocsController, :index)
get("/eth_rpc_api_docs", APIDocsController, :eth_rpc)
get("/:page", PageNotFoundController, :index)
end
end

@ -39,7 +39,7 @@
</span>
<!-- percentage of coins from total supply -->
<span class="ml-0 ml-md-2">
<% if @total_supply do %>
<%= if @total_supply do %>
(<%= balance_percentage(@address, @total_supply) %>)
<% end %>
</span>

@ -80,8 +80,8 @@
</div>
<% {:ok, contract_code} -> %>
<div class="d-flex justify-content-between align-items-baseline">
<h3><%= gettext "Contract Byte Code" %></h3>
<button type="button" class="button button-secondary button-sm" id="button" data-clipboard-text="<%= contract_code %>" aria-label="copy contract creation code">
<h2 class="card-title"><%= gettext "Contract Byte Code" %></h2>
<button type="button" class="btn-line" id="button" data-clipboard-text="<%= contract_code %>" aria-label="copy contract creation code">
<%= gettext "Copy Contract Byte Code" %>
</button>
</div>

@ -2,7 +2,8 @@
<%= render BlockScoutWeb.AddressView, "overview.html", assigns %>
<div class="card">
<%= render BlockScoutWeb.AddressView, "_tabs.html", assigns %>
<%= for contract <- sort_contracts_by_version(@address.decompiled_smart_contracts) do %>
<% contract = last_decompiled_contract_version(@address.decompiled_smart_contracts) %>
<%= if contract do %>
<div class="card-body">
<h3><%= gettext "Decompiler version" %></h3>
<div class="tile tile-muted">
@ -21,6 +22,10 @@
</div>
</section>
</div>
<% else %>
<div class="tile tile-muted text-center">
<%= gettext "There is no decompilded contracts for this address." %>
</div>
<% end %>
</div>
</section>

@ -0,0 +1,34 @@
<section class="container">
<div class="card">
<div class="card-body">
<h1 class="card-title margin-bottom-sm"><%= gettext("ETH RPC API Documentation") %></h2>
<p class="api-text-monospace" data-endpoint-url="<%= BlockScoutWeb.Endpoint.url() %>/api/eth_rpc">[ <%= gettext "Base URL:" %> <%= @conn.host %>/api/eth_rpc ]</p>
<p class="card-subtitle margin-bottom-0">
<%= gettext "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found " %>
<a href="https://github.com/ethereum/wiki/wiki/JSON-RPC"><%= gettext "here." %></a>
<%= gettext "This is useful to allow sending requests to blockscout without having to change anything about the request." %>
<%= gettext "However, in general, the" %> <%= link(
gettext("custom RPC"),
to: api_docs_path(@conn, :index)
) %> <%= gettext " is recommended." %>
<%= gettext "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences." %>
</p>
</div>
</div>
<div class="card">
<div class="card-body">
<table class="table">
<tr>
<th>Supported Method</th>
<th>Notes</th>
</tr>
<%= for {method, info} <- Map.to_list(@documentation) do %>
<tr>
<td> <a href="https://github.com/ethereum/wiki/wiki/JSON-RPC#<%= method %>"> <%= method %> </a> </td>
<td> <%= Map.get(info, :notes, "N/A") %> </td>
</tr>
<% end %>
</table>
</div>
</section>

@ -57,7 +57,7 @@
<dl class="row">
<dt class="col-sm-3 text-muted"><%= gettext "Difficulty" %></dt>
<dd class="col-sm-9">
<span class="font-weight-bold"><%= @block.difficulty |> Cldr.Number.to_string! %></span>
<span><%= @block.difficulty |> Cldr.Number.to_string! %></span>
</dd>
</dl>
@ -65,13 +65,13 @@
<!-- Total Difficulty -->
<dl class="row">
<dt class="col-sm-3 text-muted"><%= gettext "Total Difficulty" %></dt>
<dd class="col-sm-9"><span class="font-weight-bold"><%= @block.total_difficulty |> Cldr.Number.to_string! %></span></dd>
<dd class="col-sm-9"><span><%= @block.total_difficulty |> Cldr.Number.to_string! %></span></dd>
</dl>
<!-- Nonce -->
<dl class="row">
<dt class="col-sm-3 text-muted"><%= gettext "Nonce" %></dt>
<dd class="col-sm-9"><span class="font-weight-bold"><%= to_string(@block.nonce) %></span></dd>
<dd class="col-sm-9"><span><%= to_string(@block.nonce) %></span></dd>
</dl>
<%= if length(@block.uncle_relations) > 0 do %>
@ -97,14 +97,14 @@
<dl class="row">
<dt class="col-sm-3 text-muted"><%= gettext "Gas Used" %></dt>
<dd class="col-sm-9">
<span class="font-weight-bold"><%= @block.gas_used |> Cldr.Number.to_string! %></span>
<span><%= @block.gas_used |> Cldr.Number.to_string! %></span>
<span class="text-muted">(<%= (Decimal.to_integer(@block.gas_used) / Decimal.to_integer(@block.gas_limit)) |> Cldr.Number.to_string!(format: "#.#%") %>)</span>
</dt>
</dl>
<dl class="row mb-0">
<dt class="col-sm-3 text-muted"><%= gettext "Gas Limit" %></dt>
<dd class="col-sm-9">
<span class="font-weight-bold"><%= Cldr.Number.to_string!(@block.gas_limit) %></span>
<span><%= Cldr.Number.to_string!(@block.gas_limit) %></span>
</dd>
</dl>
<% end %>

@ -0,0 +1,29 @@
<svg xmlns="http://www.w3.org/2000/svg" width="62" height="85">
<defs>
<filter id="questiona" width="62" height="85" x="0" y="0" filterUnits="userSpaceOnUse">
<feOffset dy="6" in="SourceAlpha"/>
<feGaussianBlur result="blurOut" stdDeviation="3.464"/>
<feFlood flood-color="#2674AF" result="floodOut"/>
<feComposite in="floodOut" in2="blurOut" operator="atop"/>
<feComponentTransfer>
<feFuncA slope=".6" type="linear"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<filter id="questionb">
<feOffset dy="-4" in="SourceAlpha"/>
<feGaussianBlur result="blurOut" stdDeviation="2.828"/>
<feFlood flood-color="#329AE9" result="floodOut"/>
<feComposite in="floodOut" in2="blurOut" operator="out" result="compOut"/>
<feComposite in="compOut" in2="SourceAlpha" operator="in"/>
<feComponentTransfer>
<feFuncA slope=".5" type="linear"/>
</feComponentTransfer>
<feBlend in2="SourceGraphic"/>
</filter>
</defs>
<path fill="#FFF" fill-rule="evenodd" d="M30.385 46.419c1.149 0 2.146-.344 2.995-1.033.847-.689 1.381-1.664 1.6-2.928.273-1.205.889-2.368 1.846-3.487.957-1.119 2.339-2.454 4.144-4.004 1.915-1.779 3.474-3.3 4.678-4.563 1.203-1.262 2.228-2.784 3.077-4.564.848-1.779 1.272-3.731 1.272-5.855 0-2.87-.794-5.438-2.38-7.707-1.587-2.267-3.774-4.046-6.565-5.338-2.79-1.292-5.963-1.937-9.518-1.937-3.174 0-6.333.531-9.478 1.593-3.147 1.062-5.95 2.54-8.412 4.434-.931.747-1.6 1.522-2.01 2.325-.41.804-.616 1.808-.616 3.013 0 1.78.479 3.287 1.436 4.521.957 1.235 2.12 1.851 3.488 1.851 1.149 0 2.653-.545 4.513-1.636l1.97-1.033c1.531-.918 2.913-1.621 4.144-2.11a10.075 10.075 0 0 1 3.734-.732c1.53 0 2.734.374 3.61 1.12.875.747 1.313 1.752 1.313 3.014 0 1.263-.315 2.41-.943 3.444-.63 1.033-1.574 2.268-2.832 3.702-1.751 1.895-3.118 3.746-4.103 5.554-.984 1.808-1.477 4.062-1.477 6.759 0 1.78.397 3.158 1.19 4.133.793.977 1.9 1.464 3.324 1.464zm.164 20.579c2.297 0 4.198-.803 5.703-2.411 1.504-1.606 2.257-3.587 2.257-5.941 0-2.353-.753-4.334-2.257-5.941-1.505-1.607-3.406-2.411-5.703-2.411-2.244 0-4.117.804-5.621 2.411-1.506 1.607-2.257 3.588-2.257 5.941 0 2.354.751 4.335 2.257 5.941 1.504 1.608 3.377 2.411 5.621 2.411z" filter="url(#questionb)"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -17,6 +17,11 @@
render BlockScoutWeb.CommonComponentsView, "_icon_warning_modal.html"
end
%>
<%=
if @status == "question" do
render BlockScoutWeb.CommonComponentsView, "_icon_question_modal.html"
end
%>
</div>
<%= render BlockScoutWeb.CommonComponentsView, "_modal_close_button.html" %>
<div class="modal-body modal-status-body">
@ -26,9 +31,20 @@
<%= if assigns[:text] do %>
<p class="modal-status-text"><%= @text %></p>
<% end %>
<button class="btn-line" type="button" data-dismiss="modal">
<span class="btn-line-text">Ok</span>
</button>
<div class="modal-status-button-wrapper">
<%= if @status !== "question" do %>
<button class="btn-line" type="button" data-dismiss="modal">
<span class="btn-line-text">Ok</span>
</button>
<% else %>
<button class="btn-line except" type="button" data-dismiss="modal">
<span class="btn-line-text">No</span>
</button>
<button class="btn-line accept" type="button" data-dismiss="modal">
<span class="btn-line-text">Yes</span>
</button>
<% end %>
</div>
</div>
</div>
</div>

@ -10,10 +10,10 @@
</div>
<% other_explorers = other_explorers() %>
<% col_size = if Enum.empty?(other_explorers), do: 3, else: 4 %>
<% col_size = if Enum.empty?(other_explorers), do: 3, else: 2 %>
<div class="row">
<div class="col-md-<%= col_size %>">
<div class="col-md-3">
<p class="footer-info-text"><%= gettext("Blockscout is a tool for inspecting and analyzing EVM based blockchains. Blockchain explorer for Ethereum Networks.") %></p>
<div class="footer-social-icons">
<a href="https://github.com/poanetwork/blockscout" rel="noreferrer" target="_blank" class="footer-social-icon" title='<%= gettext("Github") %>'>

@ -74,10 +74,15 @@
class: "dropdown-item #{tab_status("api_docs", @conn.request_path)}",
to: api_docs_path(@conn, :index)
) %>
<%= link(
gettext("Eth RPC"),
class: "dropdown-item #{tab_status("api_docs", @conn.request_path)}",
to: api_docs_path(@conn, :eth_rpc)
) %>
</div>
</li>
<li class="nav-item dropdown nav-item-networks">
<a class="nav-link topnav-nav-link dropdown-toggle active-icon js-show-network-selector" href="#">
<a class="nav-link topnav-nav-link dropdown-toggle active-icon js-show-network-selector <%= if dropdown_nets() == [], do: "disabled" %>" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="nav-link-icon">
<%= render BlockScoutWeb.IconsView, "_active_icon.html" %>
</span>

@ -4,8 +4,8 @@
<img alt="Page Not Found" src="/images/errors-img/poa-page-not-found.png" srcset="/images/errors-img/poa-page-not-found@2x.png 2x">
</div>
<div class="block-not-found-content">
<h1 class="card-title error-title">Lorem Ipsum Dolor</h1>
<p class="error-descr">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>
<h1 class="card-title error-title">Page not found</h1>
<p class="error-descr">The requested path was not found on BlockScout.</p>
<a class="error-btn btn-line" href="/">Back Home</a>
</div>
</div>

@ -19,7 +19,7 @@
<!-- Content -->
<div class="col-md-7 col-lg-8 d-flex flex-column pr-2 pr-sm-2 pr-md-0">
<%= render "_link.html", transaction_hash: @transaction.hash %>
<span class="text-nowrap">
<span>
<%= @transaction |> BlockScoutWeb.AddressView.address_partial_selector(:from, assigns[:current_address]) |> BlockScoutWeb.RenderHelpers.render_partial() %>
&rarr;
<%= @transaction |> BlockScoutWeb.AddressView.address_partial_selector(:to, assigns[:current_address]) |> BlockScoutWeb.RenderHelpers.render_partial() %>
@ -58,7 +58,7 @@
<% end %>
</div>
<!-- Block info -->
<div class="col-md-3 col-lg-2 d-flex flex-row flex-md-column flex-nowrap justify-content-center text-md-right mt-3 mt-md-0">
<div class="col-md-3 col-lg-2 d-flex flex-row flex-md-column flex-nowrap justify-content-center text-md-right mt-3 mt-md-0 tile-bottom">
<span class="mr-2 mr-md-0 order-1">
<%= @transaction |> block_number() |> BlockScoutWeb.RenderHelpers.render_partial() %>
</span>

@ -51,7 +51,7 @@
</span>
</div>
<!-- Verify in other explorers -->
<%# <%= render BlockScoutWeb.AddressView, "_verify_other_explorers.html", hash: hash(@transaction), type: "tx" %> %>
<!-- <%= render BlockScoutWeb.AddressView, "_verify_other_explorers.html", hash: hash(@transaction), type: "tx" %> -->
<hr>
<!-- Block Hash -->
<dl class="row">
@ -108,7 +108,7 @@
<dl class="row">
<dt class="col-sm-3 text-muted"><%= gettext "Raw Input" %></dt>
<dd class="col-sm-9">
<div class="d-flex mb-1 justify-content-between">
<div class="d-flex mb-3 justify-content-between">
<!-- Dropdown -->
<div class="dropdown">
<button class="btn-dropdown-line dropdown-toggle" type="button" id="tx-input-decoding-button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@ -169,39 +169,22 @@
</div>
</div>
<%= cond do %>
<% erc20_token_transfer = assigns[:token_transfers] && erc20_token_transfer(@transaction, @token_transfers) -> %>
<%= case token_transfer_type(@transaction) do %>
<% {type, token_transfer} -> %>
<div class="col-md-12 col-lg-4 d-flex flex-column flex-md-row flex-lg-column pl-0">
<!-- Value -->
<div class="card card-background-1 flex-grow-1">
<div class="card-body card-body-flex-column-space-between">
<h2 class="card-title balance-card-title"><%= gettext "ERC-20" %> <%= gettext "Token Transfer" %></h2>
<h2 class="card-title balance-card-title"><%= if type == :erc20, do: gettext("ERC-20"), else: gettext("ERC-721")%><%= gettext " Token Transfer" %></h2>
<div class="text-right">
<h3 class="address-balance-text">
<%= token_transfer_amount(erc20_token_transfer) %>
<%= link(token_symbol(erc20_token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, erc20_token_transfer.token.contract_address_hash)) %>
</h3>
</div>
</div>
</div>
<% erc721_token_transfer = assigns[:token_transfers] && erc721_token_transfer(@transaction, @token_transfers) -> %>
<div class="col-md-12 col-lg-4 d-flex flex-column flex-md-row flex-lg-column">
<!-- Value -->
<div class="card card-primary flex-grow-1">
<div class="card-body">
<h2 class="card-title text-white"><%= gettext "ERC-721" %> <%= gettext "Token Transfer" %></h2>
<div class="text-right">
<h3 class="text-white">
<span class="col-12 col-md-7 ml-3 ml-sm-0">
<%= token_transfer_amount(erc721_token_transfer) %>
<%= link(token_symbol(erc721_token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, erc721_token_transfer.token.contract_address_hash)) %>
</span>
<%= token_transfer_amount(token_transfer) %>
<%= link(token_symbol(token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, token_transfer.token.contract_address_hash)) %>
</h3>
</div>
</div>
</div>
<% true -> %>
<% _ -> %>
<div class="col-md-12 col-lg-4 d-flex flex-column flex-md-row flex-lg-column pl-0-md">
<!-- Value -->
<div class="card card-background-1 flex-grow-1">
@ -212,8 +195,8 @@
<%= value(@transaction) %>
</h3>
<%= if !empty_exchange_rate?(@exchange_rate) do %>
<p class="address-current-balance"
data-wei-value=<%= @transaction.value.value %>
<p class="address-current-balance"
data-wei-value=<%= @transaction.value.value %>
data-usd-exchange-rate=<%= @exchange_rate.usd_value %>>
</p>
<% end %>

@ -230,10 +230,8 @@ defmodule BlockScoutWeb.AddressDecompiledContractView do
end)
end
def sort_contracts_by_version(decompiled_contracts) do
decompiled_contracts
|> Enum.sort_by(& &1.decompiler_version)
|> Enum.reverse()
def last_decompiled_contract_version(decompiled_contracts) do
Enum.max_by(decompiled_contracts, & &1.decompiler_version)
end
defp add_line_numbers(code) do

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.API.RPC.AddressView do
use BlockScoutWeb, :view
alias BlockScoutWeb.API.RPC.RPCView
alias BlockScoutWeb.API.RPC.{EthRPCView, RPCView}
def render("listaccounts.json", %{accounts: accounts}) do
accounts = Enum.map(accounts, &prepare_account/1)
@ -51,6 +51,10 @@ defmodule BlockScoutWeb.API.RPC.AddressView do
RPCView.render("show.json", data: data)
end
def render("eth_get_balance_error.json", %{error: message}) do
EthRPCView.render("error.json", %{error: message, id: 0})
end
def render("error.json", assigns) do
RPCView.render("error.json", assigns)
end

@ -17,16 +17,48 @@ defmodule BlockScoutWeb.API.RPC.EthRPCView do
}
end
def render("response.json", %{response: %{error: error, id: id}}) do
%__MODULE__{
error: error,
id: id
}
end
def render("response.json", %{response: %{result: result, id: id}}) do
%__MODULE__{
result: result,
id: id
}
end
def render("responses.json", %{responses: responses}) do
Enum.map(responses, fn
%{error: error, id: id} ->
%__MODULE__{
error: error,
id: id
}
%{result: result, id: id} ->
%__MODULE__{
result: result,
id: id
}
end)
end
defimpl Poison.Encoder, for: BlockScoutWeb.API.RPC.EthRPCView do
def encode(%BlockScoutWeb.API.RPC.EthRPCView{result: result, id: id, error: error}, _options) when is_nil(error) do
result = Poison.encode!(result)
"""
{"jsonrpc":"2.0","result":"#{result}","id":#{id}}
{"jsonrpc":"2.0","result":#{result},"id":#{id}}
"""
end
def encode(%BlockScoutWeb.API.RPC.EthRPCView{id: id, error: error}, _options) do
"""
{"jsonrpc":"2.0","error": #{error},"id": #{id}}
{"jsonrpc":"2.0","error": "#{error}","id": #{id}}
"""
end
end

@ -0,0 +1,13 @@
defmodule BlockScoutWeb.API.RPC.EthView do
use BlockScoutWeb, :view
alias BlockScoutWeb.API.RPC.EthRPCView
def render("responses.json", %{responses: responses}) do
EthRPCView.render("responses.json", %{responses: responses})
end
def render("response.json", %{response: response}) do
EthRPCView.render("response.json", %{response: response})
end
end

@ -0,0 +1,5 @@
defmodule BlockScoutWeb.PageNotFoundView do
use BlockScoutWeb, :view
@dialyzer :no_match
end

@ -1,12 +1,11 @@
defmodule BlockScoutWeb.TransactionView do
use BlockScoutWeb, :view
alias ABI.TypeDecoder
alias BlockScoutWeb.{AddressView, BlockView, TabHelpers}
alias Cldr.Number
alias Explorer.Chain
alias Explorer.Chain.Block.Reward
alias Explorer.Chain.{Address, Block, InternalTransaction, TokenTransfer, Transaction, Wei}
alias Explorer.Chain.{Address, Block, InternalTransaction, Transaction, Wei}
alias Explorer.ExchangeRates.Token
alias Timex.Duration
@ -33,85 +32,10 @@ defmodule BlockScoutWeb.TransactionView do
def value_transfer?(_), do: false
def erc20_token_transfer(
%Transaction{
status: :ok,
created_contract_address_hash: nil,
input: input,
value: value
},
token_transfers
) do
zero_wei = %Wei{value: Decimal.new(0)}
case {to_string(input), value} do
{unquote(TokenTransfer.transfer_function_signature()) <> params, ^zero_wei} ->
types = [:address, {:uint, 256}]
[address, value] = decode_params(params, types)
decimal_value = Decimal.new(value)
Enum.find(token_transfers, fn token_transfer ->
token_transfer.to_address_hash.bytes == address && token_transfer.amount == decimal_value
end)
_ ->
nil
end
rescue
_ -> nil
def token_transfer_type(transaction) do
Chain.transaction_token_transfer_type(transaction)
end
def erc20_token_transfer(_, _) do
nil
end
def erc721_token_transfer(
%Transaction{
status: :ok,
created_contract_address_hash: nil,
input: input,
value: value
},
token_transfers
) do
zero_wei = %Wei{value: Decimal.new(0)}
# https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721.sol#L35
{from_address, to_address} =
case {to_string(input), value} do
# transferFrom(address,address,uint256)
{"0x23b872dd" <> params, ^zero_wei} ->
types = [:address, :address, {:uint, 256}]
[from_address, to_address, _value] = decode_params(params, types)
{from_address, to_address}
# safeTransferFrom(address,address,uint256)
{"0x42842e0e" <> params, ^zero_wei} ->
types = [:address, :address, {:uint, 256}]
[from_address, to_address, _value] = decode_params(params, types)
{from_address, to_address}
# safeTransferFrom(address,address,uint256,bytes)
{"0xb88d4fde" <> params, ^zero_wei} ->
types = [:address, :address, {:uint, 256}, :bytes]
[from_address, to_address, _value, _data] = decode_params(params, types)
{from_address, to_address}
_ ->
nil
end
Enum.find(token_transfers, fn token_transfer ->
token_transfer.from_address_hash.bytes == from_address && token_transfer.to_address_hash.bytes == to_address
end)
rescue
_ -> nil
end
def erc721_token_transfer(_, _), do: nil
def processing_time_duration(%Transaction{block: nil}) do
:pending
end
@ -339,10 +263,4 @@ defmodule BlockScoutWeb.TransactionView do
defp tab_name(["internal_transactions"]), do: gettext("Internal Transactions")
defp tab_name(["logs"]), do: gettext("Logs")
defp tab_name(["raw_trace"]), do: gettext("Raw Trace")
defp decode_params(params, types) do
params
|> Base.decode16!(case: :mixed)
|> TypeDecoder.decode_raw(types)
end
end

@ -57,13 +57,19 @@ defmodule BlockScoutWeb.WeiHelpers do
converted_value =
wei
|> Wei.to(unit)
|> Cldr.Number.to_string!(format: "#,##0.##################")
formatted_value =
if Decimal.cmp(converted_value, 1_000_000_000_000) == :gt do
Cldr.Number.to_string!(converted_value, format: "0.###E+0")
else
Cldr.Number.to_string!(converted_value, format: "#,##0.##################")
end
if Keyword.get(options, :include_unit_label, true) do
display_unit = display_unit(unit)
"#{converted_value} #{display_unit}"
"#{formatted_value} #{display_unit}"
else
converted_value
formatted_value
end
end

@ -49,7 +49,7 @@ msgid "%{subnetwork} Explorer - BlockScout"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:209
#: lib/block_scout_web/views/transaction_view.ex:133
msgid "(Awaiting internal transactions for status)"
msgstr ""
@ -112,7 +112,6 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:27
#: lib/block_scout_web/templates/address_transaction/index.html.eex:23
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:20
#: lib/block_scout_web/views/address_internal_transaction_view.ex:8
#: lib/block_scout_web/views/address_transaction_view.ex:8
msgid "All"
@ -129,6 +128,7 @@ msgid "Balance"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:5
#: lib/block_scout_web/templates/api_docs/index.html.eex:5
msgid "Base URL:"
msgstr ""
@ -166,7 +166,7 @@ msgid "Block Number"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:22
#: lib/block_scout_web/views/transaction_view.ex:21
msgid "Block Pending"
msgstr ""
@ -275,12 +275,12 @@ msgid "Contract Address Pending"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:286
#: lib/block_scout_web/views/transaction_view.ex:210
msgid "Contract Call"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:285
#: lib/block_scout_web/views/transaction_view.ex:209
msgid "Contract Creation"
msgstr ""
@ -363,12 +363,12 @@ msgid "Error trying to fetch balances."
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:213
#: lib/block_scout_web/views/transaction_view.ex:137
msgid "Error: %{reason}"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:211
#: lib/block_scout_web/views/transaction_view.ex:135
msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
@ -378,8 +378,8 @@ msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:55
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:20
#: lib/block_scout_web/templates/transaction/_tile.html.eex:30
#: lib/block_scout_web/templates/transaction/overview.html.eex:209
#: lib/block_scout_web/views/wei_helpers.ex:72
#: lib/block_scout_web/templates/transaction/overview.html.eex:192
#: lib/block_scout_web/views/wei_helpers.ex:78
msgid "Ether"
msgstr ""
@ -437,7 +437,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:20
#: lib/block_scout_web/views/wei_helpers.ex:71
#: lib/block_scout_web/views/wei_helpers.ex:77
msgid "Gwei"
msgstr ""
@ -473,7 +473,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:306
#: lib/block_scout_web/views/transaction_view.ex:339
#: lib/block_scout_web/views/transaction_view.ex:263
msgid "Internal Transactions"
msgstr ""
@ -490,7 +490,7 @@ msgid "Less than"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:237
#: lib/block_scout_web/templates/transaction/overview.html.eex:220
msgid "Limit"
msgstr ""
@ -500,7 +500,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:312
#: lib/block_scout_web/views/transaction_view.ex:340
#: lib/block_scout_web/views/transaction_view.ex:264
msgid "Logs"
msgstr ""
@ -512,7 +512,7 @@ msgid "Market Cap"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:194
#: lib/block_scout_web/views/transaction_view.ex:118
msgid "Max of"
msgstr ""
@ -602,8 +602,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:44
#: lib/block_scout_web/views/transaction_view.ex:208
#: lib/block_scout_web/views/transaction_view.ex:242
#: lib/block_scout_web/views/transaction_view.ex:132
#: lib/block_scout_web/views/transaction_view.ex:166
msgid "Pending"
msgstr ""
@ -666,8 +666,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/index.html.eex:14
#: lib/block_scout_web/templates/layout/_topnav.html.eex:97
#: lib/block_scout_web/templates/layout/_topnav.html.eex:114
#: lib/block_scout_web/templates/layout/_topnav.html.eex:116
#: lib/block_scout_web/templates/layout/_topnav.html.eex:133
msgid "Search"
msgstr ""
@ -690,7 +690,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:210
#: lib/block_scout_web/views/transaction_view.ex:134
msgid "Success"
msgstr ""
@ -794,10 +794,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:5
#: lib/block_scout_web/templates/transaction/overview.html.eex:179
#: lib/block_scout_web/templates/transaction/overview.html.eex:193
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:284
#: lib/block_scout_web/views/transaction_view.ex:208
msgid "Token Transfer"
msgstr ""
@ -807,7 +805,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:7
#: lib/block_scout_web/views/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:338
#: lib/block_scout_web/views/transaction_view.ex:262
msgid "Token Transfers"
msgstr ""
@ -847,7 +845,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:3
#: lib/block_scout_web/views/transaction_view.ex:287
#: lib/block_scout_web/views/transaction_view.ex:211
msgid "Transaction"
msgstr ""
@ -909,7 +907,7 @@ msgid "Unique Token"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:231
#: lib/block_scout_web/templates/transaction/overview.html.eex:214
msgid "Used"
msgstr ""
@ -929,7 +927,7 @@ msgid "Validations"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:209
#: lib/block_scout_web/templates/transaction/overview.html.eex:192
msgid "Value"
msgstr ""
@ -985,7 +983,7 @@ msgid "Wallet addresses"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/wei_helpers.ex:70
#: lib/block_scout_web/views/wei_helpers.ex:76
msgid "Wei"
msgstr ""
@ -1482,8 +1480,8 @@ msgid "Error: Could not determine contract creator."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:91
#: lib/block_scout_web/templates/layout/_topnav.html.eex:95
#: lib/block_scout_web/templates/layout/_topnav.html.eex:110
#: lib/block_scout_web/templates/layout/_topnav.html.eex:114
msgid "Search by address, token symbol name, transaction hash, or block number"
msgstr ""
@ -1493,7 +1491,7 @@ msgid "EVM Version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:16
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:17
msgid "Copy Decompiled Contract Code"
msgstr ""
@ -1508,12 +1506,12 @@ msgid "Decompiled code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:14
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:15
msgid "Decompiled contract code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:7
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:8
msgid "Decompiler version"
msgstr ""
@ -1523,12 +1521,12 @@ msgid "Optimization runs"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:179
#: lib/block_scout_web/templates/transaction/overview.html.eex:178
msgid "ERC-20"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:193
#: lib/block_scout_web/templates/transaction/overview.html.eex:178
msgid "ERC-721"
msgstr ""
@ -1548,14 +1546,14 @@ msgid "View All Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:227
#: lib/block_scout_web/templates/transaction/overview.html.eex:210
msgid "Gas"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24
#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:341
#: lib/block_scout_web/views/transaction_view.ex:265
msgid "Raw Trace"
msgstr ""
@ -1697,31 +1695,56 @@ msgid "New Smart Contract Verification"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:10
msgid "Change Network"
#: lib/block_scout_web/templates/transaction/overview.html.eex:178
msgid " Token Transfer"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:27
msgid "There is no decompilded contracts for this address."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:14
msgid " is recommended."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15
msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:4
msgid "ETH RPC API Documentation"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:78
msgid "Eth RPC"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23
msgid "Favorites"
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:11
msgid "However, in general, the"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:11
msgid "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore."
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:7
msgid "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found "
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:21
msgid "Mainnet"
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:10
msgid "This is useful to allow sending requests to blockscout without having to change anything about the request."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:17
msgid "Search network"
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:12
msgid "custom RPC"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:22
msgid "Testnet"
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:9
msgid "here."
msgstr ""

@ -49,7 +49,7 @@ msgid "%{subnetwork} Explorer - BlockScout"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:209
#: lib/block_scout_web/views/transaction_view.ex:133
msgid "(Awaiting internal transactions for status)"
msgstr ""
@ -112,7 +112,6 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:27
#: lib/block_scout_web/templates/address_transaction/index.html.eex:23
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:20
#: lib/block_scout_web/views/address_internal_transaction_view.ex:8
#: lib/block_scout_web/views/address_transaction_view.ex:8
msgid "All"
@ -129,6 +128,7 @@ msgid "Balance"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:5
#: lib/block_scout_web/templates/api_docs/index.html.eex:5
msgid "Base URL:"
msgstr ""
@ -166,7 +166,7 @@ msgid "Block Number"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:22
#: lib/block_scout_web/views/transaction_view.ex:21
msgid "Block Pending"
msgstr ""
@ -275,12 +275,12 @@ msgid "Contract Address Pending"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:286
#: lib/block_scout_web/views/transaction_view.ex:210
msgid "Contract Call"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:285
#: lib/block_scout_web/views/transaction_view.ex:209
msgid "Contract Creation"
msgstr ""
@ -363,12 +363,12 @@ msgid "Error trying to fetch balances."
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:213
#: lib/block_scout_web/views/transaction_view.ex:137
msgid "Error: %{reason}"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:211
#: lib/block_scout_web/views/transaction_view.ex:135
msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
@ -378,8 +378,8 @@ msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:55
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:20
#: lib/block_scout_web/templates/transaction/_tile.html.eex:30
#: lib/block_scout_web/templates/transaction/overview.html.eex:209
#: lib/block_scout_web/views/wei_helpers.ex:72
#: lib/block_scout_web/templates/transaction/overview.html.eex:192
#: lib/block_scout_web/views/wei_helpers.ex:78
msgid "Ether"
msgstr "POA"
@ -437,7 +437,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/views/block_view.ex:20
#: lib/block_scout_web/views/wei_helpers.ex:71
#: lib/block_scout_web/views/wei_helpers.ex:77
msgid "Gwei"
msgstr ""
@ -473,7 +473,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:306
#: lib/block_scout_web/views/transaction_view.ex:339
#: lib/block_scout_web/views/transaction_view.ex:263
msgid "Internal Transactions"
msgstr ""
@ -490,7 +490,7 @@ msgid "Less than"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:237
#: lib/block_scout_web/templates/transaction/overview.html.eex:220
msgid "Limit"
msgstr ""
@ -500,7 +500,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:312
#: lib/block_scout_web/views/transaction_view.ex:340
#: lib/block_scout_web/views/transaction_view.ex:264
msgid "Logs"
msgstr ""
@ -512,7 +512,7 @@ msgid "Market Cap"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:194
#: lib/block_scout_web/views/transaction_view.ex:118
msgid "Max of"
msgstr ""
@ -602,8 +602,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:44
#: lib/block_scout_web/views/transaction_view.ex:208
#: lib/block_scout_web/views/transaction_view.ex:242
#: lib/block_scout_web/views/transaction_view.ex:132
#: lib/block_scout_web/views/transaction_view.ex:166
msgid "Pending"
msgstr ""
@ -666,8 +666,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/index.html.eex:14
#: lib/block_scout_web/templates/layout/_topnav.html.eex:97
#: lib/block_scout_web/templates/layout/_topnav.html.eex:114
#: lib/block_scout_web/templates/layout/_topnav.html.eex:116
#: lib/block_scout_web/templates/layout/_topnav.html.eex:133
msgid "Search"
msgstr ""
@ -690,7 +690,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:210
#: lib/block_scout_web/views/transaction_view.ex:134
msgid "Success"
msgstr ""
@ -794,10 +794,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:5
#: lib/block_scout_web/templates/transaction/overview.html.eex:179
#: lib/block_scout_web/templates/transaction/overview.html.eex:193
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:284
#: lib/block_scout_web/views/transaction_view.ex:208
msgid "Token Transfer"
msgstr ""
@ -807,7 +805,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:7
#: lib/block_scout_web/views/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:338
#: lib/block_scout_web/views/transaction_view.ex:262
msgid "Token Transfers"
msgstr ""
@ -847,7 +845,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:3
#: lib/block_scout_web/views/transaction_view.ex:287
#: lib/block_scout_web/views/transaction_view.ex:211
msgid "Transaction"
msgstr ""
@ -909,7 +907,7 @@ msgid "Unique Token"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:231
#: lib/block_scout_web/templates/transaction/overview.html.eex:214
msgid "Used"
msgstr ""
@ -929,7 +927,7 @@ msgid "Validations"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:209
#: lib/block_scout_web/templates/transaction/overview.html.eex:192
msgid "Value"
msgstr ""
@ -985,7 +983,7 @@ msgid "Wallet addresses"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/wei_helpers.ex:70
#: lib/block_scout_web/views/wei_helpers.ex:76
msgid "Wei"
msgstr ""
@ -1482,8 +1480,8 @@ msgid "Error: Could not determine contract creator."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:91
#: lib/block_scout_web/templates/layout/_topnav.html.eex:95
#: lib/block_scout_web/templates/layout/_topnav.html.eex:110
#: lib/block_scout_web/templates/layout/_topnav.html.eex:114
msgid "Search by address, token symbol name, transaction hash, or block number"
msgstr ""
@ -1493,7 +1491,7 @@ msgid "EVM Version"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:16
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:17
msgid "Copy Decompiled Contract Code"
msgstr ""
@ -1508,12 +1506,12 @@ msgid "Decompiled code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:14
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:15
msgid "Decompiled contract code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:7
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:8
msgid "Decompiler version"
msgstr ""
@ -1523,12 +1521,12 @@ msgid "Optimization runs"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:179
#: lib/block_scout_web/templates/transaction/overview.html.eex:178
msgid "ERC-20"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:193
#: lib/block_scout_web/templates/transaction/overview.html.eex:178
msgid "ERC-721"
msgstr ""
@ -1548,14 +1546,14 @@ msgid "View All Transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:227
#: lib/block_scout_web/templates/transaction/overview.html.eex:210
msgid "Gas"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24
#: lib/block_scout_web/templates/transaction_raw_trace/index.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:341
#: lib/block_scout_web/views/transaction_view.ex:265
msgid "Raw Trace"
msgstr ""
@ -1697,36 +1695,56 @@ msgid "New Smart Contract Verification"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:10
msgid "Change Network"
#: lib/block_scout_web/templates/transaction/overview.html.eex:178
msgid " Token Transfer"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:23
msgid "Favorites"
#: lib/block_scout_web/templates/address_decompiled_contract/index.html.eex:27
msgid "There is no decompilded contracts for this address."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:11
msgid "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore."
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:14
msgid " is recommended."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:21
msgid "Mainnet"
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:15
msgid "Anything not in this list is not supported. Click on the method to be taken to the documentation for that method, and check the notes section for any potential differences."
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:17
msgid "Search network"
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:4
msgid "ETH RPC API Documentation"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:78
msgid "Eth RPC"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:11
msgid "However, in general, the"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:51
msgid "Show More Networks"
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:7
msgid "This API is provided to support some rpc methods in the exact format specified for ethereum nodes, which can be found "
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_network_selector.html.eex:22
msgid "Testnet"
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:10
msgid "This is useful to allow sending requests to blockscout without having to change anything about the request."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:12
msgid "custom RPC"
msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/api_docs/eth_rpc.html.eex:9
msgid "here."
msgstr ""

@ -43,6 +43,8 @@ defmodule BlockScoutWeb.ExchangeRateChannelTest do
describe "new_rate" do
test "subscribed user is notified", %{token: token} do
ExchangeRates.handle_info({nil, {:ok, [token]}}, %{})
Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Market.MarketHistoryCache.cache_name()})
Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Market.MarketHistoryCache.cache_name()})
topic = "exchange_rate:new_rate"
@endpoint.subscribe(topic)
@ -61,6 +63,8 @@ defmodule BlockScoutWeb.ExchangeRateChannelTest do
test "subscribed user is notified with market history", %{token: token} do
ExchangeRates.handle_info({nil, {:ok, [token]}}, %{})
Supervisor.terminate_child(Explorer.Supervisor, {ConCache, Explorer.Market.MarketHistoryCache.cache_name()})
Supervisor.restart_child(Explorer.Supervisor, {ConCache, Explorer.Market.MarketHistoryCache.cache_name()})
today = Date.utc_today()
@ -76,6 +80,8 @@ defmodule BlockScoutWeb.ExchangeRateChannelTest do
Market.bulk_insert_history(records)
Market.fetch_recent_history()
topic = "exchange_rate:new_rate"
@endpoint.subscribe(topic)

@ -0,0 +1,485 @@
defmodule BlockScoutWeb.API.RPC.EthControllerTest do
use BlockScoutWeb.ConnCase, async: false
alias Explorer.Counters.{AddressesWithBalanceCounter, AverageBlockTime}
alias Explorer.Repo
alias Indexer.Fetcher.CoinBalanceOnDemand
setup do
mocked_json_rpc_named_arguments = [
transport: EthereumJSONRPC.Mox,
transport_options: []
]
start_supervised!({Task.Supervisor, name: Indexer.TaskSupervisor})
start_supervised!(AverageBlockTime)
start_supervised!({CoinBalanceOnDemand, [mocked_json_rpc_named_arguments, [name: CoinBalanceOnDemand]]})
start_supervised!(AddressesWithBalanceCounter)
Application.put_env(:explorer, AverageBlockTime, enabled: true)
on_exit(fn ->
Application.put_env(:explorer, AverageBlockTime, enabled: false)
end)
:ok
end
defp params(api_params, params), do: Map.put(api_params, "params", params)
describe "eth_get_logs" do
setup do
%{
api_params: %{
"method" => "eth_getLogs",
"jsonrpc" => "2.0",
"id" => 0
}
}
end
test "with an invalid address", %{conn: conn, api_params: api_params} do
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [%{"address" => "badhash"}]))
|> json_response(200)
assert %{"error" => "invalid address"} = response
end
test "address with no logs", %{conn: conn, api_params: api_params} do
insert(:block)
address = insert(:address)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [%{"address" => to_string(address.hash)}]))
|> json_response(200)
assert %{"result" => []} = response
end
test "address but no logs and no toBlock provided", %{conn: conn, api_params: api_params} do
address = insert(:address)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [%{"address" => to_string(address.hash)}]))
|> json_response(200)
assert %{"result" => []} = response
end
test "with a matching address", %{conn: conn, api_params: api_params} do
address = insert(:address)
block = insert(:block, number: 0)
transaction = insert(:transaction, from_address: address) |> with_block(block)
insert(:log, address: address, transaction: transaction, data: "0x010101")
params = params(api_params, [%{"address" => to_string(address.hash)}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert %{"result" => [%{"data" => "0x010101"}]} = response
end
test "with a matching address and matching topic", %{conn: conn, api_params: api_params} do
address = insert(:address)
block = insert(:block, number: 0)
transaction = insert(:transaction, from_address: address) |> with_block(block)
insert(:log, address: address, transaction: transaction, data: "0x010101", first_topic: "0x01")
params = params(api_params, [%{"address" => to_string(address.hash), "topics" => ["0x01"]}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert %{"result" => [%{"data" => "0x010101"}]} = response
end
test "with a matching address and multiple topic matches", %{conn: conn, api_params: api_params} do
address = insert(:address)
block = insert(:block, number: 0)
transaction = insert(:transaction, from_address: address) |> with_block(block)
insert(:log, address: address, transaction: transaction, data: "0x010101", first_topic: "0x01")
insert(:log, address: address, transaction: transaction, data: "0x020202", first_topic: "0x00")
params = params(api_params, [%{"address" => to_string(address.hash), "topics" => [["0x01", "0x00"]]}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert [%{"data" => "0x010101"}, %{"data" => "0x020202"}] = Enum.sort_by(response["result"], &Map.get(&1, "data"))
end
test "with a matching address and multiple topic matches in different positions", %{
conn: conn,
api_params: api_params
} do
address = insert(:address)
block = insert(:block, number: 0)
transaction = insert(:transaction, from_address: address) |> with_block(block)
insert(:log,
address: address,
transaction: transaction,
data: "0x010101",
first_topic: "0x01",
second_topic: "0x02"
)
insert(:log, address: address, transaction: transaction, data: "0x020202", first_topic: "0x01")
params = params(api_params, [%{"address" => to_string(address.hash), "topics" => ["0x01", "0x02"]}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert [%{"data" => "0x010101"}] = response["result"]
end
test "with a matching address and multiple topic matches in different positions and multiple matches in the second position",
%{conn: conn, api_params: api_params} do
address = insert(:address)
block = insert(:block, number: 0)
transaction = insert(:transaction, from_address: address) |> with_block(block)
insert(:log,
address: address,
transaction: transaction,
data: "0x010101",
first_topic: "0x01",
second_topic: "0x02"
)
insert(:log,
address: address,
transaction: transaction,
data: "0x020202",
first_topic: "0x01",
second_topic: "0x03"
)
params = params(api_params, [%{"address" => to_string(address.hash), "topics" => ["0x01", ["0x02", "0x03"]]}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert [%{"data" => "0x010101"}, %{"data" => "0x020202"}] = Enum.sort_by(response["result"], &Map.get(&1, "data"))
end
test "with a block range filter",
%{conn: conn, api_params: api_params} do
address = insert(:address)
block1 = insert(:block, number: 0)
block2 = insert(:block, number: 1)
block3 = insert(:block, number: 2)
block4 = insert(:block, number: 3)
transaction1 = insert(:transaction, from_address: address) |> with_block(block1)
transaction2 = insert(:transaction, from_address: address) |> with_block(block2)
transaction3 = insert(:transaction, from_address: address) |> with_block(block3)
transaction4 = insert(:transaction, from_address: address) |> with_block(block4)
insert(:log, address: address, transaction: transaction1, data: "0x010101")
insert(:log, address: address, transaction: transaction2, data: "0x020202")
insert(:log, address: address, transaction: transaction3, data: "0x030303")
insert(:log, address: address, transaction: transaction4, data: "0x040404")
params = params(api_params, [%{"address" => to_string(address.hash), "fromBlock" => 1, "toBlock" => 2}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert [%{"data" => "0x020202"}, %{"data" => "0x030303"}] = Enum.sort_by(response["result"], &Map.get(&1, "data"))
end
test "with a block hash filter",
%{conn: conn, api_params: api_params} do
address = insert(:address)
block1 = insert(:block, number: 0)
block2 = insert(:block, number: 1)
block3 = insert(:block, number: 2)
transaction1 = insert(:transaction, from_address: address) |> with_block(block1)
transaction2 = insert(:transaction, from_address: address) |> with_block(block2)
transaction3 = insert(:transaction, from_address: address) |> with_block(block3)
insert(:log, address: address, transaction: transaction1, data: "0x010101")
insert(:log, address: address, transaction: transaction2, data: "0x020202")
insert(:log, address: address, transaction: transaction3, data: "0x030303")
params = params(api_params, [%{"address" => to_string(address.hash), "blockHash" => to_string(block2.hash)}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert [%{"data" => "0x020202"}] = response["result"]
end
test "with an earliest block filter",
%{conn: conn, api_params: api_params} do
address = insert(:address)
block1 = insert(:block, number: 0)
block2 = insert(:block, number: 1)
block3 = insert(:block, number: 2)
transaction1 = insert(:transaction, from_address: address) |> with_block(block1)
transaction2 = insert(:transaction, from_address: address) |> with_block(block2)
transaction3 = insert(:transaction, from_address: address) |> with_block(block3)
insert(:log, address: address, transaction: transaction1, data: "0x010101")
insert(:log, address: address, transaction: transaction2, data: "0x020202")
insert(:log, address: address, transaction: transaction3, data: "0x030303")
params =
params(api_params, [%{"address" => to_string(address.hash), "fromBlock" => "earliest", "toBlock" => "earliest"}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert [%{"data" => "0x010101"}] = response["result"]
end
test "with a pending block filter",
%{conn: conn, api_params: api_params} do
address = insert(:address)
block1 = insert(:block, number: 0)
block2 = insert(:block, number: 1)
block3 = insert(:block, number: 2)
transaction1 = insert(:transaction, from_address: address) |> with_block(block1)
transaction2 = insert(:transaction, from_address: address) |> with_block(block2)
transaction3 = insert(:transaction, from_address: address) |> with_block(block3)
insert(:log, address: address, transaction: transaction1, data: "0x010101")
insert(:log, address: address, transaction: transaction2, data: "0x020202")
insert(:log, address: address, transaction: transaction3, data: "0x030303")
changeset = Ecto.Changeset.change(block3, %{consensus: false})
Repo.update!(changeset)
params =
params(api_params, [%{"address" => to_string(address.hash), "fromBlock" => "pending", "toBlock" => "pending"}])
assert response =
conn
|> post("/api/eth_rpc", params)
|> json_response(200)
assert [%{"data" => "0x030303"}] = response["result"]
end
end
describe "eth_get_balance" do
setup do
%{
api_params: %{
"method" => "eth_getBalance",
"jsonrpc" => "2.0",
"id" => 0
}
}
end
test "with an invalid address", %{conn: conn, api_params: api_params} do
assert response =
conn
|> post("/api/eth_rpc", params(api_params, ["badHash"]))
|> json_response(200)
assert %{"error" => "Query parameter 'address' is invalid"} = response
end
test "with a valid address that has no balance", %{conn: conn, api_params: api_params} do
address = insert(:address)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash)]))
|> json_response(200)
assert %{"error" => "Balance not found"} = response
end
test "with a valid address that has a balance", %{conn: conn, api_params: api_params} do
block = insert(:block)
address = insert(:address)
insert(:fetched_balance, block_number: block.number, address_hash: address.hash, value: 1)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash)]))
|> json_response(200)
assert %{"result" => "0x1"} = response
end
test "with a valid address that has no earliest balance", %{conn: conn, api_params: api_params} do
block = insert(:block, number: 1)
address = insert(:address)
insert(:fetched_balance, block_number: block.number, address_hash: address.hash, value: 1)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash), "earliest"]))
|> json_response(200)
assert response["error"] == "Balance not found"
end
test "with a valid address that has an earliest balance", %{conn: conn, api_params: api_params} do
block = insert(:block, number: 0)
address = insert(:address)
insert(:fetched_balance, block_number: block.number, address_hash: address.hash, value: 1)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash), "earliest"]))
|> json_response(200)
assert response["result"] == "0x1"
end
test "with a valid address and no pending balance", %{conn: conn, api_params: api_params} do
block = insert(:block, number: 1, consensus: true)
address = insert(:address)
insert(:fetched_balance, block_number: block.number, address_hash: address.hash, value: 1)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash), "pending"]))
|> json_response(200)
assert response["error"] == "Balance not found"
end
test "with a valid address and a pending balance", %{conn: conn, api_params: api_params} do
block = insert(:block, number: 1, consensus: false)
address = insert(:address)
insert(:fetched_balance, block_number: block.number, address_hash: address.hash, value: 1)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash), "pending"]))
|> json_response(200)
assert response["result"] == "0x1"
end
test "with a valid address and a pending balance after a consensus block", %{conn: conn, api_params: api_params} do
insert(:block, number: 1, consensus: true)
block = insert(:block, number: 2, consensus: false)
address = insert(:address)
insert(:fetched_balance, block_number: block.number, address_hash: address.hash, value: 1)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash), "pending"]))
|> json_response(200)
assert response["result"] == "0x1"
end
test "with a block provided", %{conn: conn, api_params: api_params} do
address = insert(:address)
insert(:fetched_balance, block_number: 1, address_hash: address.hash, value: 1)
insert(:fetched_balance, block_number: 2, address_hash: address.hash, value: 2)
insert(:fetched_balance, block_number: 3, address_hash: address.hash, value: 3)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash), "2"]))
|> json_response(200)
assert response["result"] == "0x2"
end
test "with a block provided and no balance", %{conn: conn, api_params: api_params} do
address = insert(:address)
insert(:fetched_balance, block_number: 3, address_hash: address.hash, value: 3)
assert response =
conn
|> post("/api/eth_rpc", params(api_params, [to_string(address.hash), "2"]))
|> json_response(200)
assert response["error"] == "Balance not found"
end
test "with a batch of requests", %{conn: conn} do
address = insert(:address)
insert(:fetched_balance, block_number: 1, address_hash: address.hash, value: 1)
insert(:fetched_balance, block_number: 2, address_hash: address.hash, value: 2)
insert(:fetched_balance, block_number: 3, address_hash: address.hash, value: 3)
params = [
%{"id" => 0, "params" => [to_string(address.hash), "1"], "jsonrpc" => "2.0", "method" => "eth_getBalance"},
%{"id" => 1, "params" => [to_string(address.hash), "2"], "jsonrpc" => "2.0", "method" => "eth_getBalance"},
%{"id" => 2, "params" => [to_string(address.hash), "3"], "jsonrpc" => "2.0", "method" => "eth_getBalance"}
]
assert response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/eth_rpc", Jason.encode!(params))
|> json_response(200)
assert [
%{"id" => 0, "result" => "0x1"},
%{"id" => 1, "result" => "0x2"},
%{"id" => 2, "result" => "0x3"}
] = response
end
end
end

@ -2,6 +2,13 @@ defmodule BlockScoutWeb.BlockControllerTest do
use BlockScoutWeb.ConnCase
alias Explorer.Chain.Block
setup do
Supervisor.terminate_child(Explorer.Supervisor, {ConCache, :blocks})
Supervisor.restart_child(Explorer.Supervisor, {ConCache, :blocks})
:ok
end
describe "GET show/2" do
test "with block redirects to block transactions route", %{conn: conn} do
insert(:block, number: 3)

@ -9,6 +9,8 @@ defmodule BlockScoutWeb.ChainControllerTest do
alias Explorer.Counters.AddressesWithBalanceCounter
setup do
Supervisor.terminate_child(Explorer.Supervisor, {ConCache, :blocks})
Supervisor.restart_child(Explorer.Supervisor, {ConCache, :blocks})
start_supervised!(AddressesWithBalanceCounter)
AddressesWithBalanceCounter.consolidate()

@ -37,15 +37,6 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
refute hd(json_response(conn, 200)["items"]) =~ to_string(dropped_replaced.hash)
end
test "returns a count of pending transactions", %{conn: conn} do
insert(:transaction)
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index))
assert html_response(conn, 200)
assert 1 == conn.assigns.pending_transaction_count
end
test "works when there are no transactions", %{conn: conn} do
conn = get(conn, pending_transaction_path(conn, :index))

@ -10,6 +10,9 @@ defmodule BlockScoutWeb.ViewingChainTest do
alias Explorer.Counters.AddressesWithBalanceCounter
setup do
Supervisor.terminate_child(Explorer.Supervisor, {ConCache, :blocks})
Supervisor.restart_child(Explorer.Supervisor, {ConCache, :blocks})
Enum.map(401..404, &insert(:block, number: &1))
block = insert(:block, number: 405)

@ -96,15 +96,15 @@ defmodule BlockScoutWeb.AddressDecompiledContractViewTest do
end
end
describe "sort_contracts_by_version/1" do
test "sorts contracts in lexicographical order" do
describe "last_decompiled_contract_version/1" do
test "returns last version" do
contract2 = insert(:decompiled_smart_contract, decompiler_version: "v2")
contract1 = insert(:decompiled_smart_contract, decompiler_version: "v1")
contract3 = insert(:decompiled_smart_contract, decompiler_version: "v3")
result = AddressDecompiledContractView.sort_contracts_by_version([contract2, contract1, contract3])
result = AddressDecompiledContractView.last_decompiled_contract_version([contract2, contract1, contract3])
assert result == [contract3, contract2, contract1]
assert result == contract3
end
end
end

@ -47,30 +47,6 @@ defmodule BlockScoutWeb.TransactionViewTest do
end
end
describe "erc721_token_transfer/2" do
test "finds token transfer" do
from_address_hash = "0x7a30272c902563b712245696f0a81c5a0e45ddc8"
to_address_hash = "0xb544cead8b660aae9f2e37450f7be2ffbc501793"
from_address = insert(:address, hash: from_address_hash)
to_address = insert(:address, hash: to_address_hash)
block = insert(:block)
transaction =
insert(:transaction,
input:
"0x23b872dd0000000000000000000000007a30272c902563b712245696f0a81c5a0e45ddc8000000000000000000000000b544cead8b660aae9f2e37450f7be2ffbc5017930000000000000000000000000000000000000000000000000000000000000002",
value: Decimal.new(0),
created_contract_address_hash: nil
)
|> with_block(block, status: :ok)
token_transfer =
insert(:token_transfer, from_address: from_address, to_address: to_address, transaction: transaction)
assert TransactionView.erc721_token_transfer(transaction, [token_transfer]) == token_transfer
end
end
describe "processing_time_duration/2" do
test "returns :pending if the transaction has no block" do
transaction = build(:transaction, block: nil)

@ -249,6 +249,19 @@ defmodule EthereumJSONRPC do
|> fetch_blocks_by_params(&Block.ByNephew.request/1, json_rpc_named_arguments)
end
@spec fetch_net_version(json_rpc_named_arguments) :: {:ok, non_neg_integer()} | {:error, reason :: term}
def fetch_net_version(json_rpc_named_arguments) do
result =
%{id: 0, method: "net_version", params: []}
|> request()
|> json_rpc(json_rpc_named_arguments)
case result do
{:ok, bin_number} -> {:ok, String.to_integer(bin_number)}
other -> other
end
end
@doc """
Fetches block number by `t:tag/0`.

@ -319,6 +319,8 @@ defmodule EthereumJSONRPC.Block do
@spec elixir_to_transactions(elixir) :: Transactions.elixir()
def elixir_to_transactions(%{"transactions" => transactions}), do: transactions
def elixir_to_transactions(_), do: []
@doc """
Get `t:EthereumJSONRPC.Uncles.elixir/0` from `t:elixir/0`.
@ -439,8 +441,8 @@ defmodule EthereumJSONRPC.Block do
{key, quantity_to_integer(quantity)}
end
# Size may be `nil` for uncle blocks
defp entry_to_elixir({key, nil}) when key in ~w(size) do
# Size and totalDifficulty may be `nil` for uncle blocks
defp entry_to_elixir({key, nil}) when key in ~w(size totalDifficulty) do
{key, nil}
end

@ -385,22 +385,23 @@ defmodule EthereumJSONRPC.Geth.Call do
}
end
defp elixir_to_internal_transaction_params(%{
"blockNumber" => block_number,
"transactionIndex" => transaction_index,
"transactionHash" => transaction_hash,
"index" => index,
"traceAddress" => trace_address,
"type" => "call" = type,
"callType" => "staticcall" = call_type,
"from" => from_address_hash,
"to" => to_address_hash,
"input" => input,
"output" => output,
"gas" => gas,
"gasUsed" => gas_used,
"value" => 0 = value
}) do
defp elixir_to_internal_transaction_params(
%{
"blockNumber" => block_number,
"transactionIndex" => transaction_index,
"transactionHash" => transaction_hash,
"index" => index,
"traceAddress" => trace_address,
"type" => "call" = type,
"callType" => "staticcall" = call_type,
"from" => from_address_hash,
"to" => to_address_hash,
"input" => input,
"gas" => gas,
"gasUsed" => gas_used,
"value" => 0 = value
} = params
) do
%{
block_number: block_number,
transaction_index: transaction_index,
@ -414,7 +415,7 @@ defmodule EthereumJSONRPC.Geth.Call do
gas: gas,
gas_used: gas_used,
input: input,
output: output,
output: params["output"],
value: value
}
end

@ -174,6 +174,12 @@ defmodule EthereumJSONRPC.Parity.FetchedBeneficiaries do
defp get_address_type(reward_type, index) when reward_type == "external" and index == 2, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 3, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 4, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 5, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 6, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 7, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 8, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 9, do: :validator
defp get_address_type(reward_type, index) when reward_type == "external" and index == 10, do: :validator
defp get_address_type(reward_type, _index) when reward_type == "block", do: :validator
defp get_address_type(reward_type, _index) when reward_type == "uncle", do: :uncle
end

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

Loading…
Cancel
Save