Merge branch 'master' into master

pull/594/head
Mulili Nzuki 6 years ago committed by GitHub
commit 92c7ec207c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .gitignore
  2. 6
      apps/block_scout_web/assets/__tests__/lib/currency.js
  3. 2
      apps/block_scout_web/assets/__tests__/pages/chain.js
  4. 2
      apps/block_scout_web/assets/js/app.js
  5. 38
      apps/block_scout_web/assets/js/lib/currency.js
  6. 23
      apps/block_scout_web/assets/js/lib/market_history_chart.js
  7. 3
      apps/block_scout_web/assets/js/lib/stop_propagation.js
  8. 7
      apps/block_scout_web/assets/js/locale.js
  9. 2
      apps/block_scout_web/assets/js/pages/address.js
  10. 10
      apps/block_scout_web/assets/js/pages/chain.js
  11. 4
      apps/block_scout_web/assets/js/pages/transaction.js
  12. 5
      apps/block_scout_web/assets/js/router.js
  13. 4
      apps/block_scout_web/assets/js/socket.js
  14. 2
      apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex
  15. 2
      apps/block_scout_web/lib/block_scout_web/channels/block_channel.ex
  16. 1
      apps/block_scout_web/lib/block_scout_web/channels/transaction_channel.ex
  17. 5
      apps/block_scout_web/lib/block_scout_web/controllers/address_contract_verification_controller.ex
  18. 4
      apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex
  19. 4
      apps/block_scout_web/lib/block_scout_web/controllers/block_controller.ex
  20. 5
      apps/block_scout_web/lib/block_scout_web/controllers/chain_controller.ex
  21. 6
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_controller.ex
  22. 42
      apps/block_scout_web/lib/block_scout_web/exchange_rates/usd.ex
  23. 16
      apps/block_scout_web/lib/block_scout_web/router.ex
  24. 7
      apps/block_scout_web/lib/block_scout_web/templates/address/_balance_card.html.eex
  25. 2
      apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex
  26. 20
      apps/block_scout_web/lib/block_scout_web/templates/address/_token_holdings.html.eex
  27. 4
      apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex
  28. 12
      apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex
  29. 6
      apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification/new.html.eex
  30. 6
      apps/block_scout_web/lib/block_scout_web/templates/address_internal_transaction/_internal_transaction.html.eex
  31. 21
      apps/block_scout_web/lib/block_scout_web/templates/address_internal_transaction/index.html.eex
  32. 10
      apps/block_scout_web/lib/block_scout_web/templates/address_read_contract/index.html.eex
  33. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_token_balance/_tokens.html.eex
  34. 21
      apps/block_scout_web/lib/block_scout_web/templates/address_transaction/index.html.eex
  35. 2
      apps/block_scout_web/lib/block_scout_web/templates/api_docs/_action_tile.html.eex
  36. 4
      apps/block_scout_web/lib/block_scout_web/templates/block/_tile.html.eex
  37. 3
      apps/block_scout_web/lib/block_scout_web/templates/block/index.html.eex
  38. 4
      apps/block_scout_web/lib/block_scout_web/templates/block/overview.html.eex
  39. 7
      apps/block_scout_web/lib/block_scout_web/templates/block_transaction/index.html.eex
  40. 4
      apps/block_scout_web/lib/block_scout_web/templates/chain/_block.html.eex
  41. 14
      apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex
  42. 8
      apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex
  43. 9
      apps/block_scout_web/lib/block_scout_web/templates/layout/app.html.eex
  44. 15
      apps/block_scout_web/lib/block_scout_web/templates/pending_transaction/index.html.eex
  45. 4
      apps/block_scout_web/lib/block_scout_web/templates/smart_contract/_functions.html.eex
  46. 8
      apps/block_scout_web/lib/block_scout_web/templates/tokens/read_contract/index.html.eex
  47. 10
      apps/block_scout_web/lib/block_scout_web/templates/tokens/token/_token_transfer.html.eex
  48. 10
      apps/block_scout_web/lib/block_scout_web/templates/tokens/token/show.html.eex
  49. 2
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_link.html.eex
  50. 12
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex
  51. 6
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_token_transfer.html.eex
  52. 11
      apps/block_scout_web/lib/block_scout_web/templates/transaction/index.html.eex
  53. 12
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  54. 6
      apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/_internal_transaction.html.eex
  55. 15
      apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex
  56. 15
      apps/block_scout_web/lib/block_scout_web/templates/transaction_log/index.html.eex
  57. 8
      apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex
  58. 15
      apps/block_scout_web/lib/block_scout_web/templates/transaction_token_transfer/index.html.eex
  59. 28
      apps/block_scout_web/lib/block_scout_web/views/address_view.ex
  60. 15
      apps/block_scout_web/lib/block_scout_web/views/chain_view.ex
  61. 38
      apps/block_scout_web/lib/block_scout_web/views/currency_helpers.ex
  62. 35
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  63. 3
      apps/block_scout_web/mix.exs
  64. 101
      apps/block_scout_web/priv/gettext/default.pot
  65. 101
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  66. 10
      apps/block_scout_web/test/block_scout_web/controllers/address_contract_controller_test.exs
  67. 6
      apps/block_scout_web/test/block_scout_web/controllers/address_controller_test.exs
  68. 17
      apps/block_scout_web/test/block_scout_web/controllers/address_internal_transaction_controller_test.exs
  69. 6
      apps/block_scout_web/test/block_scout_web/controllers/address_read_contract_controller_test.exs
  70. 46
      apps/block_scout_web/test/block_scout_web/controllers/address_token_balance_controller_test.exs
  71. 20
      apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs
  72. 4
      apps/block_scout_web/test/block_scout_web/controllers/api_docs_controller_test.exs
  73. 16
      apps/block_scout_web/test/block_scout_web/controllers/block_controller_test.exs
  74. 16
      apps/block_scout_web/test/block_scout_web/controllers/block_transaction_controller_test.exs
  75. 42
      apps/block_scout_web/test/block_scout_web/controllers/chain_controller_test.exs
  76. 18
      apps/block_scout_web/test/block_scout_web/controllers/pending_transaction_controller_test.exs
  77. 7
      apps/block_scout_web/test/block_scout_web/controllers/smart_contract_controller_test.exs
  78. 4
      apps/block_scout_web/test/block_scout_web/controllers/tokens/read_contract_controller_test.exs
  79. 27
      apps/block_scout_web/test/block_scout_web/controllers/transaction_controller_test.exs
  80. 19
      apps/block_scout_web/test/block_scout_web/controllers/transaction_internal_transaction_controller_test.exs
  81. 20
      apps/block_scout_web/test/block_scout_web/controllers/transaction_log_controller_test.exs
  82. 20
      apps/block_scout_web/test/block_scout_web/controllers/transaction_token_transfer_controller_test.exs
  83. 48
      apps/block_scout_web/test/block_scout_web/exchange_rates/usd_test.exs
  84. 41
      apps/block_scout_web/test/block_scout_web/features/address_contract_verification_test.exs
  85. 23
      apps/block_scout_web/test/block_scout_web/features/pages/address_contract_page.ex
  86. 2
      apps/block_scout_web/test/block_scout_web/features/pages/address_page.ex
  87. 2
      apps/block_scout_web/test/block_scout_web/features/pages/block_list_page.ex
  88. 2
      apps/block_scout_web/test/block_scout_web/features/pages/block_page.ex
  89. 5
      apps/block_scout_web/test/block_scout_web/features/pages/chain_page.ex
  90. 51
      apps/block_scout_web/test/block_scout_web/features/pages/contract_verify_page.ex
  91. 2
      apps/block_scout_web/test/block_scout_web/features/pages/transaction_list_page.ex
  92. 4
      apps/block_scout_web/test/block_scout_web/features/pages/transaction_logs_page.ex
  93. 4
      apps/block_scout_web/test/block_scout_web/features/pages/transaction_page.ex
  94. 19
      apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs
  95. 21
      apps/block_scout_web/test/block_scout_web/views/address_view_test.exs
  96. 19
      apps/block_scout_web/test/block_scout_web/views/chain_view_test.exs
  97. 9
      apps/block_scout_web/test/block_scout_web/views/currency_helpers_test.exs
  98. 10
      apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs
  99. 74
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex
  100. 3
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/receipt.ex
  101. Some files were not shown because too many files have changed in this diff Show More

5
.gitignore vendored

@ -1,6 +1,7 @@
# App artifacts
/_build
/apps/*/cover
/apps/*/logs
/cover
/db
/deps
@ -15,8 +16,7 @@ erl_crash.dump
npm-debug.log
# Static artifacts
/apps/block_scout_web/assets/node_modules
/apps/explorer/node_modules
/apps/**/node_modules
# Since we are building assets from assets/,
# we ignore priv/static. You may want to comment
@ -30,7 +30,6 @@ npm-debug.log
# secrets files as long as you replace their contents by environment
# variables.
/apps/*/config/*.secret.exs
/apps/*/cover/
# Wallaby screenshots
screenshots/

@ -1,7 +1,11 @@
import { formatUsdValue } from '../../js/lib/currency'
test('formatUsdValue', () => {
expect(formatUsdValue(0.0000001)).toEqual('< $0.000001 USD')
window.localized = {
'Less than': 'Less than'
}
expect(formatUsdValue(0)).toEqual('$0.000000 USD')
expect(formatUsdValue(0.0000001)).toEqual('Less than $0.000001 USD')
expect(formatUsdValue(0.123456789)).toEqual('$0.123457 USD')
expect(formatUsdValue(0.1234)).toEqual('$0.123400 USD')
expect(formatUsdValue(1.23456789)).toEqual('$1.23 USD')

@ -40,7 +40,6 @@ test('RECEIVED_NEW_EXCHANGE_RATE', () => {
msg: {
exchangeRate: {
availableSupply: 1000000,
usdValue: 1.23,
marketCapUsd: 1230000
},
marketHistoryData: { data: 'some stuff' }
@ -50,7 +49,6 @@ test('RECEIVED_NEW_EXCHANGE_RATE', () => {
expect(output.availableSupply).toEqual(1000000)
expect(output.marketHistoryData).toEqual({ data: 'some stuff' })
expect(output.usdExchangeRate).toEqual(1.23)
expect(output.usdMarketCap).toEqual(1230000)
})

@ -21,6 +21,7 @@ import 'bootstrap'
import './locale'
import './lib/clipboard_buttons'
import './lib/currency'
import './lib/from_now'
import './lib/loading_element'
import './lib/market_history_chart'
@ -32,6 +33,7 @@ import './lib/pretty_json'
import './lib/try_api'
import './lib/token_balance_dropdown'
import './lib/token_transfers_toggle'
import './lib/stop_propagation'
import './pages/address'
import './pages/block'

@ -1,8 +1,44 @@
import $ from 'jquery'
import humps from 'humps'
import numeral from 'numeral'
import { BigNumber } from 'bignumber.js'
import socket from '../socket'
export function formatUsdValue (value) {
if (value < 0.000001) return '< $0.000001 USD'
if (value === 0) return '$0.000000 USD'
if (value < 0.000001) return `${window.localized['Less than']} $0.000001 USD`
if (value < 1) return `$${numeral(value).format('0.000000')} USD`
if (value < 100000) return `$${numeral(value).format('0,0.00')} USD`
return `$${numeral(value).format('0,0')} USD`
}
function weiToEther (wei) {
return new BigNumber(wei).dividedBy('1000000000000000000').toNumber()
}
function etherToUSD (ether, usdExchangeRate) {
return new BigNumber(ether).multipliedBy(usdExchangeRate).toNumber()
}
function formatAllUsdValues () {
$('[data-usd-value]').each((i, el) => {
el.innerHTML = formatUsdValue(el.dataset.usdValue)
})
}
formatAllUsdValues()
function tryUpdateCalculatedUsdValues (el, usdExchangeRate = el.dataset.usdExchangeRate) {
if (!el.dataset.hasOwnProperty('weiValue')) return
const ether = weiToEther(el.dataset.weiValue)
const usd = etherToUSD(ether, usdExchangeRate)
const formattedUsd = formatUsdValue(usd)
if (formattedUsd !== el.innerHTML) el.innerHTML = formattedUsd
}
function updateAllCalculatedUsdValues (usdExchangeRate) {
$('[data-usd-exchange-rate]').each((i, el) => tryUpdateCalculatedUsdValues(el, usdExchangeRate))
}
updateAllCalculatedUsdValues()
export const exchangeRateChannel = socket.channel(`exchange_rate:new_rate`)
exchangeRateChannel.join()
exchangeRateChannel.on('new_rate', (msg) => updateAllCalculatedUsdValues(humps.camelizeKeys(msg).exchangeRate.usdValue))

@ -1,6 +1,7 @@
import Chart from 'chart.js'
import humps from 'humps'
import numeral from 'numeral'
import { formatUsdValue } from '../lib/currency'
import sassVariables from '../../css/app.scss'
const config = {
@ -33,7 +34,7 @@ const config = {
},
ticks: {
beginAtZero: true,
callback: (value, index, values) => formatPrice(value),
callback: (value, index, values) => `$${numeral(value).format('0,0.00')}`,
maxTicksLimit: 4
}
}, {
@ -56,10 +57,10 @@ const config = {
callbacks: {
label: ({datasetIndex, yLabel}, {datasets}) => {
const label = datasets[datasetIndex].label
if (datasets[datasetIndex].label === 'Price') {
return `${label}: ${formatPrice(yLabel)}`
} else if (datasets[datasetIndex].label === 'Market Cap') {
return `${label}: ${formatMarketCap(yLabel)}`
if (datasets[datasetIndex].yAxisID === 'price') {
return `${label}: ${formatUsdValue(yLabel)}`
} else if (datasets[datasetIndex].yAxisID === 'marketCap') {
return `${label}: ${formatUsdValue(yLabel)}`
} else {
return yLabel
}
@ -69,14 +70,6 @@ const config = {
}
}
function formatPrice (price) {
return `$${numeral(price).format('0,0.00[0000000000000000]')}`
}
function formatMarketCap (marketCap) {
return numeral(marketCap).format('($0,0a)')
}
function getPriceData (marketHistoryData) {
return marketHistoryData.map(({ date, closingPrice }) => ({x: date, y: closingPrice}))
}
@ -88,7 +81,7 @@ function getMarketCapData (marketHistoryData, availableSupply) {
class MarketHistoryChart {
constructor (el, availableSupply, marketHistoryData) {
this.price = {
label: 'Price',
label: window.localized['Price'],
yAxisID: 'price',
data: getPriceData(marketHistoryData),
fill: false,
@ -98,7 +91,7 @@ class MarketHistoryChart {
lineTension: 0
}
this.marketCap = {
label: 'Market Cap',
label: window.localized['Market Cap'],
yAxisID: 'marketCap',
data: getMarketCapData(marketHistoryData, availableSupply),
fill: false,

@ -0,0 +1,3 @@
import $ from 'jquery'
$('[data-selector="stop-propagation"]').click((event) => event.stopPropagation())

@ -1,7 +1,8 @@
import moment from 'moment'
import numeral from 'numeral'
import 'numeral/locales'
import router from './router'
moment.locale(router.locale)
numeral.locale(router.locale)
export const locale = 'en'
moment.locale(locale)
numeral.locale(locale)

@ -72,7 +72,7 @@ export function reducer (state = initialState, action) {
}
}
router.when('/addresses/:addressHash').then((params) => initRedux(reducer, {
router.when('/address/:addressHash').then((params) => initRedux(reducer, {
main (store) {
const { addressHash, blockNumber } = params
const channel = socket.channel(`addresses:${addressHash}`, {})

@ -4,7 +4,7 @@ import numeral from 'numeral'
import router from '../router'
import socket from '../socket'
import { updateAllAges } from '../lib/from_now'
import { formatUsdValue } from '../lib/currency'
import { exchangeRateChannel, formatUsdValue } from '../lib/currency'
import { batchChannel, initRedux } from '../utils'
import { createMarketHistoryChart } from '../lib/market_history_chart'
@ -19,7 +19,6 @@ export const initialState = {
newBlock: null,
newTransactions: [],
transactionCount: null,
usdExchangeRate: null,
usdMarketCap: null
}
@ -45,7 +44,6 @@ export function reducer (state = initialState, action) {
return Object.assign({}, state, {
availableSupply: action.msg.exchangeRate.availableSupply,
marketHistoryData: action.msg.marketHistoryData,
usdExchangeRate: action.msg.exchangeRate.usdValue,
usdMarketCap: action.msg.exchangeRate.marketCapUsd
})
}
@ -85,8 +83,6 @@ router.when('', { exactPathMatch: true }).then(() => initRedux(reducer, {
blocksChannel.join()
blocksChannel.on('new_block', msg => store.dispatch({ type: 'RECEIVED_NEW_BLOCK', msg: humps.camelizeKeys(msg) }))
const exchangeRateChannel = socket.channel(`exchange_rate:new_rate`)
exchangeRateChannel.join()
exchangeRateChannel.on('new_rate', (msg) => store.dispatch({ type: 'RECEIVED_NEW_EXCHANGE_RATE', msg: humps.camelizeKeys(msg) }))
const transactionsChannel = socket.channel(`transactions:new_transaction`)
@ -103,7 +99,6 @@ router.when('', { exactPathMatch: true }).then(() => initRedux(reducer, {
const $blockList = $('[data-selector="chain-block-list"]')
const $channelBatching = $('[data-selector="channel-batching-message"]')
const $channelBatchingCount = $('[data-selector="channel-batching-count"]')
const $exchangeRate = $('[data-selector="exchange-rate"]')
const $marketCap = $('[data-selector="market-cap"]')
const $transactionsList = $('[data-selector="transactions-list"]')
const $transactionCount = $('[data-selector="transaction-count"]')
@ -114,9 +109,6 @@ router.when('', { exactPathMatch: true }).then(() => initRedux(reducer, {
if (oldState.averageBlockTime !== state.averageBlockTime) {
$averageBlockTime.empty().append(state.averageBlockTime)
}
if (oldState.usdExchangeRate !== state.usdExchangeRate) {
$exchangeRate.empty().append(formatUsdValue(state.usdExchangeRate))
}
if (oldState.usdMarketCap !== state.usdMarketCap) {
$marketCap.empty().append(formatUsdValue(state.usdMarketCap))
}

@ -65,7 +65,7 @@ export function reducer (state = initialState, action) {
}
}
router.when('/transactions/:transactionHash').then(() => initRedux(reducer, {
router.when('/tx/:transactionHash').then(() => initRedux(reducer, {
main (store) {
const blocksChannel = socket.channel(`blocks:new_block`, {})
const $transactionBlockNumber = $('[data-selector="block-number"]')
@ -85,7 +85,7 @@ router.when('/transactions/:transactionHash').then(() => initRedux(reducer, {
}
}))
router.when('/transactions', { exactPathMatch: true }).then((params) => initRedux(reducer, {
router.when('/txs', { exactPathMatch: true }).then((params) => initRedux(reducer, {
main (store) {
const { index } = params
const transactionsChannel = socket.channel(`transactions:new_transaction`)

@ -2,13 +2,10 @@ import Path from 'path-parser'
import URI from 'urijs'
import humps from 'humps'
const { locale } = Path.createPath('/:locale').partialTest(window.location.pathname) || { locale: 'en' }
export default {
locale,
when (pattern, { exactPathMatch } = { exactPathMatch: false }) {
return new Promise((resolve) => {
const path = Path.createPath(`/:locale${pattern}`)
const path = Path.createPath(pattern || '/')
const match = exactPathMatch ? path.test(window.location.pathname) : path.partialTest(window.location.pathname)
if (match) {
const routeParams = humps.camelizeKeys(match)

@ -1,7 +1,7 @@
import {Socket} from 'phoenix'
import router from './router'
import {locale} from './locale'
const socket = new Socket('/socket', {params: {locale: router.locale}})
const socket = new Socket('/socket', {params: {locale: locale}})
socket.connect()
export default socket

@ -24,7 +24,6 @@ defmodule BlockScoutWeb.AddressChannel do
View.render_to_string(
AddressView,
"_balance_card.html",
locale: socket.assigns.locale,
address: address,
exchange_rate: exchange_rate
)
@ -48,7 +47,6 @@ defmodule BlockScoutWeb.AddressChannel do
View.render_to_string(
AddressTransactionView,
"_transaction.html",
locale: socket.assigns.locale,
address: address,
transaction: transaction
)

@ -20,7 +20,6 @@ defmodule BlockScoutWeb.BlockChannel do
View.render_to_string(
BlockView,
"_tile.html",
locale: socket.assigns.locale,
block: block
)
@ -28,7 +27,6 @@ defmodule BlockScoutWeb.BlockChannel do
View.render_to_string(
ChainView,
"_block.html",
locale: socket.assigns.locale,
block: block
)

@ -20,7 +20,6 @@ defmodule BlockScoutWeb.TransactionChannel do
View.render_to_string(
TransactionView,
"_tile.html",
locale: socket.assigns.locale,
transaction: transaction
)

@ -18,12 +18,11 @@ defmodule BlockScoutWeb.AddressContractVerificationController do
def create(conn, %{
"address_id" => address_hash_string,
"smart_contract" => smart_contract,
"locale" => locale
"smart_contract" => smart_contract
}) do
case Publisher.publish(address_hash_string, smart_contract) do
{:ok, _smart_contract} ->
redirect(conn, to: address_contract_path(conn, :index, locale, address_hash_string))
redirect(conn, to: address_contract_path(conn, :index, address_hash_string))
{:error, changeset} ->
{:ok, compiler_versions} = CompilerVersion.fetch_versions()

@ -4,8 +4,8 @@ defmodule BlockScoutWeb.AddressController do
alias Explorer.Chain
alias Explorer.Chain.Address
def show(conn, %{"id" => id, "locale" => locale}) do
redirect(conn, to: address_transaction_path(conn, :index, locale, id))
def show(conn, %{"id" => id}) do
redirect(conn, to: address_transaction_path(conn, :index, id))
end
def transaction_count(%Address{} = address) do

@ -23,7 +23,7 @@ defmodule BlockScoutWeb.BlockController do
render(conn, "index.html", blocks: blocks, next_page_params: next_page_params(next_page, blocks, params))
end
def show(conn, %{"id" => number, "locale" => locale}) do
redirect(conn, to: block_transaction_path(conn, :index, locale, number))
def show(conn, %{"id" => number}) do
redirect(conn, to: block_transaction_path(conn, :index, number))
end
end

@ -61,11 +61,11 @@ defmodule BlockScoutWeb.ChainController do
end
defp redirect_search_results(conn, %Address{} = item) do
redirect(conn, to: address_path(conn, :show, Gettext.get_locale(), item))
redirect(conn, to: address_path(conn, :show, item))
end
defp redirect_search_results(conn, %Block{} = item) do
redirect(conn, to: block_path(conn, :show, Gettext.get_locale(), item))
redirect(conn, to: block_path(conn, :show, item))
end
defp redirect_search_results(conn, %Transaction{} = item) do
@ -75,7 +75,6 @@ defmodule BlockScoutWeb.ChainController do
transaction_path(
conn,
:show,
Gettext.get_locale(),
item
)
)

@ -33,13 +33,13 @@ defmodule BlockScoutWeb.TransactionController do
)
end
def show(conn, %{"id" => id, "locale" => locale}) do
def show(conn, %{"id" => id}) do
{:ok, transaction_hash} = Chain.string_to_transaction_hash(id)
if Chain.transaction_has_token_transfers?(transaction_hash) do
redirect(conn, to: transaction_token_transfer_path(conn, :index, locale, id))
redirect(conn, to: transaction_token_transfer_path(conn, :index, id))
else
redirect(conn, to: transaction_internal_transaction_path(conn, :index, locale, id))
redirect(conn, to: transaction_internal_transaction_path(conn, :index, id))
end
end
end

@ -1,42 +0,0 @@
defmodule BlockScoutWeb.ExchangeRates.USD do
@moduledoc """
Struct and associated conversion functions for USD currency
"""
@typedoc """
Represents USD currency
* `:value` - value in USD
"""
@type t :: %__MODULE__{
value: Decimal.t() | nil
}
defstruct ~w(value)a
alias Explorer.Chain.Wei
alias Explorer.ExchangeRates.Token
def from(nil), do: null()
def from(%Decimal{} = usd_decimal) do
%__MODULE__{value: usd_decimal}
end
def from(nil, _), do: null()
def from(_, nil), do: null()
def from(%Wei{value: nil}, _), do: null()
def from(_, %Token{usd_value: nil}), do: null()
def from(%Wei{} = wei, %Token{usd_value: exchange_rate}) do
ether = Wei.to(wei, :ether)
%__MODULE__{value: Decimal.mult(ether, exchange_rate)}
end
def null do
%__MODULE__{value: nil}
end
end

@ -13,10 +13,6 @@ defmodule BlockScoutWeb.Router do
plug(:accepts, ["json"])
end
pipeline :set_locale do
plug(SetLocale, gettext: BlockScoutWeb.Gettext, default_locale: "en")
end
scope "/api/v1", BlockScoutWeb.API.V1, as: :api_v1 do
pipe_through(:api)
@ -39,13 +35,7 @@ defmodule BlockScoutWeb.Router do
scope "/", BlockScoutWeb do
pipe_through(:browser)
pipe_through(:set_locale)
resources("/", ChainController, only: [:show], singleton: true, as: :chain)
end
scope "/:locale", BlockScoutWeb do
pipe_through(:browser)
pipe_through(:set_locale)
resources("/", ChainController, only: [:show], singleton: true, as: :chain)
resources "/blocks", BlockController, only: [:index, :show] do
@ -54,7 +44,9 @@ defmodule BlockScoutWeb.Router do
resources("/pending_transactions", PendingTransactionController, only: [:index])
resources "/transactions", TransactionController, only: [:index, :show] do
get("/txs", TransactionController, :index)
resources "/tx", TransactionController, only: [:show] do
resources(
"/internal_transactions",
TransactionInternalTransactionController,
@ -67,7 +59,7 @@ defmodule BlockScoutWeb.Router do
resources("/token_transfers", TransactionTokenTransferController, only: [:index], as: :token_transfer)
end
resources "/addresses", AddressController, only: [:show] do
resources "/address", AddressController, only: [:show] do
resources("/transactions", AddressTransactionController, only: [:index], as: :transaction)
resources(

@ -4,9 +4,12 @@
<span></span>
<div class="text-right">
<h3 class="text-white" data-test="address_balance"><%= balance(@address) %></h3>
<span class="text-light"><%= formatted_usd(@address, @exchange_rate) %></span>
<span class="text-light"
data-wei-value="<%= if @address.fetched_coin_balance, do: @address.fetched_coin_balance.value %>"
data-usd-exchange-rate="<%= @exchange_rate.usd_value %>">
</span>
<div class="mt-3" data-token-balance-dropdown data-api_path=<%= address_token_balance_path(@conn, :index, :en, @address.hash) %> >
<div class="mt-3" data-token-balance-dropdown data-api_path="<%= address_token_balance_path(@conn, :index, @address.hash) %>">
<p data-loading class="mb-0 text-light" style="display: none;">
<i class="fa fa-spinner fa-spin"></i>
<%= gettext("Fetching tokens...") %>

@ -1,5 +1,5 @@
<%= if @address_hash do %>
<%= link to: address_path(BlockScoutWeb.Endpoint, :show, @locale, @address_hash), "data-test": "address_hash_link" do %>
<%= link to: address_path(BlockScoutWeb.Endpoint, :show, @address_hash), "data-test": "address_hash_link" do %>
<%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: @address_hash, contract: @contract, truncate: assigns[:truncate] %>
<% end %>
<% end %>

@ -1,20 +0,0 @@
<div class="card">
<div class="card-body">
<h2 class="card-title"><%= gettext "Token Holdings" %></h2>
<!-- Dropdown -->
<div data-token-balance-dropdown
data-api_path=<%= address_token_balance_path(@conn, :index, :en, @address.hash) %>
class="icon-links ml-3 mb-3"
>
<p data-loading class="mb-0" stytle="display: none">
<i class="fa fa-spinner fa-spin"></i>
<%= gettext("Fetching tokens...") %>
</p>
<p data-error-message class="mb-0" style="display: none">
<%= gettext("Error tryng to fetch balances.") %>
</p>
</div>
</div>
</div>

@ -28,7 +28,6 @@
to: address_path(
BlockScoutWeb.Endpoint,
:show,
@locale,
@address.contracts_creation_internal_transaction.from_address_hash
)
) %>
@ -40,7 +39,6 @@
to: transaction_path(
BlockScoutWeb.Endpoint,
:show,
@locale,
@address.contracts_creation_internal_transaction.transaction_hash
),
"data-test": "transaction_hash_link"
@ -51,7 +49,7 @@
</div>
</div>
</div>
<div class="card-section col-md-6 col-lg-4" data-selector="balance-card">
<div class="card-section col-md-12 col-lg-4" data-selector="balance-card">
<%= render BlockScoutWeb.AddressView, "_balance_card.html", conn: @conn, address: @address, exchange_rate: @exchange_rate %>
</div>

@ -9,7 +9,7 @@
<%= link(
gettext("Transactions"),
class: "nav-link",
to: address_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
</li>
<li class="nav-item">
@ -17,12 +17,12 @@
gettext("Internal Transactions"),
class: "nav-link",
"data-test": "internal_transactions_tab_link",
to: address_internal_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_internal_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
</li>
<li class="nav-item">
<%= link(
to: address_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_contract_path(@conn, :index, @conn.params["address_id"]),
class: "nav-link active") do %>
<%= gettext("Code") %>
@ -35,7 +35,7 @@
<li class="nav-item">
<%= link(
gettext("Read Contract"),
to: address_read_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_read_contract_path(@conn, :index, @conn.params["address_id"]),
class: "nav-link")%>
</li>
<% end %>
@ -46,7 +46,9 @@
<%= if !smart_contract_verified?(@address) do %>
<%= link(
gettext("Verify and Publish"),
to: address_verify_contract_path(@conn, :new, @conn.assigns.locale, @conn.params["address_id"]), class: "button button--primary button--sm float-right ml-3"
to: address_verify_contract_path(@conn, :new, @conn.params["address_id"]),
class: "button button--primary button--sm float-right ml-3",
"data-test": "verify_and_publish"
) %>
<% end %>

@ -5,7 +5,7 @@
<h1 class="card-title">New Smart Contract</h1>
<%= form_for @changeset,
address_verify_contract_path(@conn, :create, @conn.assigns.locale, @conn.params["address_id"]),
address_verify_contract_path(@conn, :create, @conn.params["address_id"]),
fn f -> %>
<div class="form-group">
@ -16,7 +16,7 @@
<div class="form-group">
<%= label f, :name, "Contract Name" %>
<%= text_input f, :name, class: "form-control", "aria-describedby": "contract-name-help-block" %>
<%= text_input f, :name, class: "form-control", "aria-describedby": "contract-name-help-block", "data-test": "contract_name" %>
<%= error_tag f, :name, id: "contract-name-help-block", class: "text-danger" %>
</div>
@ -60,7 +60,7 @@
<%= reset "Reset", class: "button button--secondary button--sm mr-2" %>
<%= link(
"Cancel",
to: address_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_contract_path(@conn, :index, @conn.params["address_id"]),
class: "button button--sm") %>
<% end %>
</div>

@ -4,18 +4,18 @@
<%= gettext("Internal Transaction") %>
</div>
<div class="col-md-8 col-lg-8 d-flex flex-column text-nowrap pr-2 pr-sm-2 pr-md-0">
<%= render BlockScoutWeb.TransactionView, "_link.html", locale: @locale, transaction_hash: @internal_transaction.transaction_hash %>
<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: @internal_transaction.transaction_hash %>
<span class="text-nowrap">
<%= if @address.hash == @internal_transaction.from_address_hash do %>
<%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: @internal_transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.from_address) %>
<% else %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @internal_transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.from_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @internal_transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.from_address) %>
<% end %>
&rarr;
<%= if @address.hash == BlockScoutWeb.InternalTransactionView.to_address_hash(@internal_transaction) do %>
<%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: BlockScoutWeb.InternalTransactionView.to_address_hash(@internal_transaction), contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.to_address) %>
<% else %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: BlockScoutWeb.InternalTransactionView.to_address_hash(@internal_transaction), contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.to_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: BlockScoutWeb.InternalTransactionView.to_address_hash(@internal_transaction), contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.to_address) %>
<% end %>
</span>
<span class="tile-title text-truncate mt-3 mt-md-0">

@ -12,7 +12,7 @@
<%= link(
gettext("Transactions"),
class: "nav-link",
to: address_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
</li>
<li class="nav-item">
@ -20,13 +20,13 @@
gettext("Internal Transactions"),
class: "nav-link active",
"data-test": "internal_transactions_tab_link",
to: address_internal_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_internal_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
</li>
<%= if contract?(@address) do %>
<li class="nav-item">
<%= link(
to: address_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_contract_path(@conn, :index, @conn.params["address_id"]),
class: "nav-link") do %>
<%= gettext("Code") %>
@ -40,7 +40,7 @@
<li class="nav-item">
<%= link(
gettext("Read Contract"),
to: address_read_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_read_contract_path(@conn, :index, @conn.params["address_id"]),
class: "nav-link")%>
</li>
<% end %>
@ -54,17 +54,17 @@
<%= link(
gettext("Transactions"),
class: "dropdown-item",
to: address_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
<%= link(
gettext("Internal Transactions"),
class: "dropdown-item",
"data-test": "internal_transactions_tab_link",
to: address_internal_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_internal_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
<%= if contract?(@address) do %>
<%= link(
to: address_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_contract_path(@conn, :index, @conn.params["address_id"]),
class: "dropdown-item") do %>
<%= gettext("Code") %>
@ -86,7 +86,7 @@
<div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2">
<%= link(
gettext("All"),
to: address_internal_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_internal_transaction_path(@conn, :index, @conn.params["address_id"]),
class: "address__link address__link--active dropdown-item",
"data-test": "filter_option"
) %>
@ -95,7 +95,6 @@
to: address_internal_transaction_path(
@conn,
:index,
@conn.assigns.locale,
@conn.params["address_id"],
filter: "to"
),
@ -107,7 +106,6 @@
to: address_internal_transaction_path(
@conn,
:index,
@conn.assigns.locale,
@conn.params["address_id"],
filter: "from"
),
@ -119,7 +117,7 @@
<h2 class="card-title"><%= gettext "Internal Transactions" %></h2>
<%= if Enum.count(@internal_transactions) > 0 do %>
<%= for internal_transaction <- @internal_transactions do %>
<%= render "_internal_transaction.html", locale: @locale, address: @address, internal_transaction: internal_transaction %>
<%= render "_internal_transaction.html", address: @address, internal_transaction: internal_transaction %>
<% end %>
<% else %>
<div class="tile tile-muted text-center">
@ -134,7 +132,6 @@
to: address_internal_transaction_path(
@conn,
:index,
@conn.assigns.locale,
@address,
@next_page_params
)

@ -9,7 +9,7 @@
<%= link(
gettext("Transactions"),
class: "nav-link",
to: address_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
</li>
<li class="nav-item">
@ -17,12 +17,12 @@
gettext("Internal Transactions"),
class: "nav-link",
"data-test": "internal_transactions_tab_link",
to: address_internal_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_internal_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
</li>
<li class="nav-item">
<%= link(
to: address_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_contract_path(@conn, :index, @conn.params["address_id"]),
class: "nav-link") do %>
<%= gettext("Code") %>
@ -34,14 +34,14 @@
<li class="nav-item">
<%= link(
gettext("Read Contract"),
to: address_read_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_read_contract_path(@conn, :index, @conn.params["address_id"]),
class: "nav-link active")%>
</li>
</ul>
</div>
<!-- loaded via AJAX -->
<div class="card-body" data-smart-contract-functions data-hash="<%= to_string(@address.hash) %>" data-url="<%= smart_contract_path(@conn, :index, :en) %>">
<div class="card-body" data-smart-contract-functions data-hash="<%= to_string(@address.hash) %>" data-url="<%= smart_contract_path(@conn, :index) %>">
<i class="fa fa-spinner fa-spin"></i> <%= gettext("loading...") %>
</div>
</div>

@ -4,7 +4,7 @@
<%= for token_balance <- sort_by_name(@token_balances) do %>
<div class="border-bottom">
<%= link(
to: token_path(@conn, :show, :en, token_balance.token.contract_address_hash),
to: token_path(@conn, :show, token_balance.token.contract_address_hash),
class: "dropdown-item"
) do %>
<p class="mb-0"><%= token_name(token_balance.token) %></p>

@ -12,7 +12,7 @@
<%= link(
gettext("Transactions"),
class: "nav-link active",
to: address_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
</li>
<li class="nav-item">
@ -20,13 +20,13 @@
gettext("Internal Transactions"),
class: "nav-link",
"data-test": "internal_transactions_tab_link",
to: address_internal_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_internal_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
</li>
<%= if contract?(@address) do %>
<li class="nav-item">
<%= link(
to: address_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_contract_path(@conn, :index, @conn.params["address_id"]),
class: "nav-link") do %>
<%= gettext("Code") %>
@ -40,7 +40,7 @@
<li class="nav-item">
<%= link(
gettext("Read Contract"),
to: address_read_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_read_contract_path(@conn, :index, @conn.params["address_id"]),
class: "nav-link")%>
</li>
<% end %>
@ -54,17 +54,17 @@
<%= link(
gettext("Transactions"),
class: "dropdown-item",
to: address_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
<%= link(
gettext("Internal Transactions"),
class: "dropdown-item",
"data-test": "internal_transactions_tab_link",
to: address_internal_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"])
to: address_internal_transaction_path(@conn, :index, @conn.params["address_id"])
) %>
<%= if contract?(@address) do %>
<%= link(
to: address_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_contract_path(@conn, :index, @conn.params["address_id"]),
class: "dropdown-item") do %>
<%= gettext("Code") %>
@ -97,7 +97,7 @@
<div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2">
<%= link(
gettext("All"),
to: address_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["address_id"]),
to: address_transaction_path(@conn, :index, @conn.params["address_id"]),
class: "address__link address__link--active dropdown-item",
"data-test": "filter_option"
) %>
@ -106,7 +106,6 @@
to: address_transaction_path(
@conn,
:index,
@conn.assigns.locale,
@conn.params["address_id"],
filter: "to"
),
@ -118,7 +117,6 @@
to: address_transaction_path(
@conn,
:index,
@conn.assigns.locale,
@conn.params["address_id"],
filter: "from"
),
@ -131,7 +129,7 @@
<h2 class="card-title"><%= gettext "Transactions" %></h2>
<span data-selector="transactions-list">
<%= for transaction <- @transactions do %>
<%= render(BlockScoutWeb.TransactionView, "_tile.html", locale: @locale, current_address: @address, transaction: transaction) %>
<%= render(BlockScoutWeb.TransactionView, "_tile.html", current_address: @address, transaction: transaction) %>
<% end %>
</span>
<% else %>
@ -147,7 +145,6 @@
to: address_transaction_path(
@conn,
:index,
@conn.assigns.locale,
@address,
@next_page_params
)

@ -7,7 +7,7 @@
<span class="badge badge-primary tile-badge float-right mr-1"><%= gettext "GET" %></span>
<strong class="tile-label"><%= @action.name %></strong>
</h3>
<h4 class="text-dark"><%= raw @action.description %></h4>
<h4 class="text-dark"><span data-selector="stop-propagation"><%= raw @action.description %></span></h4>
<code><%= raw query_params(@module_name, @action) %></code>
</button>
</div>

@ -5,7 +5,7 @@
<%= link(
@block,
class: "tile-title",
to: block_path(BlockScoutWeb.Endpoint, :show, @locale, @block),
to: block_path(BlockScoutWeb.Endpoint, :show, @block),
"data-test": "block_number",
"data-block-number": to_string(@block.number)
) %>
@ -23,7 +23,7 @@
<!-- validator -->
<%= gettext "Miner" %>
<span class="ml-2">
<%= link to: address_path(BlockScoutWeb.Endpoint, :show, @locale, @block.miner_hash) do %>
<%= link to: address_path(BlockScoutWeb.Endpoint, :show, @block.miner_hash) do %>
<%= @block.miner_hash %>
<% end %>
</span>

@ -6,7 +6,7 @@
<span data-selector="blocks-list">
<%= for block <- @blocks do %>
<%= render BlockScoutWeb.BlockView, "_tile.html", locale: @locale, block: block %>
<%= render BlockScoutWeb.BlockView, "_tile.html", block: block %>
<% end %>
</span>
@ -17,7 +17,6 @@
to: block_path(
@conn,
:index,
@conn.assigns.locale,
@next_page_params
)
) %>

@ -35,7 +35,7 @@
<%= link(
@block.parent_hash,
class: "block__link",
to: block_path(@conn, :show, @conn.assigns.locale, @block.number - 1)
to: block_path(@conn, :show, @block.number - 1)
) %>
</dd>
</dl>
@ -71,7 +71,7 @@
<div class="text-right">
<!-- Validator's Name -->
<!-- Until we can get the validator's name we are using the Validator's address hash -->
<h3 class="text-white text-truncate"> <%= link @block.miner, class: "text-white", to: address_path(BlockScoutWeb.Endpoint, :show, @locale, @block.miner) %> </h3>
<h3 class="text-white text-truncate"> <%= link @block.miner, class: "text-white", to: address_path(BlockScoutWeb.Endpoint, :show, @block.miner) %> </h3>
<!-- Validator's address hash -->
<span class="text-light text-truncate"> </span>
</div>

@ -12,7 +12,7 @@
<%= link(
gettext("Transactions"),
class: "nav-link active",
to: block_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["block_id"])
to: block_transaction_path(@conn, :index, @conn.params["block_id"])
) %>
</li>
</ul>
@ -25,7 +25,7 @@
<%= link(
gettext("Transactions"),
class: "dropdown-item",
to: block_transaction_path(@conn, :index, @conn.assigns.locale, @conn.params["block_id"])
to: block_transaction_path(@conn, :index, @conn.params["block_id"])
) %>
</div>
</li>
@ -36,7 +36,7 @@
<h2 class="card-title"><%= gettext "Transactions" %></h2>
<span data-selector="transactions-list">
<%= for transaction <- @transactions do %>
<%= render BlockScoutWeb.TransactionView, "_tile.html", locale: @locale, transaction: transaction %>
<%= render BlockScoutWeb.TransactionView, "_tile.html", transaction: transaction %>
<% end %>
</span>
<% else %>
@ -52,7 +52,6 @@
to: transaction_path(
@conn,
:index,
@conn.assigns.locale,
@next_page_params
)
) %>

@ -1,13 +1,13 @@
<div class="col-sm-3 fade-up-blocks-chain mb-3 mb-sm-0" data-selector="chain-block" data-block-number="<%= @block.number %>">
<div class="tile d-flex flex-column">
<%= link(@block, to: block_path(BlockScoutWeb.Endpoint, :show, @locale, @block), class: "tile-title") %>
<%= link(@block, to: block_path(BlockScoutWeb.Endpoint, :show, @block), class: "tile-title") %>
<div>
<span class="mr-2"> <%= Enum.count(@block.transactions) %> Transactions </span>
<span class="text-nowrap" data-from-now="<%= @block.timestamp %>"> </span>
</div>
<span class="text-truncate">
<%= gettext "Miner" %>
<%= link to: address_path(BlockScoutWeb.Endpoint, :show, @locale, @block.miner),
<%= link to: address_path(BlockScoutWeb.Endpoint, :show, @block.miner),
"data-toggle": "tooltip",
"data-placement": "top",
title: @block.miner do %>

@ -9,16 +9,14 @@
<span class="dashboard-banner-chart-legend-label">
<%= gettext "Price" %>
</span>
<span class="dashboard-banner-chart-legend-value" data-selector="exchange-rate">
<%= format_exchange_rate(@exchange_rate) %>
<span class="dashboard-banner-chart-legend-value" data-selector="exchange-rate" data-wei-value="<%= Explorer.Chain.Wei.from(Decimal.new(1), :ether).value %>" data-usd-exchange-rate="<%= @exchange_rate.usd_value %>">
</span>
</div>
<div class="dashboard-banner-chart-legend-item">
<span class="dashboard-banner-chart-legend-label">
<%= gettext "Market Cap" %>
</span>
<span class="dashboard-banner-chart-legend-value" data-selector="market-cap">
<%= format_market_cap(@exchange_rate) %>
<span class="dashboard-banner-chart-legend-value" data-selector="market-cap" data-usd-value="<%= @exchange_rate.market_cap_usd %>">
</span>
</div>
</div>
@ -54,11 +52,11 @@
<section class="container">
<div class="card card-chain-blocks">
<div class="card-body">
<%= link(gettext("View All Blocks →"), to: block_path(BlockScoutWeb.Endpoint, :index, Gettext.get_locale), class: "button button--secondary button--xsmall float-right") %>
<%= link(gettext("View All Blocks →"), to: block_path(BlockScoutWeb.Endpoint, :index), class: "button button--secondary button--xsmall float-right") %>
<h2 class="card-title"><%= gettext "Blocks" %></h2>
<div class="row" data-selector="chain-block-list">
<%= for block <- @blocks do %>
<%= render BlockScoutWeb.ChainView, "_block.html", locale: @locale, block: block %>
<%= render BlockScoutWeb.ChainView, "_block.html", block: block %>
<% end %>
</div>
</div>
@ -71,11 +69,11 @@
<a href="#" class="alert-link"><span data-selector="channel-batching-count"></span> <%= gettext "More transactions have come in" %></a>
</div>
</div>
<%= link(gettext("View All Transactions →"), to: transaction_path(BlockScoutWeb.Endpoint, :index, Gettext.get_locale), class: "button button--secondary button--xsmall float-right") %>
<%= link(gettext("View All Transactions →"), to: transaction_path(BlockScoutWeb.Endpoint, :index), class: "button button--secondary button--xsmall float-right") %>
<h2 class="card-title"><%= gettext "Transactions" %></h2>
<span data-selector="transactions-list">
<%= for transaction <- @transactions do %>
<%= render BlockScoutWeb.TransactionView, "_tile.html", locale: @locale, transaction: transaction %>
<%= render BlockScoutWeb.TransactionView, "_tile.html", transaction: transaction %>
<% end %>
</span>
</div>

@ -9,22 +9,22 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<%= link to: block_path(@conn, :index, Gettext.get_locale), class: "nav-link topnav-nav-link" do %>
<%= link to: block_path(@conn, :index), class: "nav-link topnav-nav-link" do %>
<%= gettext("Blocks") %>
<% end %>
</li>
<li class="nav-item">
<%= link to: transaction_path(@conn, :index, Gettext.get_locale), class: "nav-link topnav-nav-link" do %>
<%= link to: transaction_path(@conn, :index), class: "nav-link topnav-nav-link" do %>
<%= gettext("Transactions") %>
<% end %>
</li>
<li class="nav-item">
<%= link to: api_docs_path(@conn, :index, Gettext.get_locale), class: "nav-link topnav-nav-link" do %>
<%= link to: api_docs_path(@conn, :index), class: "nav-link topnav-nav-link" do %>
<%= gettext("API") %>
<% end %>
</li>
</ul>
<%= form_for @conn, chain_path(@conn, :search, Gettext.get_locale), [class: "form-inline my-2 my-lg-0", method: :get, enforce_utf8: false], fn f -> %>
<%= form_for @conn, chain_path(@conn, :search), [class: "form-inline my-2 my-lg-0", method: :get, enforce_utf8: false], fn f -> %>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="search-icon"><i class="fas fa-search"></i></span>

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="<%= @conn.assigns.locale %>">
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
@ -18,6 +18,13 @@
</main>
<%= render BlockScoutWeb.LayoutView, "_footer.html", assigns %>
</div>
<script>
window.localized = {
'Less than': '<%= gettext("Less than") %>',
'Market Cap': '<%= gettext("Market Cap") %>',
'Price': '<%= gettext("Price") %>',
}
</script>
<script src="<%= static_path(@conn, "/js/app.js") %>"></script>
</body>
</html>

@ -8,7 +8,7 @@
<%= link(
gettext("Validated"),
class: "nav-link",
to: transaction_path(@conn, :index, @conn.assigns.locale)
to: transaction_path(@conn, :index)
) %>
</li>
<li class="nav-item">
@ -16,7 +16,7 @@
gettext("Pending"),
class: "nav-link active",
"data-test": "pending_transactions_link",
to: pending_transaction_path(@conn, :index, @conn.assigns.locale)
to: pending_transaction_path(@conn, :index)
) %>
</li>
</ul>
@ -29,13 +29,13 @@
<%= link(
gettext("Validated"),
class: "dropdown-item",
to: transaction_path(@conn, :index, @conn.assigns.locale)
to: transaction_path(@conn, :index)
) %>
<%= link(
gettext("Pending"),
class: "dropdown-item",
"data-test": "pending_transactions_link",
to: pending_transaction_path(@conn, :index, @conn.assigns.locale)
to: pending_transaction_path(@conn, :index)
) %>
</div>
</li>
@ -54,12 +54,12 @@
<div class="tile-status-label ml-2 ml-md-0" data-test="transaction_status"><%= BlockScoutWeb.TransactionView.formatted_status(transaction) %></div>
</div>
<div class="col-md-7 col-lg-8 d-flex flex-column pr-2 pr-sm-2 pr-md-0">
<%= render BlockScoutWeb.TransactionView, "_link.html", locale: @locale, transaction_hash: transaction.hash %>
<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: transaction.hash %>
<span class="text-nowrap">
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(transaction.from_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(transaction.from_address) %>
&rarr;
<%= if transaction.to_address_hash do %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: transaction.to_address_hash, contract: BlockScoutWeb.AddressView.contract?(transaction.to_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: transaction.to_address_hash, contract: BlockScoutWeb.AddressView.contract?(transaction.to_address) %>
<% else %>
<%= gettext("Contract Address Pending") %>
<% end %>
@ -80,7 +80,6 @@
to: pending_transaction_path(
@conn,
:index,
@conn.assigns.locale,
@next_page_params
)
) %>

@ -10,7 +10,7 @@
<%= if queryable?(function["inputs"]) do %>
<div class="">
<form class="form-inline" data-function-form data-url="<%= smart_contract_path(@conn, :show, :en, @address.hash) %>">
<form class="form-inline" data-function-form data-url="<%= smart_contract_path(@conn, :show, @address.hash) %>">
<input type="hidden" name="function_name" value='<%= function["name"] %>' />
<%= for input <- function["inputs"] do %>
@ -38,7 +38,7 @@
<%= if address?(output["type"]) do %>
<%= link(
output["value"],
to: address_path(@conn, :show, @conn.assigns.locale, output["value"])
to: address_path(@conn, :show, output["value"])
) %>
<% else %>
<%= if output["type"] == "uint256" do %>

@ -16,14 +16,14 @@
<%= link(
gettext("Token Transfers"),
class: "nav-link",
to: token_path(@conn, :show, @conn.assigns.locale, @conn.params["token_id"])
to: token_path(@conn, :show, @conn.params["token_id"])
) %>
</li>
<li class="nav-item">
<%= link(
gettext("Read Contract"),
to: token_read_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["token_id"]),
to: token_read_contract_path(@conn, :index, @conn.params["token_id"]),
class: "nav-link active")%>
</li>
</ul>
@ -36,7 +36,7 @@
<%= link(
gettext("Token Transfers"),
class: "nav-link active",
to: token_path(@conn, :show, @conn.assigns.locale, "1")
to: token_path(@conn, :show, @token.contract_address_hash)
) %>
<%= link(
gettext("Read Contract"),
@ -48,7 +48,7 @@
</div>
<!-- loaded via AJAX -->
<div class="card-body" data-smart-contract-functions data-hash="<%= to_string(@token.contract_address.hash) %>" data-url="<%= smart_contract_path(@conn, :index, :en) %>">
<div class="card-body" data-smart-contract-functions data-hash="<%= to_string(@token.contract_address.hash) %>" data-url="<%= smart_contract_path(@conn, :index) %>">
<i class="fa fa-spinner fa-spin"></i> <%= gettext("loading...") %>
</div>
</div>

@ -6,22 +6,20 @@
<div class="col-md-7 col-lg-8 d-flex flex-column">
<p class="tile-title text-truncate">
<%= render BlockScoutWeb.TransactionView, "_link.html", locale: @locale, transaction_hash: @transfer.transaction_hash %>
<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: @transfer.transaction_hash %>
</p>
<span>
<%= render BlockScoutWeb.AddressView,
"_link.html",
address_hash: to_string(@transfer.from_address_hash),
contract: BlockScoutWeb.AddressView.contract?(@transfer.from_address),
locale: @locale %>
contract: BlockScoutWeb.AddressView.contract?(@transfer.from_address) %>
&rarr;
<%= render BlockScoutWeb.AddressView,
"_link.html",
address_hash: to_string(@transfer.to_address_hash),
contract: BlockScoutWeb.AddressView.contract?(@transfer.to_address),
locale: @locale %>
contract: BlockScoutWeb.AddressView.contract?(@transfer.to_address) %>
</span>
<span>
@ -40,7 +38,7 @@
number: @transfer.transaction.block_number
),
class: "mr-2 mr-sm-0 text-muted",
to: block_path(BlockScoutWeb.Endpoint, :show, @locale, @transfer.transaction.block_number)
to: block_path(BlockScoutWeb.Endpoint, :show, @transfer.transaction.block_number)
) %>
</span>
</div>

@ -16,7 +16,7 @@
<%= link(
gettext("Token Transfers"),
class: "nav-link active",
to: token_path(@conn, :show, @conn.assigns.locale, "1")
to: token_path(@conn, :show, @token.contract_address_hash)
) %>
</li>
@ -24,7 +24,7 @@
<li class="nav-item">
<%= link(
gettext("Read Contract"),
to: token_read_contract_path(@conn, :index, @conn.assigns.locale, @conn.params["id"]),
to: token_read_contract_path(@conn, :index, @conn.params["id"]),
class: "nav-link")%>
</li>
<% end %>
@ -38,7 +38,7 @@
<%= link(
gettext("Token Transfers"),
class: "nav-link active",
to: token_path(@conn, :show, @conn.assigns.locale, "1")
to: token_path(@conn, :show, @token.contract_address_hash)
) %>
<%= if smart_contract_with_read_only_functions?(@token) do %>
<%= link(
@ -56,7 +56,7 @@
<%= if Enum.any?(@transfers) do %>
<%= for transfer <- @transfers do %>
<%= render("_token_transfer.html", locale: @locale, token: @token, transfer: transfer) %>
<%= render("_token_transfer.html", token: @token, transfer: transfer) %>
<% end %>
<% else %>
<div class="tile tile-muted text-center">
@ -70,7 +70,7 @@
<%= link(
gettext("Older"),
class: "button button--secondary button--small float-right mt-4",
to: token_path(@conn, :show, @conn.assigns.locale, @token.contract_address_hash, @next_page_params)
to: token_path(@conn, :show, @token.contract_address_hash, @next_page_params)
) %>
<% end %>
</div>

@ -1,4 +1,4 @@
<%= link(@transaction_hash,
to: transaction_path(BlockScoutWeb.Endpoint, :show, @locale, @transaction_hash),
to: transaction_path(BlockScoutWeb.Endpoint, :show, @transaction_hash),
"data-test": "transaction_hash_link",
class: "text-truncate") %>

@ -9,14 +9,14 @@
</span>
</div>
<div class="col-md-7 col-lg-8 d-flex flex-column pr-2 pr-sm-2 pr-md-0">
<%= render "_link.html", locale: @locale, transaction_hash: @transaction.hash %>
<%= render "_link.html", transaction_hash: @transaction.hash %>
<span class="text-nowrap">
<%= BlockScoutWeb.AddressView.display_address_hash(assigns[:current_address], @transaction.from_address, @locale) %>
<%= BlockScoutWeb.AddressView.display_address_hash(assigns[:current_address], @transaction.from_address) %>
&rarr;
<%= if assigns[:current_address] && assigns[:current_address].hash == to_address_hash(@transaction) do %>
<%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: to_address_hash(@transaction), contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address) %>
<% else %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: to_address_hash(@transaction), contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: to_address_hash(@transaction), contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address) %>
<% end %>
</span>
<span class="d-flex flex-md-row flex-column mt-3 mt-md-0">
@ -32,7 +32,7 @@
<span class="mr-2 mr-md-0 order-1">
<%= link(
gettext("Block #%{number}", number: to_string(@transaction.block.number)),
to: block_path(BlockScoutWeb.Endpoint, :show, @locale, @transaction.block)
to: block_path(BlockScoutWeb.Endpoint, :show, @transaction.block)
) %>
</span>
<span class="mr-2 mr-md-0 order-2" data-from-now="<%= @transaction.block.timestamp %>"></span>
@ -54,10 +54,10 @@
<%= if involves_token_transfers?(@transaction) do %>
<div class="offset-md-2 col-md-10 col-lg-8 d-flex flex-column mt-2 mb-2">
<% [first_token_transfer | remaining_token_transfers]= @transaction.token_transfers %>
<%= render "_token_transfer.html", address: assigns[:current_address], locale: @locale, token_transfer: first_token_transfer %>
<%= render "_token_transfer.html", address: assigns[:current_address], token_transfer: first_token_transfer %>
<div class="collapse token-transfer-toggle" id="<%= @transaction.hash %>">
<%= for token_transfer <- remaining_token_transfers do %>
<%= render "_token_transfer.html", address: assigns[:current_address], locale: @locale, token_transfer: token_transfer %>
<%= render "_token_transfer.html", address: assigns[:current_address], token_transfer: token_transfer %>
<% end %>
</div>
</div>

@ -11,12 +11,12 @@
</span>
<% end %>
<% end %>
<%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.from_address, @locale, true) %>
<%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.from_address, true) %>
&rarr;
<%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.to_address, @locale, true) %>
<%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.to_address, true) %>
</span>
<span class="col-12 col-md-7 ml-3 ml-sm-0">
<%= token_transfer_amount(@token_transfer) %>
<%= link(token_symbol(@token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, @locale, @token_transfer.token.contract_address_hash)) %>
<%= link(token_symbol(@token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, @token_transfer.token.contract_address_hash)) %>
</span>
</div>

@ -8,7 +8,7 @@
<%= link(
gettext("Validated"),
class: "nav-link active",
to: transaction_path(@conn, :index, @conn.assigns.locale)
to: transaction_path(@conn, :index)
) %>
</li>
<li class="nav-item">
@ -16,7 +16,7 @@
gettext("Pending"),
class: "nav-link",
"data-test": "pending_transactions_link",
to: pending_transaction_path(@conn, :index, @conn.assigns.locale)
to: pending_transaction_path(@conn, :index)
) %>
</li>
</ul>
@ -29,13 +29,13 @@
<%= link(
gettext("Validated"),
class: "dropdown-item",
to: transaction_path(@conn, :index, @conn.assigns.locale)
to: transaction_path(@conn, :index)
) %>
<%= link(
gettext("Pending"),
class: "dropdown-item",
"data-test": "pending_transactions_link",
to: pending_transaction_path(@conn, :index, @conn.assigns.locale)
to: pending_transaction_path(@conn, :index)
) %>
</div>
</li>
@ -57,7 +57,7 @@
<p><%= gettext("Showing") %> <span data-selector="transaction-count"><%= Cldr.Number.to_string!(@transaction_estimated_count, format: "#,###") %></span> <%= gettext("Validated Transactions") %></p>
<span data-selector="transactions-list">
<%= for transaction <- @transactions do %>
<%= render BlockScoutWeb.TransactionView, "_tile.html", locale: @locale, transaction: transaction %>
<%= render BlockScoutWeb.TransactionView, "_tile.html", transaction: transaction %>
<% end %>
</span>
@ -68,7 +68,6 @@
to: transaction_path(
@conn,
:index,
@conn.assigns.locale,
@next_page_params
)
) %>

@ -8,10 +8,10 @@
<h1 class="card-title"><%= gettext "Transaction Details" %> </h1>
<h3 data-test="transaction_detail_hash"><%= @transaction %> </h3>
<span class="d-block mb-2">
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@transaction.from_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@transaction.from_address) %>
<span class="text-muted"> &rarr; </span>
<%= if @transaction.to_address_hash do %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @transaction.to_address_hash, contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @transaction.to_address_hash, contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address) %>
<% else %>
<%= gettext("Contract Address Pending") %>
<% end %>
@ -34,7 +34,7 @@
<%= link(
block,
class: "transaction__link",
to: block_path(@conn, :show, @conn.assigns.locale, block)
to: block_path(@conn, :show, block)
) %>
<% else %>
<%= gettext "Pending" %>
@ -55,7 +55,9 @@
<!-- TX Fee -->
<dl class="row">
<dt class="col-sm-3 text-muted"> <%= gettext "TX Fee" %> </dt>
<dd class="col-sm-9"> <%= formatted_fee(@transaction, denomination: :ether) %> (<%= formatted_fee(@transaction, exchange_rate: @exchange_rate) %>)</dd>
<dd class="col-sm-9">
<%= formatted_fee(@transaction, denomination: :ether) %> (<span data-wei-value=<%= fee(@transaction) %> data-usd-exchange-rate=<%= @exchange_rate.usd_value %>></span>)
</dd>
</dl>
<!-- Input -->
@ -82,7 +84,7 @@
<h2 class="card-title text-white"><%= gettext "Ether" %> <%= gettext "Value" %></h2>
<div class="text-right">
<h3 class="text-white"> <%= value(@transaction) %></h3>
<span class="text-light"> <%= formatted_usd_value(@transaction, @exchange_rate) %></span>
<span class="text-light" data-wei-value=<%= @transaction.value.value %> data-usd-exchange-rate=<%= @exchange_rate.usd_value %>></span>
</div>
</div>
</div>

@ -4,11 +4,11 @@
<%= gettext("Internal Transaction") %>
</div>
<div class="col-md-9 col-lg-10 d-flex flex-column text-nowrap">
<%= render BlockScoutWeb.TransactionView, "_link.html", locale: @locale, transaction_hash: @internal_transaction.transaction_hash %>
<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: @internal_transaction.transaction_hash %>
<span class="text-nowrap">
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @internal_transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.from_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @internal_transaction.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.from_address) %>
&rarr;
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: BlockScoutWeb.InternalTransactionView.to_address_hash(@internal_transaction), contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.to_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: BlockScoutWeb.InternalTransactionView.to_address_hash(@internal_transaction), contract: BlockScoutWeb.AddressView.contract?(@internal_transaction.to_address) %>
</span>
<span class="tile-title text-truncate">

@ -11,7 +11,7 @@
<%= link(
gettext("Token Transfers"),
class: "nav-link",
to: transaction_token_transfer_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_token_transfer_path(@conn, :index, @transaction)
) %>
</li>
<% end %>
@ -19,14 +19,14 @@
<%= link(
gettext("Internal Transactions"),
class: "nav-link active",
to: transaction_internal_transaction_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_internal_transaction_path(@conn, :index, @transaction)
) %>
</li>
<li class="nav-item">
<%= link(
gettext("Logs"),
class: "nav-link",
to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction),
to: transaction_log_path(@conn, :index, @transaction),
"data-test": "transaction_logs_link"
) %>
</li>
@ -41,19 +41,19 @@
<%= link(
gettext("Token Transfers"),
class: "dropdown-item",
to: transaction_token_transfer_path(@conn, :index, @conn.assigns.locale, @transaction),
to: transaction_token_transfer_path(@conn, :index, @transaction),
"data-test": "transaction_token_transfer_link"
) %>
<% end %>
<%= link(
gettext("Internal Transactions"),
class: "dropdown-item",
to: transaction_internal_transaction_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_internal_transaction_path(@conn, :index, @transaction)
) %>
<%= link(
gettext("Logs"),
class: "dropdown-item",
to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction),
to: transaction_log_path(@conn, :index, @transaction),
"data-test": "transaction_logs_link"
) %>
</div>
@ -64,7 +64,7 @@
<h2 class="card-title"><%= gettext "Internal Transactions" %></h2>
<%= if Enum.count(@internal_transactions) > 0 do %>
<%= for internal_transaction <- @internal_transactions do %>
<%= render "_internal_transaction.html", locale: @locale, internal_transaction: internal_transaction %>
<%= render "_internal_transaction.html", internal_transaction: internal_transaction %>
<% end %>
<% else %>
<div class="tile tile-muted text-center">
@ -79,7 +79,6 @@
to: transaction_internal_transaction_path(
@conn,
:index,
@conn.assigns.locale,
@transaction,
@next_page_params
)

@ -12,7 +12,7 @@
<%= link(
gettext("Token Transfers"),
class: "nav-link",
to: transaction_token_transfer_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_token_transfer_path(@conn, :index, @transaction)
) %>
<% end %>
</li>
@ -20,14 +20,14 @@
<%= link(
gettext("Internal Transactions"),
class: "nav-link",
to: transaction_internal_transaction_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_internal_transaction_path(@conn, :index, @transaction)
) %>
</li>
<li class="nav-item">
<%= link(
gettext("Logs"),
class: "nav-link active",
to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_log_path(@conn, :index, @transaction)
) %>
</li>
</ul>
@ -41,19 +41,19 @@
<%= link(
gettext("Token Transfers"),
class: "dropdown-item",
to: transaction_token_transfer_path(@conn, :index, @conn.assigns.locale, @transaction),
to: transaction_token_transfer_path(@conn, :index, @transaction),
"data-test": "transaction_token_transfer_link"
) %>
<% end %>
<%= link(
gettext("Internal Transactions"),
class: "dropdown-item",
to: transaction_path(@conn, :show, @conn.assigns.locale, @transaction)
to: transaction_path(@conn, :show, @transaction)
) %>
<%= link(
gettext("Logs"),
class: "dropdown-item",
to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction),
to: transaction_log_path(@conn, :index, @transaction),
"data-test": "transaction_logs_link"
) %>
</div>
@ -72,7 +72,7 @@
<h3 class="">
<%= link(
log.address,
to: address_path(@conn, :show, @conn.assigns.locale, log.address),
to: address_path(@conn, :show, log.address),
"data-test": "log_address_link",
"data-address-hash": log.address
) %>
@ -124,7 +124,6 @@
to: transaction_log_path(
@conn,
:index,
@conn.assigns.locale,
@transaction,
@next_page_params
)

@ -5,16 +5,16 @@
</div>
<div class="col-12 col-md-8 col-lg-10 d-flex flex-column text-nowrap">
<%= render BlockScoutWeb.TransactionView, "_link.html", locale: @locale, transaction_hash: @token_transfer.transaction_hash %>
<%= render BlockScoutWeb.TransactionView, "_link.html", transaction_hash: @token_transfer.transaction_hash %>
<span class="text-nowrap">
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @token_transfer.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@token_transfer.from_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @token_transfer.from_address_hash, contract: BlockScoutWeb.AddressView.contract?(@token_transfer.from_address) %>
&rarr;
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @token_transfer.to_address_hash, contract: BlockScoutWeb.AddressView.contract?(@token_transfer.to_address), locale: @locale %>
<%= render BlockScoutWeb.AddressView, "_link.html", address_hash: @token_transfer.to_address_hash, contract: BlockScoutWeb.AddressView.contract?(@token_transfer.to_address) %>
</span>
<span class="tile-title text-truncate">
<%= token_transfer_amount(@token_transfer) %>
<%= link(token_symbol(@token_transfer.token), to: token_path(@conn, :show, @locale, @token_transfer.token.contract_address_hash)) %>
<%= link(token_symbol(@token_transfer.token), to: token_path(@conn, :show, @token_transfer.token.contract_address_hash)) %>
</span>
</div>
</div>

@ -10,21 +10,21 @@
<%= link(
gettext("Token Transfers"),
class: "nav-link active",
to: transaction_token_transfer_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_token_transfer_path(@conn, :index, @transaction)
) %>
</li>
<li class="nav-item">
<%= link(
gettext("Internal Transactions"),
class: "nav-link",
to: transaction_internal_transaction_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_internal_transaction_path(@conn, :index, @transaction)
) %>
</li>
<li class="nav-item">
<%= link(
gettext("Logs"),
class: "nav-link",
to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_log_path(@conn, :index, @transaction)
) %>
</li>
</ul>
@ -37,17 +37,17 @@
<%= link(
gettext("Token Transfers"),
class: "dropdown-item",
to: transaction_token_transfer_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_token_transfer_path(@conn, :index, @transaction)
) %>
<%= link(
gettext("Internal Transactions"),
class: "dropdown-item",
to: transaction_internal_transaction_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_internal_transaction_path(@conn, :index, @transaction)
) %>
<%= link(
gettext("Logs"),
class: "dropdown-item",
to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction)
to: transaction_log_path(@conn, :index, @transaction)
) %>
</div>
</li>
@ -58,7 +58,7 @@
<h2 class="card-title"><%= gettext "Token Transfers" %></h2>
<%= if Enum.any?(@token_transfers) do %>
<%= for token_transfer <- @token_transfers do %>
<%= render "_token_transfer.html", locale: @locale, token_transfer: token_transfer, conn: @conn %>
<%= render "_token_transfer.html", token_transfer: token_transfer, conn: @conn %>
<% end %>
<% else %>
<div class="tile tile-muted text-center">
@ -74,7 +74,6 @@
to: transaction_token_transfer_path(
@conn,
:index,
@conn.assigns.locale,
@transaction,
@next_page_params
)

@ -1,10 +1,7 @@
defmodule BlockScoutWeb.AddressView do
use BlockScoutWeb, :view
alias Explorer.Chain.{Address, Hash, SmartContract, Wei}
alias Explorer.ExchangeRates.Token
alias BlockScoutWeb.ExchangeRates.USD
alias Explorer.Chain.{Address, Hash, SmartContract}
@dialyzer :no_match
@ -37,20 +34,6 @@ defmodule BlockScoutWeb.AddressView do
def contract?(nil), do: true
def formatted_usd(%Address{fetched_coin_balance: nil}, _), do: nil
def formatted_usd(%Address{fetched_coin_balance: balance}, %Token{} = exchange_rate) do
case Wei.cast(balance) do
{:ok, wei} ->
wei
|> USD.from(exchange_rate)
|> format_usd_value()
_ ->
nil
end
end
def hash(%Address{hash: hash}) do
to_string(hash)
end
@ -79,25 +62,23 @@ defmodule BlockScoutWeb.AddressView do
def smart_contract_with_read_only_functions?(%Address{smart_contract: nil}), do: false
def display_address_hash(current_address, target_address, locale, truncate \\ false)
def display_address_hash(current_address, target_address, truncate \\ false)
def display_address_hash(nil, target_address, locale, truncate) do
def display_address_hash(nil, target_address, truncate) do
render(
"_link.html",
address_hash: target_address.hash,
contract: contract?(target_address),
locale: locale,
truncate: truncate
)
end
def display_address_hash(current_address, target_address, locale, truncate) do
def display_address_hash(current_address, target_address, truncate) do
if current_address.hash == target_address.hash do
render(
"_responsive_hash.html",
address_hash: current_address.hash,
contract: contract?(current_address),
locale: locale,
truncate: truncate
)
else
@ -105,7 +86,6 @@ defmodule BlockScoutWeb.AddressView do
"_link.html",
address_hash: target_address.hash,
contract: contract?(target_address),
locale: locale,
truncate: truncate
)
end

@ -1,9 +1,6 @@
defmodule BlockScoutWeb.ChainView do
use BlockScoutWeb, :view
alias Explorer.ExchangeRates.Token
alias BlockScoutWeb.ExchangeRates.USD
def encode_market_history_data(market_history_data) do
market_history_data
|> Enum.map(fn day -> Map.take(day, [:closing_price, :date]) end)
@ -13,16 +10,4 @@ defmodule BlockScoutWeb.ChainView do
_ -> []
end
end
def format_exchange_rate(%Token{usd_value: usd_value}) do
usd_value
|> USD.from()
|> format_usd_value()
end
def format_market_cap(%Token{market_cap_usd: market_cap}) do
market_cap
|> USD.from()
|> format_usd_value()
end
end

@ -3,46 +3,8 @@ defmodule BlockScoutWeb.CurrencyHelpers do
Helper functions for interacting with `t:BlockScoutWeb.ExchangeRates.USD.t/0` values.
"""
alias BlockScoutWeb.ExchangeRates.USD
alias BlockScoutWeb.Cldr.Number
@doc """
Formats a `BlockScoutWeb.ExchangeRates.USD` value into USD and applies a unit label.
## Examples
iex> format_usd_value(%USD{value: Decimal.new(0.0000001)})
"< $0.000001 USD"
iex> format_usd_value(%USD{value: Decimal.new(0.123456789)})
"$0.123457 USD"
iex> format_usd_value(%USD{value: Decimal.new(0.1234)})
"$0.123400 USD"
iex> format_usd_value(%USD{value: Decimal.new(1.23456789)})
"$1.23 USD"
iex> format_usd_value(%USD{value: Decimal.new(1.2)})
"$1.20 USD"
iex> format_usd_value(%USD{value: Decimal.new(123456.789)})
"$123,457 USD"
"""
@spec format_usd_value(USD.t() | nil) :: binary() | nil
def format_usd_value(nil), do: nil
def format_usd_value(%USD{value: nil}), do: nil
def format_usd_value(%USD{value: value}) do
cond do
Decimal.cmp(value, "0.000001") == :lt -> "< $0.000001 USD"
Decimal.cmp(value, 1) == :lt -> "$#{Number.to_string!(value, format: "0.000000")} USD"
Decimal.cmp(value, 100_000) == :lt -> "$#{Number.to_string!(value, format: "#,###.00")} USD"
true -> "$#{Number.to_string!(value, format: "#,###")} USD"
end
end
@doc """
Formats the given integer value to a currency format.

@ -4,9 +4,7 @@ defmodule BlockScoutWeb.TransactionView do
alias Cldr.Number
alias Explorer.Chain
alias Explorer.Chain.{Address, InternalTransaction, Transaction, Wei}
alias Explorer.ExchangeRates.Token
alias BlockScoutWeb.{AddressView, BlockView}
alias BlockScoutWeb.ExchangeRates.USD
import BlockScoutWeb.Gettext
@ -30,14 +28,18 @@ defmodule BlockScoutWeb.TransactionView do
def to_address_hash(%Transaction{to_address: %Address{hash: address_hash}}), do: address_hash
def fee(%Transaction{} = transaction) do
{_, value} = Chain.fee(transaction, :wei)
value
end
def formatted_fee(%Transaction{} = transaction, opts) do
transaction
|> Chain.fee(:wei)
|> fee_to_currency(opts)
|> fee_to_denomination(opts)
|> case do
{_, nil} -> nil
{:actual, value} -> value
{:maximum, value} -> "<= " <> value
{:maximum, value} -> "#{gettext("Max of")} #{value}"
end
end
@ -80,12 +82,6 @@ defmodule BlockScoutWeb.TransactionView do
end
end
def formatted_usd_value(%Transaction{value: nil}, _token), do: nil
def formatted_usd_value(%Transaction{value: value}, token) do
format_usd_value(USD.from(value, token))
end
defdelegate formatted_timestamp(block), to: BlockView
def gas(%type{gas: gas}) when is_transaction_type(type) do
@ -137,23 +133,6 @@ defmodule BlockScoutWeb.TransactionView do
format_wei_value(value, :ether, include_unit_label: include_label?)
end
defp fee_to_currency(fee, options) do
case Keyword.fetch(options, :exchange_rate) do
{:ok, exchange_rate} -> fee_to_usd(fee, exchange_rate)
:error -> fee_to_denomination(fee, options)
end
end
defp fee_to_usd({fee_type, fee}, %Token{} = exchange_rate) do
formatted =
fee
|> Wei.from(:wei)
|> USD.from(exchange_rate)
|> format_usd_value()
{fee_type, formatted}
end
defp fee_to_denomination({fee_type, fee}, opts) do
denomination = Keyword.get(opts, :denomination)
include_label? = Keyword.get(opts, :include_label, true)

@ -52,7 +52,6 @@ defmodule BlockScoutWeb.Mixfile do
:timex,
:timex_ecto,
:crontab,
:set_locale,
:logger,
:runtime_tools
]
@ -89,8 +88,6 @@ defmodule BlockScoutWeb.Mixfile do
{:phoenix_live_reload, "~> 1.0", only: [:dev]},
{:phoenix_pubsub, "~> 1.0"},
{:postgrex, ">= 0.0.0"},
# Waiting on https://github.com/smeevil/set_locale/pull/9
{:set_locale, github: "minifast/set_locale", branch: "master"},
{:sobelow, ">= 0.7.0", only: [:dev, :test], runtime: false},
{:timex, "~> 3.1.24"},
{:timex_ecto, "~> 3.2.1"},

@ -6,7 +6,7 @@ msgstr ""
msgid "Block"
msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:58
#: lib/block_scout_web/templates/chain/show.html.eex:56
#: lib/block_scout_web/templates/layout/_topnav.html.eex:13
msgid "Blocks"
msgstr ""
@ -39,18 +39,18 @@ msgstr ""
#: lib/block_scout_web/templates/address_read_contract/index.html.eex:10
#: lib/block_scout_web/templates/address_transaction/index.html.eex:13
#: lib/block_scout_web/templates/address_transaction/index.html.eex:55
#: lib/block_scout_web/templates/address_transaction/index.html.eex:131
#: lib/block_scout_web/templates/address_transaction/index.html.eex:129
#: lib/block_scout_web/templates/block_transaction/index.html.eex:13
#: lib/block_scout_web/templates/block_transaction/index.html.eex:26
#: lib/block_scout_web/templates/block_transaction/index.html.eex:36
#: lib/block_scout_web/templates/chain/show.html.eex:75
#: lib/block_scout_web/templates/chain/show.html.eex:73
#: lib/block_scout_web/templates/layout/_topnav.html.eex:18
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:46
#: lib/block_scout_web/templates/transaction/index.html.eex:56
msgid "Transactions"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:82
#: lib/block_scout_web/templates/transaction/overview.html.eex:84
msgid "Value"
msgstr ""
@ -110,7 +110,7 @@ msgstr ""
msgid "Cumulative Gas Used"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:93
#: lib/block_scout_web/templates/transaction/overview.html.eex:95
msgid "Gas"
msgstr ""
@ -118,7 +118,7 @@ msgstr ""
msgid "Gas Price"
msgstr ""
#: lib/block_scout_web/templates/transaction/overview.html.eex:63
#: lib/block_scout_web/templates/transaction/overview.html.eex:65
msgid "Input"
msgstr ""
@ -130,12 +130,12 @@ msgstr ""
msgid "%{count} transactions in this block"
msgstr ""
#: lib/block_scout_web/views/address_view.ex:15
#: lib/block_scout_web/views/address_view.ex:12
msgid "Address"
msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:106
#: lib/block_scout_web/templates/address_transaction/index.html.eex:117
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:105
#: lib/block_scout_web/templates/address_transaction/index.html.eex:116
#: lib/block_scout_web/views/address_internal_transaction_view.ex:10
#: lib/block_scout_web/views/address_transaction_view.ex:10
msgid "From"
@ -146,7 +146,7 @@ msgstr ""
msgid "Overview"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:79
#: lib/block_scout_web/views/transaction_view.ex:81
msgid "Success"
msgstr ""
@ -198,8 +198,8 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/index.html.eex:16
#: lib/block_scout_web/templates/transaction/index.html.eex:35
#: lib/block_scout_web/templates/transaction/overview.html.eex:40
#: lib/block_scout_web/views/transaction_view.ex:44
#: lib/block_scout_web/views/transaction_view.ex:78
#: lib/block_scout_web/views/transaction_view.ex:46
#: lib/block_scout_web/views/transaction_view.ex:80
msgid "Pending"
msgstr ""
@ -267,11 +267,11 @@ msgstr ""
msgid "Next Page"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:76
#: lib/block_scout_web/views/transaction_view.ex:78
msgid "Failed"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:77
#: lib/block_scout_web/views/transaction_view.ex:79
msgid "Out of Gas"
msgstr ""
@ -291,7 +291,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/_internal_transaction.html.eex:22
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:68
#: lib/block_scout_web/templates/transaction/_tile.html.eex:24
#: lib/block_scout_web/templates/transaction/overview.html.eex:82
#: lib/block_scout_web/templates/transaction/overview.html.eex:84
#: lib/block_scout_web/templates/transaction_internal_transaction/_internal_transaction.html.eex:16
#: lib/block_scout_web/views/wei_helpers.ex:72
msgid "Ether"
@ -305,7 +305,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_contract/index.html.eex:17
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:20
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:119
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:117
#: lib/block_scout_web/templates/address_read_contract/index.html.eex:17
#: lib/block_scout_web/templates/address_transaction/index.html.eex:20
#: lib/block_scout_web/templates/address_transaction/index.html.eex:60
@ -391,11 +391,13 @@ msgstr ""
msgid "Avg Block Time"
msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:17
#: lib/block_scout_web/templates/layout/app.html.eex:24
msgid "Market Cap"
msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:10
#: lib/block_scout_web/templates/layout/app.html.eex:25
msgid "Price"
msgstr ""
@ -439,7 +441,7 @@ msgstr ""
msgid "Total Gas Used"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:124
#: lib/block_scout_web/views/transaction_view.ex:120
msgid "Transaction"
msgstr ""
@ -462,7 +464,7 @@ msgstr ""
msgid "Contract"
msgstr ""
#: lib/block_scout_web/views/address_view.ex:13
#: lib/block_scout_web/views/address_view.ex:10
msgid "Contract Address"
msgstr ""
@ -474,8 +476,8 @@ msgstr ""
msgid "There are no Transactions"
msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:132
#: lib/block_scout_web/templates/address_transaction/index.html.eex:145
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:130
#: lib/block_scout_web/templates/address_transaction/index.html.eex:143
#: lib/block_scout_web/templates/block/index.html.eex:15
#: lib/block_scout_web/templates/block_transaction/index.html.eex:50
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:78
@ -524,7 +526,7 @@ msgid "Newer"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:122
#: lib/block_scout_web/views/transaction_view.ex:118
msgid "Contract Creation"
msgstr ""
@ -554,27 +556,27 @@ msgid "Twitter"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:57
#: lib/block_scout_web/templates/chain/show.html.eex:55
msgid "View All Blocks →"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:74
#: lib/block_scout_web/templates/chain/show.html.eex:72
msgid "View All Transactions →"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:28
#: lib/block_scout_web/templates/chain/show.html.eex:26
msgid "Average block time"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:36
#: lib/block_scout_web/templates/chain/show.html.eex:34
msgid "Total transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:44
#: lib/block_scout_web/templates/chain/show.html.eex:42
msgid "Wallet addresses"
msgstr ""
@ -586,7 +588,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:8
#: lib/block_scout_web/templates/address_contract/index.html.eex:73
#: lib/block_scout_web/templates/address_contract/index.html.eex:75
msgid "Copy Address"
msgstr ""
@ -599,17 +601,17 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:13
#: lib/block_scout_web/templates/address/overview.html.eex:66
#: lib/block_scout_web/templates/address/overview.html.eex:64
msgid "QR Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:126
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:124
msgid "There are no internal transactions for this address."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_transaction/index.html.eex:139
#: lib/block_scout_web/templates/address_transaction/index.html.eex:137
#: lib/block_scout_web/templates/block_transaction/index.html.eex:44
msgid "There are no transactions for this address."
msgstr ""
@ -621,7 +623,7 @@ msgid "Contract Address Pending"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:123
#: lib/block_scout_web/views/transaction_view.ex:119
msgid "Contract Call"
msgstr ""
@ -631,12 +633,12 @@ msgid "Contract created by"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:36
#: lib/block_scout_web/templates/address/overview.html.eex:35
msgid "at"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/token/_token_transfer.html.eex:38
#: lib/block_scout_web/templates/tokens/token/_token_transfer.html.eex:36
#: lib/block_scout_web/templates/transaction/_tile.html.eex:34
msgid "Block #%{number}"
msgstr ""
@ -693,7 +695,7 @@ msgid "Block Height #%{height}"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:75
#: lib/block_scout_web/templates/address/overview.html.eex:73
msgid "Close"
msgstr ""
@ -708,7 +710,7 @@ msgid "Block Confirmations"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:105
#: lib/block_scout_web/templates/transaction/overview.html.eex:107
msgid "Limit"
msgstr ""
@ -724,14 +726,14 @@ msgid "There are no logs for this transaction."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:98
#: lib/block_scout_web/templates/transaction/overview.html.eex:100
msgid "Used"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/token/_token_transfer.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:121
#: lib/block_scout_web/views/transaction_view.ex:117
msgid "Token Transfer"
msgstr ""
@ -749,7 +751,7 @@ msgstr[1] ""
#, elixir-format
#: lib/block_scout_web/templates/address_transaction/index.html.eex:84
#: lib/block_scout_web/templates/chain/show.html.eex:71
#: lib/block_scout_web/templates/chain/show.html.eex:69
#: lib/block_scout_web/templates/transaction/index.html.eex:48
msgid "More transactions have come in"
msgstr ""
@ -831,22 +833,15 @@ msgstr[0] ""
msgstr[1] ""
#, elixir-format
#: lib/block_scout_web/templates/address/_balance_card.html.eex:16
#: lib/block_scout_web/templates/address/_token_holdings.html.eex:16
#: lib/block_scout_web/templates/address/_balance_card.html.eex:19
msgid "Error tryng to fetch balances."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_balance_card.html.eex:12
#: lib/block_scout_web/templates/address/_token_holdings.html.eex:12
#: lib/block_scout_web/templates/address/_balance_card.html.eex:15
msgid "Fetching tokens..."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_token_holdings.html.eex:3
msgid "Token Holdings"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:38
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:53
@ -1005,3 +1000,13 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tile.html.eex:68
msgid "View Less Transfers"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:23
msgid "Less than"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:42
msgid "Max of"
msgstr ""

@ -18,7 +18,7 @@ msgstr "Age"
msgid "Block"
msgstr "Block"
#: lib/block_scout_web/templates/chain/show.html.eex:58
#: lib/block_scout_web/templates/chain/show.html.eex:56
#: lib/block_scout_web/templates/layout/_topnav.html.eex:13
msgid "Blocks"
msgstr "Blocks"
@ -51,18 +51,18 @@ msgstr "BlockScout"
#: lib/block_scout_web/templates/address_read_contract/index.html.eex:10
#: lib/block_scout_web/templates/address_transaction/index.html.eex:13
#: lib/block_scout_web/templates/address_transaction/index.html.eex:55
#: lib/block_scout_web/templates/address_transaction/index.html.eex:131
#: lib/block_scout_web/templates/address_transaction/index.html.eex:129
#: lib/block_scout_web/templates/block_transaction/index.html.eex:13
#: lib/block_scout_web/templates/block_transaction/index.html.eex:26
#: lib/block_scout_web/templates/block_transaction/index.html.eex:36
#: lib/block_scout_web/templates/chain/show.html.eex:75
#: lib/block_scout_web/templates/chain/show.html.eex:73
#: lib/block_scout_web/templates/layout/_topnav.html.eex:18
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:46
#: lib/block_scout_web/templates/transaction/index.html.eex:56
msgid "Transactions"
msgstr "Transactions"
#: lib/block_scout_web/templates/transaction/overview.html.eex:82
#: lib/block_scout_web/templates/transaction/overview.html.eex:84
msgid "Value"
msgstr "Value"
@ -122,7 +122,7 @@ msgstr "Transaction Details"
msgid "Cumulative Gas Used"
msgstr "Cumulative Gas Used"
#: lib/block_scout_web/templates/transaction/overview.html.eex:93
#: lib/block_scout_web/templates/transaction/overview.html.eex:95
msgid "Gas"
msgstr "Gas"
@ -130,7 +130,7 @@ msgstr "Gas"
msgid "Gas Price"
msgstr "Gas Price"
#: lib/block_scout_web/templates/transaction/overview.html.eex:63
#: lib/block_scout_web/templates/transaction/overview.html.eex:65
msgid "Input"
msgstr "Input"
@ -142,12 +142,12 @@ msgstr "%{confirmations} block confirmations"
msgid "%{count} transactions in this block"
msgstr "%{count} transactions in this block"
#: lib/block_scout_web/views/address_view.ex:15
#: lib/block_scout_web/views/address_view.ex:12
msgid "Address"
msgstr "Address"
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:106
#: lib/block_scout_web/templates/address_transaction/index.html.eex:117
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:105
#: lib/block_scout_web/templates/address_transaction/index.html.eex:116
#: lib/block_scout_web/views/address_internal_transaction_view.ex:10
#: lib/block_scout_web/views/address_transaction_view.ex:10
msgid "From"
@ -158,7 +158,7 @@ msgstr "From"
msgid "Overview"
msgstr "Overview"
#: lib/block_scout_web/views/transaction_view.ex:79
#: lib/block_scout_web/views/transaction_view.ex:81
msgid "Success"
msgstr "Success"
@ -210,8 +210,8 @@ msgstr "Showing %{count} Transactions"
#: lib/block_scout_web/templates/transaction/index.html.eex:16
#: lib/block_scout_web/templates/transaction/index.html.eex:35
#: lib/block_scout_web/templates/transaction/overview.html.eex:40
#: lib/block_scout_web/views/transaction_view.ex:44
#: lib/block_scout_web/views/transaction_view.ex:78
#: lib/block_scout_web/views/transaction_view.ex:46
#: lib/block_scout_web/views/transaction_view.ex:80
msgid "Pending"
msgstr "Pending"
@ -279,11 +279,11 @@ msgstr ""
msgid "Next Page"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:76
#: lib/block_scout_web/views/transaction_view.ex:78
msgid "Failed"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:77
#: lib/block_scout_web/views/transaction_view.ex:79
msgid "Out of Gas"
msgstr ""
@ -303,7 +303,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/_internal_transaction.html.eex:22
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:68
#: lib/block_scout_web/templates/transaction/_tile.html.eex:24
#: lib/block_scout_web/templates/transaction/overview.html.eex:82
#: lib/block_scout_web/templates/transaction/overview.html.eex:84
#: lib/block_scout_web/templates/transaction_internal_transaction/_internal_transaction.html.eex:16
#: lib/block_scout_web/views/wei_helpers.ex:72
msgid "Ether"
@ -317,7 +317,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_contract/index.html.eex:17
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:20
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:119
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:117
#: lib/block_scout_web/templates/address_read_contract/index.html.eex:17
#: lib/block_scout_web/templates/address_transaction/index.html.eex:20
#: lib/block_scout_web/templates/address_transaction/index.html.eex:60
@ -403,11 +403,13 @@ msgstr ""
msgid "Avg Block Time"
msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:18
#: lib/block_scout_web/templates/chain/show.html.eex:17
#: lib/block_scout_web/templates/layout/app.html.eex:24
msgid "Market Cap"
msgstr ""
#: lib/block_scout_web/templates/chain/show.html.eex:10
#: lib/block_scout_web/templates/layout/app.html.eex:25
msgid "Price"
msgstr ""
@ -451,7 +453,7 @@ msgstr ""
msgid "Total Gas Used"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:124
#: lib/block_scout_web/views/transaction_view.ex:120
msgid "Transaction"
msgstr ""
@ -474,7 +476,7 @@ msgstr ""
msgid "Contract"
msgstr ""
#: lib/block_scout_web/views/address_view.ex:13
#: lib/block_scout_web/views/address_view.ex:10
msgid "Contract Address"
msgstr ""
@ -486,8 +488,8 @@ msgstr ""
msgid "There are no Transactions"
msgstr ""
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:132
#: lib/block_scout_web/templates/address_transaction/index.html.eex:145
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:130
#: lib/block_scout_web/templates/address_transaction/index.html.eex:143
#: lib/block_scout_web/templates/block/index.html.eex:15
#: lib/block_scout_web/templates/block_transaction/index.html.eex:50
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:78
@ -536,7 +538,7 @@ msgid "Newer"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:122
#: lib/block_scout_web/views/transaction_view.ex:118
msgid "Contract Creation"
msgstr ""
@ -566,27 +568,27 @@ msgid "Twitter"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:57
#: lib/block_scout_web/templates/chain/show.html.eex:55
msgid "View All Blocks →"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:74
#: lib/block_scout_web/templates/chain/show.html.eex:72
msgid "View All Transactions →"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:28
#: lib/block_scout_web/templates/chain/show.html.eex:26
msgid "Average block time"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:36
#: lib/block_scout_web/templates/chain/show.html.eex:34
msgid "Total transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:44
#: lib/block_scout_web/templates/chain/show.html.eex:42
msgid "Wallet addresses"
msgstr ""
@ -598,7 +600,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:8
#: lib/block_scout_web/templates/address_contract/index.html.eex:73
#: lib/block_scout_web/templates/address_contract/index.html.eex:75
msgid "Copy Address"
msgstr ""
@ -611,17 +613,17 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:13
#: lib/block_scout_web/templates/address/overview.html.eex:66
#: lib/block_scout_web/templates/address/overview.html.eex:64
msgid "QR Code"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:126
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:124
msgid "There are no internal transactions for this address."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_transaction/index.html.eex:139
#: lib/block_scout_web/templates/address_transaction/index.html.eex:137
#: lib/block_scout_web/templates/block_transaction/index.html.eex:44
msgid "There are no transactions for this address."
msgstr ""
@ -633,7 +635,7 @@ msgid "Contract Address Pending"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:123
#: lib/block_scout_web/views/transaction_view.ex:119
msgid "Contract Call"
msgstr ""
@ -643,12 +645,12 @@ msgid "Contract created by"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:36
#: lib/block_scout_web/templates/address/overview.html.eex:35
msgid "at"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/token/_token_transfer.html.eex:38
#: lib/block_scout_web/templates/tokens/token/_token_transfer.html.eex:36
#: lib/block_scout_web/templates/transaction/_tile.html.eex:34
msgid "Block #%{number}"
msgstr ""
@ -705,7 +707,7 @@ msgid "Block Height #%{height}"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:75
#: lib/block_scout_web/templates/address/overview.html.eex:73
msgid "Close"
msgstr ""
@ -720,7 +722,7 @@ msgid "Block Confirmations"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:105
#: lib/block_scout_web/templates/transaction/overview.html.eex:107
msgid "Limit"
msgstr ""
@ -736,14 +738,14 @@ msgid "There are no logs for this transaction."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:98
#: lib/block_scout_web/templates/transaction/overview.html.eex:100
msgid "Used"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/token/_token_transfer.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:121
#: lib/block_scout_web/views/transaction_view.ex:117
msgid "Token Transfer"
msgstr ""
@ -761,7 +763,7 @@ msgstr[1] ""
#, elixir-format
#: lib/block_scout_web/templates/address_transaction/index.html.eex:84
#: lib/block_scout_web/templates/chain/show.html.eex:71
#: lib/block_scout_web/templates/chain/show.html.eex:69
#: lib/block_scout_web/templates/transaction/index.html.eex:48
msgid "More transactions have come in"
msgstr ""
@ -843,22 +845,15 @@ msgstr[0] ""
msgstr[1] ""
#, elixir-format
#: lib/block_scout_web/templates/address/_balance_card.html.eex:16
#: lib/block_scout_web/templates/address/_token_holdings.html.eex:16
#: lib/block_scout_web/templates/address/_balance_card.html.eex:19
msgid "Error tryng to fetch balances."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_balance_card.html.eex:12
#: lib/block_scout_web/templates/address/_token_holdings.html.eex:12
#: lib/block_scout_web/templates/address/_balance_card.html.eex:15
msgid "Fetching tokens..."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_token_holdings.html.eex:3
msgid "Token Holdings"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:38
#: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:53
@ -1017,3 +1012,13 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tile.html.eex:68
msgid "View Less Transfers"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/app.html.eex:23
msgid "Less than"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:42
msgid "Max of"
msgstr ""

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.AddressContractControllerTest do
use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [address_contract_path: 4]
import BlockScoutWeb.Router.Helpers, only: [address_contract_path: 3]
alias Explorer.Factory
alias Explorer.Chain.Hash
@ -11,7 +11,7 @@ defmodule BlockScoutWeb.AddressContractControllerTest do
test "returns not found for unexistent address", %{conn: conn} do
unexistent_address_hash = Hash.to_string(Factory.address_hash())
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, :en, unexistent_address_hash))
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, unexistent_address_hash))
assert html_response(conn, 404)
end
@ -19,7 +19,7 @@ defmodule BlockScoutWeb.AddressContractControllerTest do
test "returns not found given an invalid address hash ", %{conn: conn} do
invalid_hash = "invalid_hash"
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, :en, invalid_hash))
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, invalid_hash))
assert html_response(conn, 404)
end
@ -27,7 +27,7 @@ defmodule BlockScoutWeb.AddressContractControllerTest do
test "returns not found when the address isn't a contract", %{conn: conn} do
address = insert(:address)
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, :en, address))
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, address))
assert html_response(conn, 404)
end
@ -44,7 +44,7 @@ defmodule BlockScoutWeb.AddressContractControllerTest do
created_contract_address: address
)
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, :en, address))
conn = get(conn, address_contract_path(BlockScoutWeb.Endpoint, :index, address))
assert html_response(conn, 200)
assert address.hash == conn.assigns.address.hash

@ -2,12 +2,12 @@ defmodule BlockScoutWeb.AddressControllerTest do
use BlockScoutWeb.ConnCase
describe "GET show/3" do
test "redirects to addresses/:address_id/transactions", %{conn: conn} do
test "redirects to address/:address_id/transactions", %{conn: conn} do
insert(:address, hash: "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed")
conn = get(conn, "/en/addresses/0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed")
conn = get(conn, "/address/0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed")
assert redirected_to(conn) =~ "/en/addresses/0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed/transactions"
assert redirected_to(conn) =~ "/en/address/0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed/transactions"
end
end
end

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do
use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [address_internal_transaction_path: 4]
import BlockScoutWeb.Router.Helpers, only: [address_internal_transaction_path: 3]
alias Explorer.Chain.{Block, InternalTransaction, Transaction}
alias Explorer.ExchangeRates.Token
@ -10,14 +10,13 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do
test "with invalid address hash", %{conn: conn} do
conn =
conn
|> get(address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, "invalid_address"))
|> get(address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, "invalid_address"))
assert html_response(conn, 404)
end
test "with valid address hash without address", %{conn: conn} do
conn =
get(conn, address_internal_transaction_path(conn, :index, :en, "0x8bf38d4764929064f2d4d3a56520a76ab3df415b"))
conn = get(conn, address_internal_transaction_path(conn, :index, "0x8bf38d4764929064f2d4d3a56520a76ab3df415b"))
assert html_response(conn, 404)
end
@ -35,7 +34,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do
to_internal_transaction = insert(:internal_transaction, transaction: transaction, to_address: address, index: 2)
path = address_internal_transaction_path(conn, :index, :en, address)
path = address_internal_transaction_path(conn, :index, address)
conn = get(conn, path)
actual_transaction_ids =
@ -49,7 +48,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do
test "includes USD exchange rate value for address in assigns", %{conn: conn} do
address = insert(:address)
conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address.hash))
conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash))
assert %Token{} = conn.assigns.exchange_rate
end
@ -118,7 +117,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do
|> insert(transaction: transaction_3, from_address: address, index: 11)
conn =
get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address.hash), %{
get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{
"block_number" => Integer.to_string(b_block.number),
"transaction_index" => Integer.to_string(transaction_3.index),
"index" => Integer.to_string(index)
@ -152,7 +151,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do
)
end)
conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address.hash))
conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash))
assert %{"block_number" => ^number, "index" => 11, "transaction_index" => ^transaction_index} =
conn.assigns.next_page_params
@ -176,7 +175,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionControllerTest do
)
end)
conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address.hash))
conn = get(conn, address_internal_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash))
refute conn.assigns.next_page_params
end

@ -5,7 +5,7 @@ defmodule BlockScoutWeb.AddressReadContractControllerTest do
describe "GET index/3" do
test "with invalid address hash", %{conn: conn} do
conn = get(conn, address_read_contract_path(BlockScoutWeb.Endpoint, :index, :en, "invalid_address"))
conn = get(conn, address_read_contract_path(BlockScoutWeb.Endpoint, :index, "invalid_address"))
assert html_response(conn, 404)
end
@ -13,7 +13,7 @@ defmodule BlockScoutWeb.AddressReadContractControllerTest do
test "with valid address that is not a contract", %{conn: conn} do
address = insert(:address)
conn = get(conn, address_read_contract_path(BlockScoutWeb.Endpoint, :index, :en, address.hash))
conn = get(conn, address_read_contract_path(BlockScoutWeb.Endpoint, :index, address.hash))
assert html_response(conn, 404)
end
@ -32,7 +32,7 @@ defmodule BlockScoutWeb.AddressReadContractControllerTest do
insert(:smart_contract, address_hash: contract_address.hash)
conn = get(conn, address_read_contract_path(BlockScoutWeb.Endpoint, :index, :en, contract_address.hash))
conn = get(conn, address_read_contract_path(BlockScoutWeb.Endpoint, :index, contract_address.hash))
assert html_response(conn, 200)
assert contract_address.hash == conn.assigns.address.hash

@ -0,0 +1,46 @@
defmodule BlockScoutWeb.AddressTokenBalanceControllerTest do
use BlockScoutWeb.ConnCase
alias Explorer.Chain.Address
alias Explorer.Factory
describe "GET index/3" do
test "without AJAX", %{conn: conn} do
%Address{hash: hash} = Factory.insert(:address)
response_conn = get(conn, address_token_balance_path(conn, :index, :en, to_string(hash)))
assert html_response(response_conn, 404)
end
test "with AJAX without valid address", %{conn: conn} do
ajax_conn = ajax(conn)
response_conn = get(ajax_conn, address_token_balance_path(ajax_conn, :index, :en, "invalid_address"))
assert html_response(response_conn, 404)
end
test "with AJAX with valid address without address still returns token balances", %{conn: conn} do
ajax_conn = ajax(conn)
response_conn = get(ajax_conn, address_token_balance_path(ajax_conn, :index, :en, Factory.address_hash()))
assert html_response(response_conn, 200)
end
test "with AJAX with valid address with address returns token balances", %{conn: conn} do
%Address{hash: hash} = Factory.insert(:address)
ajax_conn = ajax(conn)
response_conn = get(ajax_conn, address_token_balance_path(ajax_conn, :index, :en, hash))
assert html_response(response_conn, 200)
end
end
defp ajax(conn) do
put_req_header(conn, "x-requested-with", "XMLHttpRequest")
end
end

@ -1,20 +1,20 @@
defmodule BlockScoutWeb.AddressTransactionControllerTest do
use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [address_transaction_path: 4]
import BlockScoutWeb.Router.Helpers, only: [address_transaction_path: 3]
alias Explorer.Chain.{Block, Transaction}
alias Explorer.ExchangeRates.Token
describe "GET index/2" do
test "with invalid address hash", %{conn: conn} do
conn = get(conn, address_transaction_path(conn, :index, :en, "invalid_address"))
conn = get(conn, address_transaction_path(conn, :index, "invalid_address"))
assert html_response(conn, 422)
end
test "with valid address hash without address", %{conn: conn} do
conn = get(conn, address_transaction_path(conn, :index, :en, "0x8bf38d4764929064f2d4d3a56520a76ab3df415b"))
conn = get(conn, address_transaction_path(conn, :index, "0x8bf38d4764929064f2d4d3a56520a76ab3df415b"))
assert html_response(conn, 404)
end
@ -34,7 +34,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
|> insert(to_address: address)
|> with_block(block)
conn = get(conn, address_transaction_path(conn, :index, :en, address))
conn = get(conn, address_transaction_path(conn, :index, address))
actual_transaction_hashes =
conn.assigns.transactions
@ -50,7 +50,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
insert(:transaction, from_address: address, to_address: address)
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address))
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address))
assert html_response(conn, 200)
assert conn.status == 200
@ -62,7 +62,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
test "includes USD exchange rate value for address in assigns", %{conn: conn} do
address = insert(:address)
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address.hash))
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash))
assert %Token{} = conn.assigns.exchange_rate
end
@ -82,7 +82,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
|> with_block()
conn =
get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address.hash), %{
get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{
"block_number" => Integer.to_string(block_number),
"index" => Integer.to_string(index)
})
@ -103,7 +103,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
|> insert_list(:transaction, from_address: address)
|> with_block(block)
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address.hash))
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash))
assert %{"block_number" => ^number, "index" => 10} = conn.assigns.next_page_params
end
@ -115,7 +115,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
|> insert(from_address: address)
|> with_block()
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, :en, address.hash))
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash))
refute conn.assigns.next_page_params
end
@ -138,7 +138,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
transaction: transaction
)
conn = get(conn, address_transaction_path(conn, :index, :en, address))
conn = get(conn, address_transaction_path(conn, :index, address))
assert [transaction] == conn.assigns.transactions
end

@ -1,11 +1,11 @@
defmodule BlockScoutWeb.APIDocsControllerTest do
use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [api_docs_path: 3]
import BlockScoutWeb.Router.Helpers, only: [api_docs_path: 2]
describe "GET index/2" do
test "renders documentation tiles for each API module#action", %{conn: conn} do
conn = get(conn, api_docs_path(BlockScoutWeb.Endpoint, :index, :en))
conn = get(conn, api_docs_path(BlockScoutWeb.Endpoint, :index))
documentation = BlockScoutWeb.Etherscan.get_documentation()

@ -2,13 +2,11 @@ defmodule BlockScoutWeb.BlockControllerTest do
use BlockScoutWeb.ConnCase
alias Explorer.Chain.Block
@locale "en"
describe "GET show/2" do
test "with block redirects to block transactions route", %{conn: conn} do
insert(:block, number: 3)
conn = get(conn, "/en/blocks/3")
assert redirected_to(conn) =~ "/en/blocks/3/transactions"
conn = get(conn, "/blocks/3")
assert redirected_to(conn) =~ "/blocks/3/transactions"
end
end
@ -20,7 +18,7 @@ defmodule BlockScoutWeb.BlockControllerTest do
|> Stream.map(fn block -> block.number end)
|> Enum.reverse()
conn = get(conn, block_path(conn, :index, @locale))
conn = get(conn, block_path(conn, :index))
assert conn.assigns.blocks |> Enum.map(fn block -> block.number end) == block_ids
end
@ -32,7 +30,7 @@ defmodule BlockScoutWeb.BlockControllerTest do
|> insert_list(:transaction)
|> with_block(block)
conn = get(conn, block_path(conn, :index, @locale))
conn = get(conn, block_path(conn, :index))
assert conn.assigns.blocks |> Enum.count() == 1
end
@ -46,7 +44,7 @@ defmodule BlockScoutWeb.BlockControllerTest do
block = insert(:block)
conn =
get(conn, block_path(conn, :index, @locale), %{
get(conn, block_path(conn, :index), %{
"block_number" => Integer.to_string(block.number)
})
@ -64,7 +62,7 @@ defmodule BlockScoutWeb.BlockControllerTest do
|> insert_list(:block)
|> Enum.fetch!(10)
conn = get(conn, block_path(conn, :index, @locale))
conn = get(conn, block_path(conn, :index))
assert %{"block_number" => ^number} = conn.assigns.next_page_params
end
@ -72,7 +70,7 @@ defmodule BlockScoutWeb.BlockControllerTest do
test "next_page_params are empty if on last page", %{conn: conn} do
insert(:block)
conn = get(conn, block_path(conn, :index, @locale))
conn = get(conn, block_path(conn, :index))
refute conn.assigns.next_page_params
end

@ -2,17 +2,17 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do
use BlockScoutWeb.ConnCase
alias Explorer.Chain.Block
import BlockScoutWeb.Router.Helpers, only: [block_transaction_path: 4]
import BlockScoutWeb.Router.Helpers, only: [block_transaction_path: 3]
describe "GET index/2" do
test "with invalid block number", %{conn: conn} do
conn = get(conn, block_transaction_path(conn, :index, :en, "unknown"))
conn = get(conn, block_transaction_path(conn, :index, "unknown"))
assert html_response(conn, 404)
end
test "with valid block number without block", %{conn: conn} do
conn = get(conn, block_transaction_path(conn, :index, :en, "1"))
conn = get(conn, block_transaction_path(conn, :index, "1"))
assert html_response(conn, 404)
end
@ -23,7 +23,7 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do
:transaction |> insert() |> with_block(block)
:transaction |> insert(to_address: nil) |> with_block(block)
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, :en, block.number))
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block.number))
assert html_response(conn, 200)
assert 2 == Enum.count(conn.assigns.transactions)
@ -33,7 +33,7 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do
insert(:transaction)
block = insert(:block)
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, :en, block))
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block))
assert html_response(conn, 200)
assert Enum.empty?(conn.assigns.transactions)
@ -43,7 +43,7 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do
block = insert(:block)
insert(:transaction)
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, :en, block))
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block))
assert html_response(conn, 200)
assert Enum.empty?(conn.assigns.transactions)
@ -56,7 +56,7 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do
|> insert_list(:transaction)
|> with_block(block)
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, :en, block))
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block))
assert %{"block_number" => ^number, "index" => 10} = conn.assigns.next_page_params
end
@ -68,7 +68,7 @@ defmodule BlockScoutWeb.BlockTransactionControllerTest do
|> insert()
|> with_block(block)
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, :en, block))
conn = get(conn, block_transaction_path(BlockScoutWeb.Endpoint, :index, block))
refute conn.assigns.next_page_params
end

@ -1,26 +1,18 @@
defmodule BlockScoutWeb.ChainControllerTest do
use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [chain_path: 3, block_path: 4, transaction_path: 4, address_path: 4]
import BlockScoutWeb.Router.Helpers, only: [chain_path: 2, block_path: 3, transaction_path: 3, address_path: 3]
describe "GET index/2 without a locale" do
test "redirects to the en locale", %{conn: conn} do
conn = get(conn, "/")
assert(redirected_to(conn) == "/en")
end
end
describe "GET index/2 with a locale" do
describe "GET index/2" do
test "returns a welcome message", %{conn: conn} do
conn = get(conn, chain_path(BlockScoutWeb.Endpoint, :show, %{locale: :en}))
conn = get(conn, chain_path(BlockScoutWeb.Endpoint, :show))
assert(html_response(conn, 200) =~ "POA")
end
test "returns a block", %{conn: conn} do
insert(:block, %{number: 23})
conn = get(conn, "/en")
conn = get(conn, "/")
assert(List.first(conn.assigns.blocks).number == 23)
end
@ -28,7 +20,7 @@ defmodule BlockScoutWeb.ChainControllerTest do
test "excludes all but the most recent five blocks", %{conn: conn} do
old_block = insert(:block)
insert_list(5, :block)
conn = get(conn, "/en")
conn = get(conn, "/")
refute(Enum.member?(conn.assigns.blocks, old_block))
end
@ -41,7 +33,7 @@ defmodule BlockScoutWeb.ChainControllerTest do
unassociated = insert(:transaction)
conn = get(conn, "/en")
conn = get(conn, "/")
transaction_hashes = Enum.map(conn.assigns.transactions, fn transaction -> transaction.hash end)
@ -55,7 +47,7 @@ defmodule BlockScoutWeb.ChainControllerTest do
|> insert()
|> with_block()
conn = get(conn, "/en")
conn = get(conn, "/")
assert(List.first(conn.assigns.transactions).hash == transaction.hash)
end
@ -64,7 +56,7 @@ defmodule BlockScoutWeb.ChainControllerTest do
today = Date.utc_today()
for day <- -40..0, do: insert(:market_history, date: Date.add(today, day))
conn = get(conn, "/en")
conn = get(conn, "/")
assert Map.has_key?(conn.assigns, :market_history_data)
assert length(conn.assigns.market_history_data) == 30
@ -74,9 +66,9 @@ defmodule BlockScoutWeb.ChainControllerTest do
describe "GET q/2" do
test "finds a block by block number", %{conn: conn} do
insert(:block, number: 37)
conn = get(conn, "/en/search?q=37")
conn = get(conn, "/search?q=37")
assert redirected_to(conn) == block_path(conn, :show, "en", "37")
assert redirected_to(conn) == block_path(conn, :show, "37")
end
test "finds a transaction by hash", %{conn: conn} do
@ -85,27 +77,27 @@ defmodule BlockScoutWeb.ChainControllerTest do
|> insert()
|> with_block()
conn = get(conn, "/en/search?q=#{to_string(transaction.hash)}")
conn = get(conn, "/search?q=#{to_string(transaction.hash)}")
assert redirected_to(conn) == transaction_path(conn, :show, "en", transaction)
assert redirected_to(conn) == transaction_path(conn, :show, transaction)
end
test "finds an address by hash", %{conn: conn} do
address = insert(:address)
conn = get(conn, "en/search?q=#{to_string(address.hash)}")
conn = get(conn, "search?q=#{to_string(address.hash)}")
assert redirected_to(conn) == address_path(conn, :show, "en", address)
assert redirected_to(conn) == address_path(conn, :show, address)
end
test "finds an address by hash when there are extra spaces", %{conn: conn} do
address = insert(:address)
conn = get(conn, "en/search?q=#{to_string(address.hash)} ")
conn = get(conn, "search?q=#{to_string(address.hash)}")
assert redirected_to(conn) == address_path(conn, :show, "en", address)
assert redirected_to(conn) == address_path(conn, :show, address)
end
test "redirects to 404 when it finds nothing", %{conn: conn} do
conn = get(conn, "en/search?q=zaphod")
conn = get(conn, "search?q=zaphod")
assert conn.status == 404
end
end

@ -2,7 +2,7 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
use BlockScoutWeb.ConnCase
alias Explorer.Chain.{Hash, Transaction}
import BlockScoutWeb.Router.Helpers, only: [pending_transaction_path: 3]
import BlockScoutWeb.Router.Helpers, only: [pending_transaction_path: 2]
describe "GET index/2" do
test "returns no transactions that are in a block", %{conn: conn} do
@ -10,7 +10,7 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
|> insert()
|> with_block()
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index, :en))
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index))
assert html_response(conn, 200)
assert Enum.empty?(conn.assigns.transactions)
@ -21,7 +21,7 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
|> insert()
|> with_block()
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index, :en))
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index))
assert html_response(conn, 200)
assert Enum.empty?(conn.assigns.transactions)
@ -30,7 +30,7 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
test "returns pending transactions", %{conn: conn} do
transaction = insert(:transaction)
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index, :en))
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index))
actual_transaction_hashes =
conn.assigns.transactions
@ -43,14 +43,14 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
test "returns a count of pending transactions", %{conn: conn} do
insert(:transaction)
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index, :en))
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, :en))
conn = get(conn, pending_transaction_path(conn, :index))
assert html_response(conn, 200)
end
@ -64,7 +64,7 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
%Transaction{inserted_at: inserted_at, hash: hash} = insert(:transaction)
conn =
get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index, :en), %{
get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index), %{
"inserted_at" => DateTime.to_iso8601(inserted_at),
"hash" => Hash.to_string(hash)
})
@ -85,7 +85,7 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
converted_date = DateTime.to_iso8601(inserted_at)
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index, :en))
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index))
assert %{"inserted_at" => ^converted_date, "hash" => ^hash} = conn.assigns.next_page_params
end
@ -93,7 +93,7 @@ defmodule BlockScoutWeb.PendingTransactionControllerTest do
test "next_page_params are empty if on last page", %{conn: conn} do
insert(:transaction)
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index, :en))
conn = get(conn, pending_transaction_path(BlockScoutWeb.Endpoint, :index))
refute conn.assigns.next_page_params
end

@ -9,7 +9,7 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
test "only responds to ajax requests", %{conn: conn} do
smart_contract = insert(:smart_contract)
path = smart_contract_path(BlockScoutWeb.Endpoint, :index, :en, hash: smart_contract.address_hash)
path = smart_contract_path(BlockScoutWeb.Endpoint, :index, hash: smart_contract.address_hash)
conn = get(conn, path)
@ -23,7 +23,7 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
blockchain_get_function_mock()
path = smart_contract_path(BlockScoutWeb.Endpoint, :index, :en, hash: token_contract_address.hash)
path = smart_contract_path(BlockScoutWeb.Endpoint, :index, hash: token_contract_address.hash)
conn =
build_conn()
@ -43,7 +43,6 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
smart_contract_path(
BlockScoutWeb.Endpoint,
:show,
:en,
smart_contract.address_hash,
function_name: "get",
args: []
@ -63,7 +62,6 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
smart_contract_path(
BlockScoutWeb.Endpoint,
:show,
:en,
smart_contract.address_hash,
function_name: "get",
args: []
@ -79,7 +77,6 @@ defmodule BlockScoutWeb.SmartContractControllerTest do
assert %{
function_name: "get",
layout: false,
locale: "en",
outputs: [%{"name" => "", "type" => "uint256", "value" => 0}]
} = conn.assigns
end

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.Tokens.ReadContractControllerTest do
describe "GET index/3" do
test "with invalid address hash", %{conn: conn} do
conn = get(conn, token_read_contract_path(BlockScoutWeb.Endpoint, :index, :en, "invalid_address"))
conn = get(conn, token_read_contract_path(BlockScoutWeb.Endpoint, :index, "invalid_address"))
assert html_response(conn, 404)
end
@ -26,7 +26,7 @@ defmodule BlockScoutWeb.Tokens.ReadContractControllerTest do
token: token
)
conn = get(conn, token_read_contract_path(BlockScoutWeb.Endpoint, :index, :en, token.contract_address_hash))
conn = get(conn, token_read_contract_path(BlockScoutWeb.Endpoint, :index, token.contract_address_hash))
assert html_response(conn, 200)
assert token.contract_address_hash == conn.assigns.token.contract_address_hash

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.TransactionControllerTest do
alias Explorer.Chain.{Block, Transaction}
import BlockScoutWeb.Router.Helpers,
only: [transaction_path: 4, transaction_internal_transaction_path: 4, transaction_token_transfer_path: 4]
only: [transaction_path: 3, transaction_internal_transaction_path: 3, transaction_token_transfer_path: 3]
describe "GET index/2" do
test "returns a collated transactions", %{conn: conn} do
@ -12,7 +12,7 @@ defmodule BlockScoutWeb.TransactionControllerTest do
|> insert()
|> with_block()
conn = get(conn, "/en/transactions")
conn = get(conn, "/txs")
assert List.first(conn.assigns.transactions).hash == transaction.hash
end
@ -22,7 +22,7 @@ defmodule BlockScoutWeb.TransactionControllerTest do
|> insert()
|> with_block()
conn = get(conn, "/en/transactions")
conn = get(conn, "/txs")
assert is_integer(conn.assigns.transaction_estimated_count)
end
@ -35,7 +35,7 @@ defmodule BlockScoutWeb.TransactionControllerTest do
insert(:transaction)
conn = get(conn, "/en/transactions")
conn = get(conn, "/txs")
assert [%Transaction{hash: ^hash}] = conn.assigns.transactions
end
@ -53,7 +53,7 @@ defmodule BlockScoutWeb.TransactionControllerTest do
|> with_block()
conn =
get(conn, "/en/transactions", %{
get(conn, "/txs", %{
"block_number" => Integer.to_string(block_number),
"index" => Integer.to_string(index)
})
@ -74,7 +74,7 @@ defmodule BlockScoutWeb.TransactionControllerTest do
|> insert_list(:transaction, from_address: address)
|> with_block(block)
conn = get(conn, "/en/transactions")
conn = get(conn, "/txs")
assert %{"block_number" => ^number, "index" => 10} = conn.assigns.next_page_params
end
@ -86,13 +86,13 @@ defmodule BlockScoutWeb.TransactionControllerTest do
|> insert(from_address: address)
|> with_block()
conn = get(conn, "/en/transactions")
conn = get(conn, "/txs")
refute conn.assigns.next_page_params
end
test "works when there are no transactions", %{conn: conn} do
conn = get(conn, "/en/transactions")
conn = get(conn, "/txs")
assert conn.assigns.transactions == []
end
@ -100,23 +100,20 @@ defmodule BlockScoutWeb.TransactionControllerTest do
describe "GET show/3" do
test "redirects to transactions/:transaction_id/token_transfers when there are token transfers", %{conn: conn} do
locale = "en"
transaction = insert(:transaction)
insert(:token_transfer, transaction: transaction)
conn = get(conn, transaction_path(BlockScoutWeb.Endpoint, :show, locale, transaction))
conn = get(conn, transaction_path(BlockScoutWeb.Endpoint, :show, transaction))
assert redirected_to(conn) =~ transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, locale, transaction)
assert redirected_to(conn) =~ transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction)
end
test "redirects to transactions/:transaction_id/internal_transactions when there are no token transfers", %{
conn: conn
} do
locale = "en"
transaction = insert(:transaction)
conn = get(conn, transaction_path(BlockScoutWeb.Endpoint, :show, locale, transaction))
conn = get(conn, transaction_path(BlockScoutWeb.Endpoint, :show, transaction))
assert redirected_to(conn) =~
transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, locale, transaction)
assert redirected_to(conn) =~ transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction)
end
end
end

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [transaction_internal_transaction_path: 4]
import BlockScoutWeb.Router.Helpers, only: [transaction_internal_transaction_path: 3]
alias Explorer.Chain.{Block, InternalTransaction, Transaction}
alias Explorer.ExchangeRates.Token
@ -9,13 +9,13 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
describe "GET index/3" do
test "with missing transaction", %{conn: conn} do
hash = transaction_hash()
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, hash))
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, hash))
assert html_response(conn, 404)
end
test "with invalid transaction hash", %{conn: conn} do
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, "nope"))
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, "nope"))
assert html_response(conn, 404)
end
@ -28,7 +28,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
|> insert()
|> with_block(block)
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert html_response(conn, 200)
assert conn.assigns.transaction.hash == transaction.hash
@ -39,7 +39,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
expected_internal_transaction = insert(:internal_transaction, transaction: transaction, index: 0)
insert(:internal_transaction, transaction: transaction, index: 1)
path = transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash)
path = transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash)
conn = get(conn, path)
@ -55,7 +55,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
test "includes USD exchange rate value for address in assigns", %{conn: conn} do
transaction = insert(:transaction)
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert %Token{} = conn.assigns.exchange_rate
end
@ -80,7 +80,6 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
transaction_internal_transaction_path(
BlockScoutWeb.Endpoint,
:index,
:en,
internal_transaction.transaction_hash
)
)
@ -102,7 +101,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
|> Enum.map(& &1.index)
conn =
get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash), %{
get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{
"index" => Integer.to_string(index)
})
@ -131,7 +130,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
)
end)
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert %{"block_number" => ^number, "index" => 50, "transaction_index" => ^transaction_index} =
conn.assigns.next_page_params
@ -152,7 +151,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionControllerTest do
)
end)
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_internal_transaction_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
refute conn.assigns.next_page_params
end

@ -1,13 +1,13 @@
defmodule BlockScoutWeb.TransactionLogControllerTest do
use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [transaction_log_path: 4]
import BlockScoutWeb.Router.Helpers, only: [transaction_log_path: 3]
alias Explorer.ExchangeRates.Token
describe "GET index/2" do
test "with invalid transaction hash", %{conn: conn} do
conn = get(conn, transaction_log_path(conn, :index, :en, "invalid_transaction_string"))
conn = get(conn, transaction_log_path(conn, :index, "invalid_transaction_string"))
assert html_response(conn, 404)
end
@ -16,7 +16,7 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do
conn =
get(
conn,
transaction_log_path(conn, :index, :en, "0x3a3eb134e6792ce9403ea4188e5e79693de9e4c94e499db132be086400da79e6")
transaction_log_path(conn, :index, "0x3a3eb134e6792ce9403ea4188e5e79693de9e4c94e499db132be086400da79e6")
)
assert html_response(conn, 404)
@ -31,7 +31,7 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do
address = insert(:address)
insert(:log, address: address, transaction: transaction)
conn = get(conn, transaction_log_path(conn, :index, :en, transaction))
conn = get(conn, transaction_log_path(conn, :index, transaction))
first_log = List.first(conn.assigns.logs)
@ -47,7 +47,7 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do
address = insert(:address)
insert(:log, address: address, transaction: transaction)
conn = get(conn, transaction_log_path(conn, :index, :en, transaction))
conn = get(conn, transaction_log_path(conn, :index, transaction))
first_log = List.first(conn.assigns.logs)
@ -56,7 +56,7 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do
test "assigns no logs when there are none", %{conn: conn} do
transaction = insert(:transaction)
path = transaction_log_path(conn, :index, :en, transaction)
path = transaction_log_path(conn, :index, transaction)
conn = get(conn, path)
@ -77,7 +77,7 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do
|> Enum.map(& &1.index)
conn =
get(conn, transaction_log_path(conn, :index, :en, transaction), %{
get(conn, transaction_log_path(conn, :index, transaction), %{
"index" => Integer.to_string(log.index)
})
@ -95,7 +95,7 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do
1..60
|> Enum.map(fn index -> insert(:log, transaction: transaction, index: index) end)
conn = get(conn, transaction_log_path(conn, :index, :en, transaction))
conn = get(conn, transaction_log_path(conn, :index, transaction))
assert %{"index" => 50} = conn.assigns.next_page_params
end
@ -106,7 +106,7 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do
|> insert()
|> with_block()
conn = get(conn, transaction_log_path(conn, :index, :en, transaction))
conn = get(conn, transaction_log_path(conn, :index, transaction))
refute conn.assigns.next_page_params
end
@ -115,7 +115,7 @@ defmodule BlockScoutWeb.TransactionLogControllerTest do
test "includes USD exchange rate value for address in assigns", %{conn: conn} do
transaction = insert(:transaction)
conn = get(conn, transaction_log_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_log_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert %Token{} = conn.assigns.exchange_rate
end

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do
use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [transaction_token_transfer_path: 4]
import BlockScoutWeb.Router.Helpers, only: [transaction_token_transfer_path: 3]
alias Explorer.ExchangeRates.Token
@ -10,20 +10,20 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do
transaction = insert(:transaction)
token_transfer = insert(:token_transfer, transaction: transaction)
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert List.first(conn.assigns.transaction.token_transfers).id == token_transfer.id
end
test "with missing transaction", %{conn: conn} do
hash = transaction_hash()
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, hash))
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, hash))
assert html_response(conn, 404)
end
test "with invalid transaction hash", %{conn: conn} do
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, "nope"))
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, "nope"))
assert html_response(conn, 404)
end
@ -36,7 +36,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do
|> insert()
|> with_block(block)
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert html_response(conn, 200)
assert conn.assigns.transaction.hash == transaction.hash
@ -49,7 +49,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do
insert(:token_transfer, transaction: transaction)
path = transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash)
path = transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash)
conn = get(conn, path)
@ -65,7 +65,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do
test "includes USD exchange rate value for address in assigns", %{conn: conn} do
transaction = insert(:transaction)
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert %Token{} = conn.assigns.exchange_rate
end
@ -86,7 +86,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do
end)
conn =
get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash), %{
get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash), %{
"inserted_at" => first_transfer_time |> DateTime.from_naive!("Etc/UTC") |> DateTime.to_iso8601()
})
@ -112,7 +112,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do
)
end)
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert Enum.any?(conn.assigns.next_page_params)
end
@ -132,7 +132,7 @@ defmodule BlockScoutWeb.TransactionTokenTransferControllerTest do
)
end)
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, :en, transaction.hash))
conn = get(conn, transaction_token_transfer_path(BlockScoutWeb.Endpoint, :index, transaction.hash))
assert is_nil(conn.assigns.next_page_params)
end

@ -1,48 +0,0 @@
defmodule BlockScoutWeb.ExchangeRates.USDTest do
use ExUnit.Case, async: true
alias BlockScoutWeb.ExchangeRates.USD
alias Explorer.ExchangeRates.Token
alias Explorer.Chain.Wei
describe "from/2" do
test "with nil wei returns null object" do
token = %Token{usd_value: Decimal.new(0.5)}
assert USD.null() == USD.from(nil, token)
end
test "with nil token returns nil" do
wei = %Wei{value: Decimal.new(10_000_000_000_000)}
assert USD.null() == USD.from(wei, nil)
end
test "without a wei value returns nil" do
wei = %Wei{value: nil}
token = %Token{usd_value: Decimal.new(0.5)}
assert USD.null() == USD.from(wei, token)
end
test "without an exchange rate returns nil" do
wei = %Wei{value: Decimal.new(10_000_000_000_000)}
token = %Token{usd_value: nil}
assert USD.null() == USD.from(wei, token)
end
test "returns formatted usd value" do
wei = %Wei{value: Decimal.new(10_000_000_000_000)}
token = %Token{usd_value: Decimal.new(0.5)}
assert %USD{value: Decimal.new(0.000005)} == USD.from(wei, token)
end
test "returns USD struct from decimal usd value" do
value = Decimal.new(0.000005)
assert %USD{value: ^value} = USD.from(value)
end
end
end

@ -1,11 +1,9 @@
defmodule BlockScoutWeb.AddressContractVerificationTest do
use BlockScoutWeb.FeatureCase, async: true
import Wallaby.Query
alias Plug.Conn
alias Explorer.Chain.Address
alias Explorer.Factory
alias BlockScoutWeb.{AddressContractPage, ContractVerifyPage}
setup do
bypass = Bypass.open()
@ -21,7 +19,7 @@ defmodule BlockScoutWeb.AddressContractVerificationTest do
%{name: name, source_code: source_code, bytecode: bytecode, version: version} = Factory.contract_code_info()
transaction = :transaction |> insert() |> with_block()
address = %Address{hash: address_hash} = insert(:address, contract_code: bytecode)
address = insert(:address, contract_code: bytecode)
insert(
:internal_transaction_create,
@ -32,33 +30,30 @@ defmodule BlockScoutWeb.AddressContractVerificationTest do
)
session
|> visit("/en/addresses/#{address_hash}/contract_verifications/new")
|> fill_in(text_field("Contract Name"), with: name)
|> click(option(version))
|> click(radio_button("No"))
|> fill_in(text_field("Enter the Solidity Contract Code below"), with: source_code)
|> click(button("Verify and publish"))
assert current_path(session) =~ ~r/\/en\/addresses\/#{address_hash}\/contracts/
|> AddressContractPage.visit_page(address)
|> AddressContractPage.click_verify_and_publish()
|> ContractVerifyPage.fill_form(%{
contract_name: name,
version: version,
optimization: false,
source_code: source_code
})
|> ContractVerifyPage.verify_and_publish()
assert AddressContractPage.on_page?(session, address)
end
test "with invalid data shows error messages", %{session: session, bypass: bypass} do
Bypass.expect(bypass, fn conn -> Conn.resp(conn, 200, solc_bin_versions()) end)
session
|> visit("/en/addresses/0x1e0eaa06d02f965be2dfe0bc9ff52b2d82133461/contract_verifications/new")
|> fill_in(text_field("Contract Name"), with: "")
|> fill_in(text_field("Enter the Solidity Contract Code below"), with: "")
|> click(button("Verify and publish"))
|> assert_has(
css(
"[data-test='contract-source-code-error']",
text: "there was an error validating your contract, please try again."
)
)
|> ContractVerifyPage.visit_page("0x1e0eaa06d02f965be2dfe0bc9ff52b2d82133461")
|> ContractVerifyPage.fill_form(%{contract_name: "", version: nil, optimization: nil, source_code: ""})
|> ContractVerifyPage.verify_and_publish()
|> assert_has(ContractVerifyPage.validation_error())
end
def solc_bin_versions() do
defp solc_bin_versions do
File.read!("./test/support/fixture/smart_contract/solc_bin.json")
end
end

@ -0,0 +1,23 @@
defmodule BlockScoutWeb.AddressContractPage do
@moduledoc false
use Wallaby.DSL
import Wallaby.Query, only: [css: 1]
def on_page?(session, address) do
current_path(session) =~ address_contract_path(address)
end
def click_verify_and_publish(session) do
click(session, css("[data-test='verify_and_publish']"))
end
def visit_page(session, address) do
visit(session, address_contract_path(address))
end
defp address_contract_path(address) do
"/en/address/#{address.hash}/contracts"
end
end

@ -74,7 +74,7 @@ defmodule BlockScoutWeb.AddressPage do
def visit_page(session, %Address{hash: address_hash}), do: visit_page(session, address_hash)
def visit_page(session, address_hash) do
visit(session, "/en/addresses/#{address_hash}")
visit(session, "/address/#{address_hash}")
end
def token_transfer(%Transaction{hash: transaction_hash}, %Address{hash: address_hash}, count: count) do

@ -8,7 +8,7 @@ defmodule BlockScoutWeb.BlockListPage do
alias Explorer.Chain.Block
def visit_page(session) do
visit(session, "/en/blocks")
visit(session, "/blocks")
end
def block(%Block{number: block_number}) do

@ -32,6 +32,6 @@ defmodule BlockScoutWeb.BlockPage do
end
def visit_page(session, %Block{number: block_number}) do
visit(session, "/en/blocks/#{block_number}/transactions")
visit(session, "/blocks/#{block_number}/transactions")
end
end

@ -6,7 +6,6 @@ defmodule BlockScoutWeb.ChainPage do
import Wallaby.Query, only: [css: 1, css: 2]
alias Explorer.Chain.Transaction
alias BlockScoutWeb.ChainView
def blocks(count: count) do
css("[data-selector='chain-block']", count: count)
@ -16,10 +15,6 @@ defmodule BlockScoutWeb.ChainPage do
css("[data-test='contract-creation'] [data-address-hash='#{hash}']")
end
def exchange_rate(token) do
css("[data-selector='exchange-rate']", text: ChainView.format_exchange_rate(token))
end
def non_loaded_transaction_count(count) do
css("[data-selector='channel-batching-count']", text: count)
end

@ -0,0 +1,51 @@
defmodule BlockScoutWeb.ContractVerifyPage do
@moduledoc false
use Wallaby.DSL
import Wallaby.Query
def visit_page(session, address_hash) do
visit(session, "/en/address/#{address_hash}/contract_verifications/new")
end
def fill_form(session, %{
contract_name: contract_name,
version: version,
optimization: optimization,
source_code: source_code
}) do
session
|> fill_in(css("[data-test='contract_name']"), with: contract_name)
|> fill_in(text_field("Enter the Solidity Contract Code below"), with: source_code)
case version do
nil -> nil
_ -> click(session, option(version))
end
case optimization do
true ->
click(session, radio_button("Yes"))
false ->
click(session, radio_button("No"))
_ ->
nil
end
session
end
def validation_error do
css(
"[data-test='contract-source-code-error']",
text: "there was an error validating your contract, please try again."
)
end
def verify_and_publish(session) do
click(session, button("Verify and publish"))
end
end

@ -32,6 +32,6 @@ defmodule BlockScoutWeb.TransactionListPage do
end
def visit_page(session) do
visit(session, "/en/transactions")
visit(session, "/txs")
end
end

@ -4,7 +4,7 @@ defmodule BlockScoutWeb.TransactionLogsPage do
use Wallaby.DSL
import Wallaby.Query, only: [css: 1, css: 2]
import BlockScoutWeb.Router.Helpers, only: [transaction_log_path: 4]
import BlockScoutWeb.Router.Helpers, only: [transaction_log_path: 3]
alias Explorer.Chain.{Address, Transaction}
alias BlockScoutWeb.Endpoint
@ -14,7 +14,7 @@ defmodule BlockScoutWeb.TransactionLogsPage do
end
def visit_page(session, %Transaction{} = transaction) do
visit(session, transaction_log_path(Endpoint, :index, :en, transaction))
visit(session, transaction_log_path(Endpoint, :index, transaction))
end
def click_address(session, %Address{hash: address_hash}) do

@ -16,10 +16,10 @@ defmodule BlockScoutWeb.TransactionPage do
end
def visit_page(session, %Transaction{hash: transaction_hash}) do
visit(session, "/en/transactions/#{transaction_hash}")
visit(session, "/tx/#{transaction_hash}")
end
def visit_page(session, transaction_hash = %Hash{}) do
visit(session, "/en/transactions/#{transaction_hash}")
visit(session, "/tx/#{transaction_hash}")
end
end

@ -2,7 +2,8 @@ defmodule BlockScoutWeb.ViewingAddressesTest do
use BlockScoutWeb.FeatureCase, async: true
alias Explorer.Chain.Wei
alias BlockScoutWeb.AddressPage
alias Explorer.Factory
alias BlockScoutWeb.{AddressPage, AddressView}
setup do
block = insert(:block)
@ -40,7 +41,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do
describe "viewing contract creator" do
test "see the contract creator and transaction links", %{session: session} do
address = insert(:address)
contract = insert(:address, contract_code: Explorer.Factory.data("contract_code"))
contract = insert(:address, contract_code: Factory.data("contract_code"))
transaction = insert(:transaction, from_address: address, created_contract_address: contract)
internal_transaction =
@ -52,8 +53,8 @@ defmodule BlockScoutWeb.ViewingAddressesTest do
created_contract_address: contract
)
address_hash = BlockScoutWeb.AddressView.trimmed_hash(address.hash)
transaction_hash = BlockScoutWeb.AddressView.trimmed_hash(transaction.hash)
address_hash = AddressView.trimmed_hash(address.hash)
transaction_hash = AddressView.trimmed_hash(transaction.hash)
session
|> AddressPage.visit_page(internal_transaction.created_contract_address)
@ -62,9 +63,9 @@ defmodule BlockScoutWeb.ViewingAddressesTest do
test "see the contract creator and transaction links even when the creator is another contract", %{session: session} do
lincoln = insert(:address)
contract = insert(:address, contract_code: Explorer.Factory.data("contract_code"))
contract = insert(:address, contract_code: Factory.data("contract_code"))
transaction = insert(:transaction)
another_contract = insert(:address, contract_code: Explorer.Factory.data("contract_code"))
another_contract = insert(:address, contract_code: Factory.data("contract_code"))
insert(
:internal_transaction,
@ -85,8 +86,8 @@ defmodule BlockScoutWeb.ViewingAddressesTest do
created_contract_address: another_contract
)
contract_hash = BlockScoutWeb.AddressView.trimmed_hash(contract.hash)
transaction_hash = BlockScoutWeb.AddressView.trimmed_hash(transaction.hash)
contract_hash = AddressView.trimmed_hash(contract.hash)
transaction_hash = AddressView.trimmed_hash(transaction.hash)
session
|> AddressPage.visit_page(internal_transaction.created_contract_address)
@ -337,7 +338,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do
contract_token_address =
insert(
:address,
contract_code: Explorer.Factory.data("contract_code")
contract_code: Factory.data("contract_code")
)
insert(:token, contract_address: contract_token_address)

@ -3,7 +3,6 @@ defmodule BlockScoutWeb.AddressViewTest do
alias Explorer.Chain.Data
alias BlockScoutWeb.AddressView
alias Explorer.ExchangeRates.Token
describe "contract?/1" do
test "with a smart contract" do
@ -18,26 +17,6 @@ defmodule BlockScoutWeb.AddressViewTest do
end
end
describe "formatted_usd/2" do
test "without a fetched_coin_balance returns nil" do
address = build(:address, fetched_coin_balance: nil)
token = %Token{usd_value: Decimal.new(0.5)}
assert nil == AddressView.formatted_usd(address, token)
end
test "without a usd_value returns nil" do
address = build(:address)
token = %Token{usd_value: nil}
assert nil == AddressView.formatted_usd(address, token)
end
test "returns formatted usd value" do
address = build(:address, fetched_coin_balance: 10_000_000_000_000)
token = %Token{usd_value: Decimal.new(0.5)}
assert "$0.000005 USD" == AddressView.formatted_usd(address, token)
end
end
describe "qr_code/1" do
test "it returns an encoded value" do
address = build(:address)

@ -1,7 +1,6 @@
defmodule BlockScoutWeb.ChainViewTest do
use BlockScoutWeb.ConnCase, async: true
alias Explorer.ExchangeRates.Token
alias BlockScoutWeb.ChainView
describe "encode_market_history_data/1" do
@ -17,22 +16,4 @@ defmodule BlockScoutWeb.ChainViewTest do
ChainView.encode_market_history_data(market_history_data)
end
end
describe "format_exchange_rate/1" do
test "returns a formatted usd value from a `Token`'s usd_value" do
token = %Token{usd_value: Decimal.new(5.45)}
assert "$5.45 USD" == ChainView.format_exchange_rate(token)
assert nil == ChainView.format_exchange_rate(%Token{usd_value: nil})
end
end
describe "format_market_cap/1" do
test "returns a formatted usd value from a `Token`'s market_cap_usd" do
token = %Token{market_cap_usd: Decimal.new(5.4)}
assert "$5.40 USD" == ChainView.format_market_cap(token)
assert nil == ChainView.format_market_cap(%Token{market_cap_usd: nil})
end
end
end

@ -2,18 +2,9 @@ defmodule BlockScoutWeb.CurrencyHelpersTest do
use ExUnit.Case
alias BlockScoutWeb.CurrencyHelpers
alias BlockScoutWeb.ExchangeRates.USD
doctest BlockScoutWeb.CurrencyHelpers, import: true
test "with nil it returns nil" do
assert nil == CurrencyHelpers.format_usd_value(nil)
end
test "with USD.null() it returns nil" do
assert nil == CurrencyHelpers.format_usd_value(USD.null())
end
describe "format_according_to_decimals/1" do
test "formats the amount as value considering the given decimals" do
amount = Decimal.new(205_000_000_000_000)

@ -2,7 +2,6 @@ defmodule BlockScoutWeb.TransactionViewTest do
use BlockScoutWeb.ConnCase, async: true
alias Explorer.Chain.Wei
alias Explorer.ExchangeRates.Token
alias Explorer.Repo
alias BlockScoutWeb.TransactionView
@ -18,21 +17,16 @@ defmodule BlockScoutWeb.TransactionViewTest do
gas_used: nil
)
token = %Token{usd_value: Decimal.new(0.50)}
expected_value = "<= 0.009 POA"
expected_value = "max of 0.009 POA"
assert expected_value == TransactionView.formatted_fee(transaction, denomination: :ether)
assert "<= $0.004500 USD" == TransactionView.formatted_fee(transaction, exchange_rate: token)
end
test "with fee and exchange_rate" do
test "with fee" do
{:ok, gas_price} = Wei.cast(3_000_000_000)
transaction = build(:transaction, gas_price: gas_price, gas_used: Decimal.new(1_034_234.0))
token = %Token{usd_value: Decimal.new(0.50)}
expected_value = "0.003102702 POA"
assert expected_value == TransactionView.formatted_fee(transaction, denomination: :ether)
assert "$0.001551 USD" == TransactionView.formatted_fee(transaction, exchange_rate: token)
end
test "with fee but no available exchange_rate" do

@ -188,10 +188,15 @@ defmodule EthereumJSONRPC do
Transaction data is included for each block.
"""
def fetch_blocks_by_hash(block_hashes, json_rpc_named_arguments) do
id_to_params =
block_hashes
|> Enum.map(fn block_hash -> %{hash: block_hash} end)
|> id_to_params()
id_to_params
|> get_block_by_hash_requests()
|> json_rpc(json_rpc_named_arguments)
|> handle_get_blocks()
|> handle_get_blocks(id_to_params)
|> case do
{:ok, _next, results} -> {:ok, results}
{:error, reason} -> {:error, reason}
@ -202,10 +207,15 @@ defmodule EthereumJSONRPC do
Fetches blocks by block number range.
"""
def fetch_blocks_by_range(_first.._last = range, json_rpc_named_arguments) do
id_to_params =
range
|> Enum.map(fn number -> %{number: number} end)
|> id_to_params()
id_to_params
|> get_block_by_number_requests()
|> json_rpc(json_rpc_named_arguments)
|> handle_get_blocks()
|> handle_get_blocks(id_to_params)
end
@doc """
@ -284,14 +294,6 @@ defmodule EthereumJSONRPC do
transport.json_rpc(request, transport_options)
end
@doc """
Converts `t:nonce/0` to `t:non_neg_integer/0`
"""
@spec nonce_to_integer(nonce) :: non_neg_integer()
def nonce_to_integer(nonce) do
quantity_to_integer(nonce)
end
@doc """
Converts `t:quantity/0` to `t:non_neg_integer/0`.
"""
@ -427,10 +429,10 @@ defmodule EthereumJSONRPC do
{:error, annotated_error}
end
defp get_block_by_hash_requests(block_hashes) do
for block_hash <- block_hashes do
get_block_by_hash_request(%{id: block_hash, hash: block_hash, transactions: :full})
end
defp get_block_by_hash_requests(id_to_params) do
Enum.map(id_to_params, fn {id, %{hash: hash}} ->
get_block_by_hash_request(%{id: id, hash: hash, transactions: :full})
end)
end
defp get_block_by_hash_request(%{id: id} = options) do
@ -441,10 +443,10 @@ defmodule EthereumJSONRPC do
[hash, get_block_transactions(options)]
end
defp get_block_by_number_requests(range) do
for current <- range do
get_block_by_number_request(%{id: current, quantity: current, transactions: :full})
end
defp get_block_by_number_requests(id_to_params) do
Enum.map(id_to_params, fn {id, %{number: number}} ->
get_block_by_number_request(%{id: id, quantity: number, transactions: :full})
end)
end
defp get_block_by_number_request(%{id: id} = options) do
@ -467,12 +469,6 @@ defmodule EthereumJSONRPC do
{:error, {:ok, tag}} ->
tag
{{:ok, _}, {:ok, _}} ->
raise ArgumentError, "Only one of :quantity or :tag can be passed to get_block_by_number_request"
{:error, :error} ->
raise ArgumentError, "One of :quantity or :tag MUST be passed to get_block_by_number_request"
end
end
@ -483,13 +479,8 @@ defmodule EthereumJSONRPC do
end
end
defp handle_get_blocks({:ok, results}) do
{blocks, next} =
Enum.reduce(results, {[], :more}, fn
%{result: nil}, {blocks, _} -> {blocks, :end_of_chain}
%{result: %{} = block}, {blocks, next} -> {[block | blocks], next}
end)
defp handle_get_blocks({:ok, results}, id_to_params) when is_list(results) do
with {:ok, next, blocks} <- reduce_results(results, id_to_params) do
elixir_blocks = Blocks.to_elixir(blocks)
elixir_transactions = Blocks.elixir_to_transactions(elixir_blocks)
blocks_params = Blocks.elixir_to_params(elixir_blocks)
@ -501,8 +492,27 @@ defmodule EthereumJSONRPC do
transactions: transactions_params
}}
end
end
defp handle_get_blocks({:error, _} = error, _id_to_params), do: error
defp reduce_results(results, id_to_params) do
Enum.reduce(results, {:ok, :more, []}, &reduce_result(&1, &2, id_to_params))
end
defp reduce_result(%{result: nil}, {:ok, _, blocks}, _id_to_params), do: {:ok, :end_of_chain, blocks}
defp reduce_result(%{result: %{} = block}, {:ok, next, blocks}, _id_to_params), do: {:ok, next, [block | blocks]}
defp reduce_result(%{result: _}, {:error, _} = error, _id_to_params), do: error
defp handle_get_blocks({:error, _} = error), do: error
defp reduce_result(%{error: reason, id: id}, acc, id_to_params) do
data = Map.fetch!(id_to_params, id)
annotated_reason = Map.put(reason, :data, data)
case acc do
{:ok, _, _} -> {:error, [annotated_reason]}
{:error, reasons} -> {:error, [annotated_reason | reasons]}
end
end
defp handle_get_block_by_tag({:ok, %{"number" => quantity}}) do
{:ok, quantity_to_integer(quantity)}

@ -266,6 +266,7 @@ defmodule EthereumJSONRPC.Receipt do
defp elixir_reducer({:ok, {_, _}}, {:error, _reasons} = acc_error), do: acc_error
defp elixir_reducer({:error, reason}, {:ok, _}), do: {:error, [reason]}
defp elixir_reducer({:error, reason}, {:error, reasons}), do: {:error, [reason | reasons]}
defp elixir_reducer(:ignore, acc), do: acc
defp ok!({:ok, elixir}, _receipt), do: elixir
@ -327,6 +328,8 @@ defmodule EthereumJSONRPC.Receipt do
case status do
"0x0" -> {:ok, {key, :error}}
"0x1" -> {:ok, {key, :ok}}
# pre-Byzantium / Ethereum Classic on Parity
nil -> :ignore
other -> {:error, {:unknown_value, %{key: key, value: other}}}
end
end

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

Loading…
Cancel
Save