Display token icons for tokens from TrustWallet repo

pull/4596/head
Viktor Baranov 3 years ago
parent ad67d53bc0
commit 82a8e26248
  1. 1
      CHANGELOG.md
  2. 3
      apps/block_scout_web/assets/css/components/_navbar.scss
  3. 1
      apps/block_scout_web/assets/css/components/_search.scss
  4. 34
      apps/block_scout_web/assets/js/lib/autocomplete.js
  5. 59
      apps/block_scout_web/assets/js/lib/token_icon.js
  6. 13
      apps/block_scout_web/assets/js/pages/token/overview.js
  7. 377
      apps/block_scout_web/assets/package-lock.json
  8. 1
      apps/block_scout_web/assets/static/images/xdai_alternative.svg
  9. 4
      apps/block_scout_web/assets/static/manifest.webmanifest
  10. 3
      apps/block_scout_web/assets/webpack.config.js
  11. 3
      apps/block_scout_web/lib/block_scout_web/controllers/tokens/tokens_controller.ex
  12. 2
      apps/block_scout_web/lib/block_scout_web/csp_header.ex
  13. 10
      apps/block_scout_web/lib/block_scout_web/templates/bridged_tokens/_tile.html.eex
  14. 10
      apps/block_scout_web/lib/block_scout_web/templates/layout/_search.html.eex
  15. 34
      apps/block_scout_web/lib/block_scout_web/templates/search/_tile.html.eex
  16. 7
      apps/block_scout_web/lib/block_scout_web/templates/search/results.html.eex
  17. 31
      apps/block_scout_web/lib/block_scout_web/templates/tokens/_tile.html.eex
  18. 16
      apps/block_scout_web/lib/block_scout_web/templates/tokens/index.html.eex
  19. 9
      apps/block_scout_web/lib/block_scout_web/templates/tokens/overview/_details.html.eex
  20. 2
      apps/block_scout_web/lib/block_scout_web/views/bridged_tokens_view.ex
  21. 1
      apps/block_scout_web/lib/block_scout_web/views/search_view.ex
  22. 3
      apps/block_scout_web/lib/block_scout_web/views/tokens_view.ex
  23. 20
      apps/block_scout_web/priv/gettext/default.pot
  24. 20
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  25. 70
      apps/explorer/lib/explorer/chain.ex
  26. 16
      docker/Dockerfile
  27. 48
      docker/Makefile

@ -2,6 +2,7 @@
### Features
- [#4608](https://github.com/blockscout/blockscout/pull/4608) - Block Details page: Improved style of transactions button
- [#4596](https://github.com/blockscout/blockscout/pull/4596) - Display token icon for bridged with Mainnet tokens or identicons for other tokens
- [#4520](https://github.com/blockscout/blockscout/pull/4520) - Add support for EIP-1559
- [#4593](https://github.com/blockscout/blockscout/pull/4593) - Add status in `Position` pane for txs have no block
- [#4579](https://github.com/blockscout/blockscout/pull/4579) - Write contract page: Resize inputs; Improve multiplier selector

@ -248,7 +248,8 @@ $navbar-logo-width: auto !default;
.logo-text {
color: #333;
font-size: 0.7rem;
font-size: 1rem;
font-weight: 700;
margin-left: 5px;
line-height: 28px;

@ -50,6 +50,7 @@
font-weight: 100;
text-transform: uppercase;
color: rgb(33,33,33);
margin-left: auto;
}
.autoComplete_highlight {

@ -1,6 +1,8 @@
import AutoComplete from '@tarekraafat/autocomplete.js/dist/autoComplete.js'
import { getTextAdData, fetchTextAdData } from './ad.js'
import $ from 'jquery'
import AutoComplete from '@tarekraafat/autocomplete.js/dist/autoComplete'
import { getTextAdData, fetchTextAdData } from './ad'
import { DateTime } from 'luxon'
import { appendTokenIcon } from './token_icon'
const placeHolder = 'Search by address, token symbol, name, transaction hash, or block number'
const dataSrc = async (query, id) => {
@ -51,11 +53,13 @@ const searchEngine = (query, record) => {
(record.block_hash && record.block_hash.toLowerCase().includes(query.toLowerCase()))
)
) {
var searchResult = `${record.address_hash || record.tx_hash || record.block_hash}<br/>`
var searchResult = '<div>'
searchResult += `<div>${record.address_hash || record.tx_hash || record.block_hash}</div>`
if (record.type === 'label') {
searchResult += `<div class="fontawesome-icon tag"></div><span> <b>${record.name}</b></span>`
} else {
searchResult += '<div>'
if (record.name) {
searchResult += `<b>${record.name}</b>`
}
@ -68,23 +72,31 @@ const searchEngine = (query, record) => {
if (record.inserted_at) {
searchResult += ` (${DateTime.fromISO(record.inserted_at).toLocaleString(DateTime.DATETIME_SHORT)})`
}
searchResult += '</div>'
}
searchResult += '</div>'
var re = new RegExp(query, 'ig')
searchResult = searchResult.replace(re, '<mark class=\'autoComplete_highlight\'>$&</mark>')
return searchResult
}
}
const resultItemElement = (item, data) => {
// Modify Results Item Style
item.style = 'display: flex; justify-content: space-between;'
// Modify Results Item Content
const resultItemElement = async (item, data) => {
item.style = 'display: flex;'
item.innerHTML = `
<span style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
<div id='token-icon-${data.value.address_hash}' style='margin-top: -1px;'></div>
<div style="padding-left: 10px; padding-right: 10px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden;">
${data.match}
</span>
<span class="autocomplete-category">
</div>
<div class="autocomplete-category">
${data.value.type}
</span>`
</div>`
const $tokenIconContainer = $(item).find(`#token-icon-${data.value.address_hash}`)
const $searchInput = $('#main-search-autocomplete')
const chainID = $searchInput.data('chain-id')
const displayTokenIcons = $searchInput.data('display-token-icons')
appendTokenIcon($tokenIconContainer, chainID, data.value.address_hash, data.value.foreign_chain_id, data.value.foreign_token_hash, displayTokenIcons, 15)
}
const config = (id) => {
return {

@ -0,0 +1,59 @@
function getTokenIconUrl (chainID, addressHash) {
var chainName = null
switch (chainID) {
case '1':
chainName = 'ethereum'
break
case '99':
chainName = 'poa'
break
case '100':
chainName = 'xdai'
break
default:
chainName = null
break
}
if (chainName) {
return `https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/${chainName}/assets/${addressHash}/logo.png`
} else {
return null
}
}
function appendTokenIcon ($tokenIconContainer, chainID, addressHash, foreignChainID, foreignAddressHash, displayTokenIcons, size) {
const iconSize = size || 20
var tokenIconURL = null
if (foreignChainID) {
tokenIconURL = getTokenIconUrl(foreignChainID.toString(), foreignAddressHash)
} else if (chainID) {
tokenIconURL = getTokenIconUrl(chainID.toString(), addressHash)
}
if (displayTokenIcons) {
checkLink(tokenIconURL)
.then(checkTokenIconLink => {
if (checkTokenIconLink) {
if ($tokenIconContainer) {
var img = new Image(iconSize, iconSize)
img.src = tokenIconURL
$tokenIconContainer.append(img)
}
}
})
}
}
async function checkLink (url) {
if (url) {
try {
const res = await fetch(url)
return res.ok
} catch (_error) {
return false
}
} else {
return false
}
}
export { appendTokenIcon, checkLink, getTokenIconUrl }

@ -0,0 +1,13 @@
import $ from 'jquery'
import { appendTokenIcon } from '../../lib/token_icon'
if ($('[data-page="token-details"]').length) {
const $tokenIconContainer = $('#token-icon')
const chainID = $tokenIconContainer.data('chain-id')
const addressHash = $tokenIconContainer.data('address-hash')
const foreignChainID = $tokenIconContainer.data('foreign-chain-id')
const foreignAddressHash = $tokenIconContainer.data('foreign-address-hash')
const displayTokenIcons = $tokenIconContainer.data('display-token-icons')
appendTokenIcon($tokenIconContainer, chainID, addressHash, foreignChainID, foreignAddressHash, displayTokenIcons)
}

@ -2338,21 +2338,6 @@
"node": ">=8"
}
},
"node_modules/@jest/core/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@jest/core/node_modules/strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
@ -2759,6 +2744,45 @@
"node": ">=8"
}
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz",
"integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"detect-libc": "^1.0.3",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
"node-fetch": "^2.6.1",
"nopt": "^5.0.0",
"npmlog": "^4.1.2",
"rimraf": "^3.0.2",
"semver": "^7.3.4",
"tar": "^6.1.0"
},
"bin": {
"node-pre-gyp": "bin/node-pre-gyp"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@ -3325,6 +3349,20 @@
"node": ">=0.4.0"
}
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/aggregate-error": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
@ -4574,6 +4612,64 @@
"url": "https://opencollective.com/browserslist"
}
},
"node_modules/canvas": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz",
"integrity": "sha512-gLTi17X8WY9Cf5GZ2Yns8T5lfBOcGgFehDFb+JQwDqdOoBOcECS9ZWMEAqMSVcMYwXD659J8NyzjRY/2aE+C2Q==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"peer": true,
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.0",
"nan": "^2.14.0",
"simple-get": "^3.0.3"
},
"engines": {
"node": ">=6"
}
},
"node_modules/canvas/node_modules/decompress-response": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"mimic-response": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/canvas/node_modules/mimic-response": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/canvas/node_modules/simple-get": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"node_modules/capture-exit": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
@ -5137,21 +5233,6 @@
"node": ">=6"
}
},
"node_modules/copy-webpack-plugin/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/copy-webpack-plugin/node_modules/serialize-javascript": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
@ -5924,6 +6005,20 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"node_modules/detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
"dev": true,
"optional": true,
"peer": true,
"bin": {
"detect-libc": "bin/detect-libc.js"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@ -8182,6 +8277,21 @@
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
},
"node_modules/https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/human-signals": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
@ -11844,6 +11954,17 @@
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
"integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
},
"node_modules/node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": "4.x || >=6.0.0"
}
},
"node_modules/node-gyp": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
@ -11878,21 +11999,6 @@
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/node-gyp/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/node-gyp/node_modules/semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
@ -14367,6 +14473,21 @@
"integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
"dev": true
},
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ripemd160": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
@ -16116,9 +16237,9 @@
}
},
"node_modules/tar": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz",
"integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==",
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"dev": true,
"dependencies": {
"chownr": "^2.0.0",
@ -19703,15 +19824,6 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
@ -20030,6 +20142,38 @@
}
}
},
"@mapbox/node-pre-gyp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz",
"integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"detect-libc": "^1.0.3",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
"node-fetch": "^2.6.1",
"nopt": "^5.0.0",
"npmlog": "^4.1.2",
"rimraf": "^3.0.2",
"semver": "^7.3.4",
"tar": "^6.1.0"
},
"dependencies": {
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@ -20526,6 +20670,17 @@
"integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
"dev": true
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"debug": "4"
}
},
"aggregate-error": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
@ -21500,6 +21655,53 @@
"integrity": "sha512-zWEwIVqnzPkSAXOUlQnPW2oKoYb2aLQ4Q5ejdjBcnH63rfypaW34CxaeBn1VMya2XaEU3P/R2qHpWyj+l0BT1A==",
"dev": true
},
"canvas": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz",
"integrity": "sha512-gLTi17X8WY9Cf5GZ2Yns8T5lfBOcGgFehDFb+JQwDqdOoBOcECS9ZWMEAqMSVcMYwXD659J8NyzjRY/2aE+C2Q==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"@mapbox/node-pre-gyp": "^1.0.0",
"nan": "^2.14.0",
"simple-get": "^3.0.3"
},
"dependencies": {
"decompress-response": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"mimic-response": "^2.0.0"
}
},
"mimic-response": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
"dev": true,
"optional": true,
"peer": true
},
"simple-get": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
}
}
},
"capture-exit": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
@ -21963,15 +22165,6 @@
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"serialize-javascript": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
@ -22561,6 +22754,14 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
"dev": true,
"optional": true,
"peer": true
},
"detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@ -24390,6 +24591,18 @@
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
},
"https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"dev": true,
"optional": true,
"peer": true,
"requires": {
"agent-base": "6",
"debug": "4"
}
},
"human-signals": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
@ -27210,6 +27423,14 @@
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
"integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"dev": true,
"optional": true,
"peer": true
},
"node-gyp": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
@ -27228,15 +27449,6 @@
"which": "^2.0.2"
},
"dependencies": {
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
@ -29136,6 +29348,15 @@
"integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
"dev": true
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"ripemd160": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
@ -30534,9 +30755,9 @@
"dev": true
},
"tar": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz",
"integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==",
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"dev": true,
"requires": {
"chownr": "^2.0.0",

@ -0,0 +1 @@
<svg height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m40 298h86v86h86v86h-172zm430 0v172h-172v-86h86v-86zm-258-258v86h-172v-86zm258 0v86h-172v-86z" fill="#48a9a6" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 233 B

@ -15,5 +15,7 @@
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
"display": "standalone",
"permissions": [ "https://raw.githubusercontent.com/" ],
"content_security_policy": "connect-src 'self' raw.githubusercontent.com;"
}

@ -96,7 +96,8 @@ const appJs =
'text_ad': './js/lib/text_ad.js',
'banner': './js/lib/banner.js',
'autocomplete': './js/lib/autocomplete.js',
'search-results': './js/pages/search-results/search.js'
'search-results': './js/pages/search-results/search.js',
'token-overview': './js/pages/token/overview.js'
},
output: {
filename: '[name].js',

@ -54,7 +54,8 @@ defmodule BlockScoutWeb.TokensController do
TokensView,
"_tile.html",
token: token,
index: items_count + index
index: items_count + index,
conn: conn
)
end)

@ -11,7 +11,7 @@ defmodule BlockScoutWeb.CSPHeader do
def call(conn, _opts) do
Controller.put_secure_browser_headers(conn, %{
"content-security-policy" => "\
connect-src 'self' #{websocket_endpoints(conn)} https://request-global.czilladx.com/;\
connect-src 'self' #{websocket_endpoints(conn)} https://request-global.czilladx.com/ https://raw.githubusercontent.com/;\
default-src 'self';\
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://coinzillatag.com;\
style-src 'self' 'unsafe-inline' 'unsafe-eval' https://fonts.googleapis.com;\

@ -10,6 +10,16 @@
<div class="centered-container">
<div>
<div style="display: table;">
<%= if System.get_env("DISPLAY_TOKEN_ICONS") === "true" do %>
<% foreign_chain_id = if Map.has_key?(@bridged_token, :foreign_chain_id), do: @bridged_token.foreign_chain_id, else: nil %>
<% chain_id_for_token_icon = if foreign_chain_id, do: foreign_chain_id |> Decimal.to_integer() |> to_string(), else: System.get_env("CHAIN_ID") %>
<% foreign_token_contract_address_hash = if Map.has_key?(@bridged_token, :foreign_token_contract_address_hash), do: Address.checksum(@bridged_token.foreign_token_contract_address_hash), else: nil %>
<% token_hash_for_token_icon = if foreign_token_contract_address_hash, do: foreign_token_contract_address_hash, else: Address.checksum(@token.contract_address_hash) %>
<% token_icon_url = Explorer.Chain.get_token_icon_url_by(chain_id_for_token_icon, token_hash_for_token_icon) %>
<%= if token_icon_url do %>
<img heigth=15 width=15 src="<%= token_icon_url %>" style="margin-top: -3px;" class="mr-1"/>
<% end %>
<% end %>
<%= link(token,
to: token_path(BlockScoutWeb.Endpoint, :show, @token.contract_address_hash),
"data-test": "token_link",

@ -2,7 +2,15 @@
<div class="search-form d-lg-flex d-inline-block <%= if assigns[:additional_classes] do @additional_classes |> Enum.join(" ") end %>">
<div class="input-group" style="width: 100%;" title='<%= gettext("Search by address, token symbol name, transaction hash, or block number") %>'>
<div class="form-control search-control me auto <%= if assigns[:additional_classes] do @additional_classes |> Enum.join(" ") end %>">
<input id="<%= @id %>" class="main-search-autocomplete" data-test="search_input" type="text" tabindex="1">
<input
id="<%= @id %>"
class="main-search-autocomplete"
data-test="search_input"
data-chain-id="<%= System.get_env("CHAIN_ID") %>"
data-display-token-icons="<%= System.get_env("DISPLAY_TOKEN_ICONS") %>"
type="text"
tabindex="1"
>
</div>
<div class="input-group-append left">
<button class="input-group-text" id="search-icon">

@ -1,3 +1,4 @@
<% address_hash_checksummed = @result.address_hash %>
<tr data-identifier-hash="<%= @result.address_hash %>-<%= if @result.tx_hash, do: Base.encode16(@result.tx_hash, case: :lower), else: "" %>-<%= if @result.block_hash, do: Base.encode16(@result.block_hash, case: :lower), else: "" %>">
<td class="stakes-td">
<!-- incremented number by order in the list -->
@ -7,19 +8,33 @@
<td class="stakes-td">
<%= case @result.type do %>
<% "token" -> %>
<span
class="token-icon mr-1"
data-address-hash="<%= address_hash_checksummed %>"
>
<%= if System.get_env("DISPLAY_TOKEN_ICONS") === "true" do %>
<% chain_id_for_token_icon = if @result.foreign_chain_id, do: @result.foreign_chain_id, else: System.get_env("CHAIN_ID") %>
<% address_hash = if @result.foreign_token_hash, do: @result.foreign_token_hash, else: @result.address_hash %>
<% token_icon_url = Chain.get_token_icon_url_by(chain_id_for_token_icon, address_hash) %>
<%= if token_icon_url do %>
<img heigth=15 width=15 src="<%= token_icon_url %>" style="margin-top: -2px;"/>
<% end %>
<% end %>
</span>
<% res = @result.name <> " (" <> @result.symbol <> ")" %>
<a href="<%= token_path(@conn, :show, Address.checksum(@result.address_hash)) %>">
<a href="<%= token_path(@conn, :show, address_hash_checksummed) %>">
<%= highlight_search_result(res, @query) %>
</a>
<% "address" -> %>
<%= if @result.name do %>
<a href="<%= address_path(@conn, :show, Address.checksum(@result.address_hash)) %>">
<a href="<%= address_path(@conn, :show, address_hash_checksummed) %>">
<%= highlight_search_result(@result.name, @query) %>
</a>
<% end %>
<% "contract" -> %>
<%= if @result.name do %>
<a href="<%= address_path(@conn, :show, Address.checksum(@result.address_hash)) %>">
<a href="<%= address_path(@conn, :show, address_hash_checksummed) %>">
<%= highlight_search_result(@result.name, @query) %>
</a>
<% end %>
@ -34,7 +49,8 @@
<td class="stakes-td">
<%= case @result.type do %>
<% "token" -> %>
<%= with {:ok, address} <- Chain.hash_to_address(@result.address_hash) do %>
<%= with {:ok, address_hash} = Chain.string_to_address_hash(@result.address_hash),
{:ok, address} <- Chain.hash_to_address(address_hash) do %>
<%= render BlockScoutWeb.AddressView,
"_link.html",
address: address,
@ -43,7 +59,8 @@
%>
<% end %>
<% "address" -> %>
<%= with {:ok, address} <- Chain.hash_to_address(@result.address_hash) do %>
<%= with {:ok, address_hash} = Chain.string_to_address_hash(@result.address_hash),
{:ok, address} <- Chain.hash_to_address(address_hash) do %>
<%= render BlockScoutWeb.AddressView,
"_link.html",
address: address,
@ -52,7 +69,8 @@
%>
<% end %>
<% "contract" -> %>
<%= with {:ok, address} <- Chain.hash_to_address(@result.address_hash) do %>
<%= with {:ok, address_hash} = Chain.string_to_address_hash(@result.address_hash),
{:ok, address} <- Chain.hash_to_address(address_hash) do %>
<%= render BlockScoutWeb.AddressView,
"_link.html",
address: address,
@ -75,3 +93,7 @@
<div class="bs-label <%= @result.type %>"><%= @result.type %></div>
</td>
</tr>
<script src="https://cdn.jsdelivr.net/npm/jdenticon@3.1.1/dist/jdenticon.min.js"
integrity="sha384-l0/0sn63N3mskDgRYJZA6Mogihu0VY3CusdLMiwpJ9LFPklOARUcOiWEIGGmFELx"
crossorigin="anonymous">
</script>

@ -1,4 +1,9 @@
<section class="container" data-page="search-results">
<section
class="container"
data-page="search-results"
data-chain-id="<%= System.get_env("CHAIN_ID") %>"
data-display-token-icons="<%= System.get_env("DISPLAY_TOKEN_ICONS") %>"
>
<%= render BlockScoutWeb.Advertisement.TextAdView, "index.html", conn: @conn %>
<div class="card">
<div class="card-body" data-async-load data-async-listing="<%= @current_path %>">

@ -6,6 +6,26 @@
</span>
</td>
<td class="stakes-td">
<%= if System.get_env("DISPLAY_TOKEN_ICONS") === "true" do %>
<% foreign_chain_id =
if @bridged_token do
if Map.has_key?(@bridged_token, :foreign_chain_id), do: @bridged_token.foreign_chain_id, else: nil
else
nil
end %>
<% chain_id_for_token_icon = if foreign_chain_id, do: foreign_chain_id |> Decimal.to_integer() |> to_string(), else: System.get_env("CHAIN_ID") %>
<% foreign_token_contract_address_hash =
if @bridged_token do
if Map.has_key?(@bridged_token, :foreign_token_contract_address_hash), do: Address.checksum(@bridged_token.foreign_token_contract_address_hash), else: nil
else
nil
end %>
<% token_hash_for_token_icon = if foreign_token_contract_address_hash, do: foreign_token_contract_address_hash, else: Address.checksum(@token.contract_address_hash) %>
<% token_icon_url = Explorer.Chain.get_token_icon_url_by(chain_id_for_token_icon, token_hash_for_token_icon) %>
<%= if token_icon_url do %>
<img heigth=15 width=15 src="<%= token_icon_url %>" style="margin-top: -3px;"/>
<% end %>
<% end %>
<% token = token_display_name(@token) %>
<%= link(token,
to: token_path(BlockScoutWeb.Endpoint, :show, @token.contract_address_hash),
@ -20,17 +40,6 @@
use_custom_tooltip: false
%>
</td>
<%= if Chain.bridged_tokens_enabled?() do %>
<td class="stakes-td">
<%= case @token.bridged do %>
<% nil -> %>
<i style="color: #f7b32b; font-size: 20px;" class="far fa-question-circle"></i>
<% true -> %>
<i style="color: #20b760; font-size: 20px;" class="far fa-check-circle"></i>
<% false -> %>
<% end %>
</td>
<% end %>
<td class="stakes-td">
<%= if decimals?(@token) do %>
<span data-test="token_supply"><%= format_according_to_decimals(@token.total_supply, @token.decimals) %></span>

@ -1,4 +1,9 @@
<section class="container" data-page="tokens">
<section
class="container"
data-page="tokens"
data-chain-id="<%= System.get_env("CHAIN_ID") %>"
data-display-token-icons="<%= System.get_env("DISPLAY_TOKEN_ICONS") %>"
>
<%= render BlockScoutWeb.Advertisement.TextAdView, "index.html", conn: @conn %>
<div class="card">
<div class="card-body" data-async-load data-async-listing="<%= @current_path %>">
@ -25,11 +30,6 @@
<th class="stakes-table-th">
<div class="stakes-table-th-content">Address</div>
</th>
<%= if Chain.bridged_tokens_enabled?() do %>
<th class="stakes-table-th">
<div class="stakes-table-th-content">Bridged?</div>
</th>
<% end %>
<th class="stakes-table-th">
<div class="stakes-table-th-content">
Total Supply
@ -52,6 +52,6 @@
<%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
</div>
</div>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/tokens.js") %>"></script>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>"></script>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/tokens.js") %>"></script>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>"></script>
</section>

@ -24,6 +24,14 @@
<% foreign_chain_id = if Map.has_key?(@token, :foreign_chain_id), do: @token.foreign_chain_id, else: nil %>
<% tag = Chain.chain_id_display_name(foreign_chain_id) %>
<%= if token_name?(@token) do %>
<span
id="token-icon"
data-chain-id="<%= System.get_env("CHAIN_ID") %>"
data-address-hash="<%= Address.checksum(@token.contract_address_hash) %>"
data-foreign-chain-id="<%= foreign_chain_id %>"
data-foreign-address-hash="<%= if Map.has_key?(@token, :foreign_token_contract_address_hash), do: Address.checksum(@token.foreign_token_contract_address_hash), else: "" %>"
data-display-token-icons="<%= System.get_env("DISPLAY_TOKEN_ICONS") %>">
</span>
<div class="title-with-label"><%= @token.name %></div>
<%= if tag !== "" do %>
<%= render BlockScoutWeb.FormView, "_tag.html", text: "bridged", additional_classes: ["bridged", "ml-1"] %>
@ -114,3 +122,4 @@
<!-- Modal QR -->
<%= render BlockScoutWeb.CommonComponentsView, "_modal_qr_code.html", qr_code: BlockScoutWeb.AddressView.qr_code(Address.checksum(@token.contract_address_hash)), title: @token.contract_address %>
<%= render BlockScoutWeb.Advertisement.BannersAdView, "_banner_728.html", conn: @conn %>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/token-overview.js") %>"></script>

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.BridgedTokensView do
alias BlockScoutWeb.ChainView
alias Explorer.Chain
alias Explorer.Chain.Token
alias Explorer.Chain.{Address, Token}
@owl_token_amb "0x0905Ab807F8FD040255F0cF8fa14756c1D824931"
@owl_token_omni "0x750eCf8c11867Ce5Dbc556592c5bb1E0C6d16538"

@ -2,7 +2,6 @@ defmodule BlockScoutWeb.SearchView do
use BlockScoutWeb, :view
alias Explorer.Chain
alias Explorer.Chain.Address
alias Floki
def highlight_search_result(result, query) do

@ -1,8 +1,7 @@
defmodule BlockScoutWeb.TokensView do
use BlockScoutWeb, :view
alias Explorer.Chain
alias Explorer.Chain.Token
alias Explorer.Chain.{Address, Token}
def decimals?(%Token{decimals: nil}), do: false
def decimals?(%Token{decimals: _}), do: true

@ -727,8 +727,8 @@ msgstr ""
#: lib/block_scout_web/templates/address/overview.html.eex:38
#: lib/block_scout_web/templates/block/overview.html.eex:98
#: lib/block_scout_web/templates/block/overview.html.eex:99
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:40
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:41
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:48
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:49
msgid "Copy Address"
msgstr ""
@ -906,7 +906,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:52
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:75
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:83
msgid "Decimals"
msgstr ""
@ -1780,7 +1780,7 @@ msgid "Potential matches from our contract method database:"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_search.html.eex:19
#: lib/block_scout_web/templates/layout/_search.html.eex:27
msgid "Press / and focus will be moved to the search field"
msgstr ""
@ -1940,12 +1940,12 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/index.html.eex:16
#: lib/block_scout_web/templates/layout/_search.html.eex:26
#: lib/block_scout_web/templates/layout/_search.html.eex:34
msgid "Search"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/search/results.html.eex:12
#: lib/block_scout_web/templates/search/results.html.eex:17
msgid "Search Results"
msgstr ""
@ -2491,7 +2491,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:10
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:33
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:41
msgid "Token Details"
msgstr ""
@ -2544,7 +2544,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:13
#: lib/block_scout_web/templates/layout/_topnav.html.eex:75
#: lib/block_scout_web/templates/layout/_topnav.html.eex:101
#: lib/block_scout_web/templates/tokens/index.html.eex:5
#: lib/block_scout_web/templates/tokens/index.html.eex:10
#: lib/block_scout_web/views/address_view.ex:343
msgid "Tokens"
msgstr ""
@ -2591,7 +2591,7 @@ msgid "Total Difficulty"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:87
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:95
msgid "Total Supply"
msgstr ""
@ -2898,7 +2898,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:16
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:20
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:67
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:75
msgid "View Contract"
msgstr ""

@ -727,8 +727,8 @@ msgstr ""
#: lib/block_scout_web/templates/address/overview.html.eex:38
#: lib/block_scout_web/templates/block/overview.html.eex:98
#: lib/block_scout_web/templates/block/overview.html.eex:99
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:40
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:41
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:48
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:49
msgid "Copy Address"
msgstr ""
@ -906,7 +906,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:52
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:75
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:83
msgid "Decimals"
msgstr ""
@ -1780,7 +1780,7 @@ msgid "Potential matches from our contract method database:"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_search.html.eex:19
#: lib/block_scout_web/templates/layout/_search.html.eex:27
msgid "Press / and focus will be moved to the search field"
msgstr ""
@ -1940,12 +1940,12 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address_logs/index.html.eex:16
#: lib/block_scout_web/templates/layout/_search.html.eex:26
#: lib/block_scout_web/templates/layout/_search.html.eex:34
msgid "Search"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/search/results.html.eex:12
#: lib/block_scout_web/templates/search/results.html.eex:17
msgid "Search Results"
msgstr ""
@ -2491,7 +2491,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:10
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:33
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:41
msgid "Token Details"
msgstr ""
@ -2544,7 +2544,7 @@ msgstr ""
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:13
#: lib/block_scout_web/templates/layout/_topnav.html.eex:75
#: lib/block_scout_web/templates/layout/_topnav.html.eex:101
#: lib/block_scout_web/templates/tokens/index.html.eex:5
#: lib/block_scout_web/templates/tokens/index.html.eex:10
#: lib/block_scout_web/views/address_view.ex:343
msgid "Tokens"
msgstr ""
@ -2591,7 +2591,7 @@ msgid "Total Difficulty"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:87
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:95
msgid "Total Supply"
msgstr ""
@ -2898,7 +2898,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:16
#: lib/block_scout_web/templates/tokens/instance/overview/_details.html.eex:20
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:67
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:75
msgid "View Contract"
msgstr ""

@ -1173,11 +1173,15 @@ defmodule Explorer.Chain do
defp search_token_query(term) do
from(token in Token,
left_join: bridged in BridgedToken,
on: token.contract_address_hash == bridged.home_token_contract_address_hash,
where: fragment("to_tsvector(symbol || ' ' || name ) @@ to_tsquery(?)", ^term),
select: %{
address_hash: token.contract_address_hash,
tx_hash: fragment("CAST(NULL AS bytea)"),
block_hash: fragment("CAST(NULL AS bytea)"),
foreign_token_hash: bridged.foreign_token_contract_address_hash,
foreign_chain_id: bridged.foreign_chain_id,
type: "token",
name: token.name,
symbol: token.symbol,
@ -1197,6 +1201,8 @@ defmodule Explorer.Chain do
address_hash: smart_contract.address_hash,
tx_hash: fragment("CAST(NULL AS bytea)"),
block_hash: fragment("CAST(NULL AS bytea)"),
foreign_token_hash: fragment("CAST(NULL AS bytea)"),
foreign_chain_id: ^nil,
type: "contract",
name: smart_contract.name,
symbol: ^nil,
@ -1218,6 +1224,8 @@ defmodule Explorer.Chain do
address_hash: address.hash,
tx_hash: fragment("CAST(NULL AS bytea)"),
block_hash: fragment("CAST(NULL AS bytea)"),
foreign_token_hash: fragment("CAST(NULL AS bytea)"),
foreign_chain_id: ^nil,
type: "address",
name: address_name.name,
symbol: ^nil,
@ -1241,6 +1249,8 @@ defmodule Explorer.Chain do
address_hash: fragment("CAST(NULL AS bytea)"),
tx_hash: transaction.hash,
block_hash: fragment("CAST(NULL AS bytea)"),
foreign_token_hash: fragment("CAST(NULL AS bytea)"),
foreign_chain_id: ^nil,
type: "transaction",
name: ^nil,
symbol: ^nil,
@ -1264,6 +1274,8 @@ defmodule Explorer.Chain do
address_hash: fragment("CAST(NULL AS bytea)"),
tx_hash: fragment("CAST(NULL AS bytea)"),
block_hash: block.hash,
foreign_token_hash: fragment("CAST(NULL AS bytea)"),
foreign_chain_id: ^nil,
type: "block",
name: ^nil,
symbol: ^nil,
@ -1282,6 +1294,8 @@ defmodule Explorer.Chain do
address_hash: fragment("CAST(NULL AS bytea)"),
tx_hash: fragment("CAST(NULL AS bytea)"),
block_hash: block.hash,
foreign_token_hash: fragment("CAST(NULL AS bytea)"),
foreign_chain_id: ^nil,
type: "block",
name: ^nil,
symbol: ^nil,
@ -1342,7 +1356,28 @@ defmodule Explorer.Chain do
ordered_query
|> page_search_results(paging_options)
Repo.all(paginated_ordered_query)
search_results = Repo.all(paginated_ordered_query)
search_results
|> Enum.map(fn result ->
result_checksummed_address_hash =
if result.address_hash do
result
|> Map.put(:address_hash, Address.checksum(result.address_hash))
else
result
end
result_checksummed =
if result_checksummed_address_hash.foreign_token_hash do
result_checksummed_address_hash
|> Map.put(:foreign_token_hash, Address.checksum(result_checksummed_address_hash.foreign_token_hash))
else
result_checksummed_address_hash
end
result_checksummed
end)
_ ->
[]
@ -6873,4 +6908,37 @@ defmodule Explorer.Chain do
:token_transfer
end
end
@spec get_token_icon_url_by(String.t(), String.t()) :: String.t() | nil
def get_token_icon_url_by(chain_id, address_hash) do
chain_name =
case chain_id do
"1" ->
"ethereum"
"99" ->
"poa"
"100" ->
"xdai"
_ ->
nil
end
if chain_name do
try_url =
"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/#{chain_name}/assets/#{address_hash}/logo.png"
%HTTPoison.Response{status_code: status_code} = HTTPoison.get!(try_url)
if status_code == 200 do
try_url
else
nil
end
else
nil
end
end
end

@ -1,6 +1,17 @@
FROM bitwalker/alpine-elixir-phoenix:1.11.4
RUN apk --no-cache --update add alpine-sdk gmp-dev automake libtool inotify-tools autoconf python3 file
RUN apk --no-cache --update add alpine-sdk gmp-dev automake libtool inotify-tools autoconf python3 file pango-dev jpeg-dev libjpeg-turbo-dev giflib-dev librsvg-dev
ENV GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc
ENV GLIBC_VERSION=2.30-r0
RUN set -ex && \
apk --update add libstdc++ curl ca-certificates && \
for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
apk add --allow-untrusted /tmp/*.apk && \
rm -v /tmp/*.apk && \
/usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib
# Get Rust
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
@ -31,6 +42,9 @@ RUN if [ "$COIN" != "" ]; then sed -i s/"POA"/"${COIN}"/g apps/block_scout_web/p
# Run forderground build and phoenix digest
RUN mix compile
RUN npm install npm@latest
RUN npm install canvas
# Add blockscout npm deps
RUN cd apps/block_scout_web/assets/ && \
npm install && \

@ -281,6 +281,54 @@ endif
ifdef HIDE_BLOCK_MINER
BLOCKSCOUT_CONTAINER_PARAMS += -e 'HIDE_BLOCK_MINER=$(HIDE_BLOCK_MINER)'
endif
ifdef COIN_BALANCE_HISTORY_DAYS
BLOCKSCOUT_CONTAINER_PARAMS += -e 'COIN_BALANCE_HISTORY_DAYS=$(COIN_BALANCE_HISTORY_DAYS)'
endif
ifdef POS_STAKING_CONTRACT
BLOCKSCOUT_CONTAINER_PARAMS += -e 'POS_STAKING_CONTRACT=$(POS_STAKING_CONTRACT)'
endif
ifdef ENABLE_POS_STAKING_IN_MENU
BLOCKSCOUT_CONTAINER_PARAMS += -e 'ENABLE_POS_STAKING_IN_MENU=$(ENABLE_POS_STAKING_IN_MENU)'
endif
ifdef TOKEN_EXCHANGE_RATE_CACHE_PERIOD
BLOCKSCOUT_CONTAINER_PARAMS += -e 'TOKEN_EXCHANGE_RATE_CACHE_PERIOD=$(TOKEN_EXCHANGE_RATE_CACHE_PERIOD)'
endif
ifdef ADDRESS_TOKENS_USD_SUM_CACHE_PERIOD
BLOCKSCOUT_CONTAINER_PARAMS += -e 'ADDRESS_TOKENS_USD_SUM_CACHE_PERIOD=$(ADDRESS_TOKENS_USD_SUM_CACHE_PERIOD)'
endif
ifdef SHOW_MAINTENANCE_ALERT
BLOCKSCOUT_CONTAINER_PARAMS += -e 'SHOW_MAINTENANCE_ALERT=$(SHOW_MAINTENANCE_ALERT)'
endif
ifdef MAINTENANCE_ALERT_MESSAGE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'MAINTENANCE_ALERT_MESSAGE=$(MAINTENANCE_ALERT_MESSAGE)'
endif
ifdef SHOW_STAKING_WARNING
BLOCKSCOUT_CONTAINER_PARAMS += -e 'SHOW_STAKING_WARNING=$(SHOW_STAKING_WARNING)'
endif
ifdef STAKING_WARNING_MESSAGE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'STAKING_WARNING_MESSAGE=$(STAKING_WARNING_MESSAGE)'
endif
ifdef ENABLE_SOURCIFY_INTEGRATION
BLOCKSCOUT_CONTAINER_PARAMS += -e 'ENABLE_SOURCIFY_INTEGRATION=$(ENABLE_SOURCIFY_INTEGRATION)'
endif
ifdef SOURCIFY_SERVER_URL
BLOCKSCOUT_CONTAINER_PARAMS += -e 'SOURCIFY_SERVER_URL=$(SOURCIFY_SERVER_URL)'
endif
ifdef SOURCIFY_REPO_URL
BLOCKSCOUT_CONTAINER_PARAMS += -e 'SOURCIFY_REPO_URL=$(SOURCIFY_REPO_URL)'
endif
ifdef CHAIN_ID
BLOCKSCOUT_CONTAINER_PARAMS += -e 'CHAIN_ID=$(CHAIN_ID)'
endif
ifdef MAX_SIZE_UNLESS_HIDE_ARRAY
BLOCKSCOUT_CONTAINER_PARAMS += -e 'MAX_SIZE_UNLESS_HIDE_ARRAY=$(MAX_SIZE_UNLESS_HIDE_ARRAY)'
endif
ifdef ENABLE_1559_SUPPORT
BLOCKSCOUT_CONTAINER_PARAMS += -e 'ENABLE_1559_SUPPORT=$(ENABLE_1559_SUPPORT)'
endif
ifdef DISPLAY_TOKEN_ICONS
BLOCKSCOUT_CONTAINER_PARAMS += -e 'DISPLAY_TOKEN_ICONS=$(DISPLAY_TOKEN_ICONS)'
endif
HAS_BLOCKSCOUT_IMAGE := $(shell docker images | grep -sw ${DOCKER_IMAGE})
build:

Loading…
Cancel
Save