Merge pull request #495 from poanetwork/frg-fix-token-transfers-in-ui

Fix tokens transfers info according to the tokens' type
pull/512/head
Felipe Renan 6 years ago committed by GitHub
commit 4a72926d57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      apps/explorer_web/lib/explorer_web.ex
  2. 2
      apps/explorer_web/lib/explorer_web/templates/address_transaction/_transaction.html.eex
  3. 23
      apps/explorer_web/lib/explorer_web/views/address_transaction_view.ex
  4. 40
      apps/explorer_web/lib/explorer_web/views/currency_helpers.ex
  5. 60
      apps/explorer_web/lib/explorer_web/views/token_helpers.ex
  6. 37
      apps/explorer_web/test/explorer_web/views/address_transaction_view_test.exs
  7. 37
      apps/explorer_web/test/explorer_web/views/currency_helpers_test.exs
  8. 62
      apps/explorer_web/test/explorer_web/views/token_helpers_test.exs

@ -41,7 +41,14 @@ defmodule ExplorerWeb do
# Use all HTML functionality (forms, tags, etc)
use Phoenix.HTML
import ExplorerWeb.{CurrencyHelpers, ErrorHelpers, Gettext, Router.Helpers, WeiHelpers}
import ExplorerWeb.{
CurrencyHelpers,
ErrorHelpers,
Gettext,
Router.Helpers,
TokenHelpers,
WeiHelpers
}
end
end

@ -77,7 +77,7 @@
</span>
</span>
<span class="tile-title">
<%= formatted_token_amount(token_transfer.amount, token_transfer.token.decimals) %> <%= token_transfer.token.symbol %>
<%= token_transfer_amount(token_transfer) %> <%= token_symbol(token_transfer.token) %>
</span>
</div>
<div class="col-md-3 col-lg-2 d-flex flex-row flex-md-column align-items-end">

@ -14,29 +14,6 @@ defmodule ExplorerWeb.AddressTransactionView do
end
end
@doc """
Formats the given amount according to given decimals.
## Examples
iex> ExplorerWeb.AddressTransactionView.formatted_token_amount(Decimal.new(20500000), 5)
"205"
iex> ExplorerWeb.AddressTransactionView.formatted_token_amount(Decimal.new(20500000), 7)
"2.05"
iex> ExplorerWeb.AddressTransactionView.formatted_token_amount(Decimal.new(205000), 12)
"0.000000205"
"""
@spec formatted_token_amount(Decimal.t(), non_neg_integer()) :: String.t()
def formatted_token_amount(%Decimal{sign: sign, coef: coef, exp: exp}, decimals) do
sign
|> Decimal.new(coef, exp - decimals)
|> Decimal.reduce()
|> Decimal.to_string(:normal)
end
def from_or_to_address?(%{from_address_hash: from_hash, to_address_hash: to_hash}, %Address{hash: hash}) do
from_hash == hash || to_hash == hash
end

@ -33,4 +33,44 @@ defmodule ExplorerWeb.CurrencyHelpers do
_ -> nil
end
end
@spec format_integer_to_currency(non_neg_integer()) :: String.t()
def format_integer_to_currency(value) do
{:ok, formatted} = Cldr.Number.to_string(value, format: "#,##0")
formatted
end
@doc """
Formats the given amount according to given decimals.
## Examples
iex> format_according_to_decimals(Decimal.new(20500000), 5)
"205"
iex> format_according_to_decimals(Decimal.new(20500000), 7)
"2.05"
iex> format_according_to_decimals(Decimal.new(205000), 12)
"0.000000205"
iex> format_according_to_decimals(Decimal.new(205000), 2)
"2,050"
"""
@spec format_according_to_decimals(Decimal.t(), non_neg_integer()) :: String.t()
def format_according_to_decimals(%Decimal{sign: sign, coef: coef, exp: exp}, decimals) do
sign
|> Decimal.new(coef, exp - decimals)
|> Decimal.reduce()
|> thousands_separator()
end
defp thousands_separator(value) do
if Decimal.to_float(value) > 999 do
Cldr.Number.to_string!(value)
else
Decimal.to_string(value, :normal)
end
end
end

@ -0,0 +1,60 @@
defmodule ExplorerWeb.TokenHelpers do
@moduledoc """
Helper functions for intereacting with `t:ExplorerWeb.Chain.Token` attributes.
"""
alias Explorer.Chain.{Token, TokenTransfer}
alias ExplorerWeb.{CurrencyHelpers}
@doc """
Returns the token transfers' amount according to the token's type and decimails.
When the token's type is ERC-20, then we are going to format the amount according to the token's
decimals considering 0 when the decimals is nil. Case the amount is nil, this function will
return the symbol `--`.
When the token's type is ERC-721, the function will return a string with the token_id that
represents the ERC-721 token since this kind of token doesn't have amount and decimals.
"""
def token_transfer_amount(%TokenTransfer{token: token, amount: amount, token_id: token_id}) do
do_token_transfer_amount(token, amount, token_id)
end
defp do_token_transfer_amount(%Token{type: "ERC-20"}, nil, _token_id) do
"--"
end
defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: nil}, amount, _token_id) do
CurrencyHelpers.format_according_to_decimals(amount, 0)
end
defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: decimals}, amount, _token_id) do
CurrencyHelpers.format_according_to_decimals(amount, decimals)
end
defp do_token_transfer_amount(%Token{type: "ERC-721"}, _amount, token_id) do
"TokenID [#{token_id}]"
end
defp do_token_transfer_amount(_token, _amount, _token_id) do
nil
end
@doc """
Returns the token's symbol.
When the token's symbol is nil, the function will return the contract address hash.
"""
def token_symbol(%Token{symbol: nil, contract_address_hash: address_hash}) do
address_hash =
address_hash
|> to_string()
|> String.slice(0..6)
"#{address_hash}..."
end
def token_symbol(%Token{symbol: symbol}) do
symbol
end
end

@ -1,37 +0,0 @@
defmodule ExplorerWeb.AddresstransactionViewTest do
use ExplorerWeb.ConnCase, async: true
alias ExplorerWeb.AddressTransactionView
doctest ExplorerWeb.AddressTransactionView
describe "formatted_token_amount/1" do
test "formats the amount as value considering the given decimals" do
amount = Decimal.new(205_000_000_000_000)
decimals = 12
assert AddressTransactionView.formatted_token_amount(amount, decimals) == "205"
end
test "considers the decimal places according to the given decimals" do
amount = Decimal.new(205_000)
decimals = 12
assert AddressTransactionView.formatted_token_amount(amount, decimals) == "0.000000205"
end
test "does not consider right zeros in decimal places" do
amount = Decimal.new(90_000_000)
decimals = 6
assert AddressTransactionView.formatted_token_amount(amount, decimals) == "90"
end
test "returns the full number when there is no right zeros in decimal places" do
amount = Decimal.new(9_324_876)
decimals = 6
assert AddressTransactionView.formatted_token_amount(amount, decimals) == "9.324876"
end
end
end

@ -13,4 +13,41 @@ defmodule ExplorerWeb.CurrencyHelpersTest do
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)
decimals = 12
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "205"
end
test "considers the decimal places according to the given decimals" do
amount = Decimal.new(205_000)
decimals = 12
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "0.000000205"
end
test "does not consider right zeros in decimal places" do
amount = Decimal.new(90_000_000)
decimals = 6
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "90"
end
test "returns the full number when there is no right zeros in decimal places" do
amount = Decimal.new(9_324_876)
decimals = 6
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "9.324876"
end
test "formats the value considering thousands separators" do
amount = Decimal.new(1_000_450)
decimals = 2
assert CurrencyHelpers.format_according_to_decimals(amount, decimals) == "10,004.5"
end
end
end

@ -0,0 +1,62 @@
defmodule ExplorerWeb.TokenHelpersTest do
use ExplorerWeb.ConnCase, async: true
alias ExplorerWeb.{TokenHelpers}
describe "token_transfer_amount/1" do
test "returns the symbol -- with ERC-20 token and amount nil" do
token = build(:token, type: "ERC-20")
token_transfer = build(:token_transfer, token: token, amount: nil)
assert TokenHelpers.token_transfer_amount(token_transfer) == "--"
end
test "returns the formatted amount according to token decimals with ERC-20 token" do
token = build(:token, type: "ERC-20", decimals: 6)
token_transfer = build(:token_transfer, token: token, amount: Decimal.new(1_000_000))
assert TokenHelpers.token_transfer_amount(token_transfer) == "1"
end
test "returns the formatted amount when the decimals is nil with ERC-20 token" do
token = build(:token, type: "ERC-20", decimals: nil)
token_transfer = build(:token_transfer, token: token, amount: Decimal.new(1_000_000))
assert TokenHelpers.token_transfer_amount(token_transfer) == "1,000,000"
end
test "returns a string with the token_id with ERC-721 token" do
token = build(:token, type: "ERC-721", decimals: nil)
token_transfer = build(:token_transfer, token: token, amount: nil, token_id: 1)
assert TokenHelpers.token_transfer_amount(token_transfer) == "TokenID [1]"
end
test "returns nothing for unknow token's type" do
token = build(:token, type: "unknow")
token_transfer = build(:token_transfer, token: token)
assert TokenHelpers.token_transfer_amount(token_transfer) == nil
end
end
describe "token_symbol/1" do
test "returns the token symbol" do
token = build(:token, symbol: "BAT")
assert TokenHelpers.token_symbol(token) == "BAT"
end
test "returns the token contract address hash when the symbol is nil" do
address = build(:address)
token = build(:token, symbol: nil, contract_address_hash: address.hash)
address_hash =
address.hash
|> Explorer.Chain.Hash.to_string()
|> String.slice(0..6)
assert TokenHelpers.token_symbol(token) == "#{address_hash}..."
end
end
end
Loading…
Cancel
Save