diff --git a/openapi/.openapi-generator/FILES b/openapi/.openapi-generator/FILES index efabcf67..f79065ae 100644 --- a/openapi/.openapi-generator/FILES +++ b/openapi/.openapi-generator/FILES @@ -10,5 +10,6 @@ src/Api/Request/Entities.elm src/Api/Request/General.elm src/Api/Request/Rates.elm src/Api/Request/Tags.elm +src/Api/Request/Tokens.elm src/Api/Request/Txs.elm src/Api/Time.elm diff --git a/openapi/src/Api/Data.elm b/openapi/src/Api/Data.elm index e4c14540..636ac621 100644 --- a/openapi/src/Api/Data.elm +++ b/openapi/src/Api/Data.elm @@ -47,6 +47,8 @@ module Api.Data exposing , Stats , Tag , Taxonomy + , TokenConfig + , TokenConfigs , Tx(..) , TxAccount , TxSummary @@ -85,6 +87,8 @@ module Api.Data exposing , encodeStats , encodeTag , encodeTaxonomy + , encodeTokenConfig + , encodeTokenConfigs , encodeTx , encodeTxAccount , encodeTxSummary @@ -123,6 +127,8 @@ module Api.Data exposing , statsDecoder , tagDecoder , taxonomyDecoder + , tokenConfigDecoder + , tokenConfigsDecoder , txDecoder , txAccountDecoder , txSummaryDecoder @@ -438,6 +444,18 @@ type alias Taxonomy = } +type alias TokenConfig = + { decimals : Int + , pegCurrency : Maybe String + , ticker : String + } + + +type alias TokenConfigs = + { tokenConfigs : List (TokenConfig) + } + + type Tx = TxTxAccount TxAccount | TxTxUtxo TxUtxo @@ -445,7 +463,8 @@ type Tx type alias TxAccount = - { currency : String + { contractCreation : Maybe Bool + , currency : String , fromAddress : String , height : Int , timestamp : Int @@ -1276,6 +1295,48 @@ encodeTaxonomyPairs model = pairs +encodeTokenConfig : TokenConfig -> Json.Encode.Value +encodeTokenConfig = + encodeObject << encodeTokenConfigPairs + + +encodeTokenConfigWithTag : ( String, String ) -> TokenConfig -> Json.Encode.Value +encodeTokenConfigWithTag (tagField, tag) model = + encodeObject (encodeTokenConfigPairs model ++ [ encode tagField Json.Encode.string tag ]) + + +encodeTokenConfigPairs : TokenConfig -> List EncodedField +encodeTokenConfigPairs model = + let + pairs = + [ encode "decimals" Json.Encode.int model.decimals + , maybeEncode "peg_currency" Json.Encode.string model.pegCurrency + , encode "ticker" Json.Encode.string model.ticker + ] + in + pairs + + +encodeTokenConfigs : TokenConfigs -> Json.Encode.Value +encodeTokenConfigs = + encodeObject << encodeTokenConfigsPairs + + +encodeTokenConfigsWithTag : ( String, String ) -> TokenConfigs -> Json.Encode.Value +encodeTokenConfigsWithTag (tagField, tag) model = + encodeObject (encodeTokenConfigsPairs model ++ [ encode tagField Json.Encode.string tag ]) + + +encodeTokenConfigsPairs : TokenConfigs -> List EncodedField +encodeTokenConfigsPairs model = + let + pairs = + [ encode "token_configs" (Json.Encode.list encodeTokenConfig) model.tokenConfigs + ] + in + pairs + + encodeTx : Tx -> Json.Encode.Value encodeTx model = case model of @@ -1302,7 +1363,8 @@ encodeTxAccountPairs : TxAccount -> List EncodedField encodeTxAccountPairs model = let pairs = - [ encode "currency" Json.Encode.string model.currency + [ maybeEncode "contract_creation" Json.Encode.bool model.contractCreation + , encode "currency" Json.Encode.string model.currency , encode "from_address" Json.Encode.string model.fromAddress , encode "height" Json.Encode.int model.height , encode "timestamp" Json.Encode.int model.timestamp @@ -1777,6 +1839,20 @@ taxonomyDecoder = |> decode "uri" Json.Decode.string +tokenConfigDecoder : Json.Decode.Decoder TokenConfig +tokenConfigDecoder = + Json.Decode.succeed TokenConfig + |> decode "decimals" Json.Decode.int + |> maybeDecode "peg_currency" Json.Decode.string Nothing + |> decode "ticker" Json.Decode.string + + +tokenConfigsDecoder : Json.Decode.Decoder TokenConfigs +tokenConfigsDecoder = + Json.Decode.succeed TokenConfigs + |> decode "token_configs" (Json.Decode.list tokenConfigDecoder) + + txDecoder : Json.Decode.Decoder Tx txDecoder = Json.Decode.field "tx_type" Json.Decode.string @@ -1800,6 +1876,7 @@ txTagDecoder tag = txAccountDecoder : Json.Decode.Decoder TxAccount txAccountDecoder = Json.Decode.succeed TxAccount + |> maybeDecode "contract_creation" Json.Decode.bool Nothing |> decode "currency" Json.Decode.string |> decode "from_address" Json.Decode.string |> decode "height" Json.Decode.int diff --git a/openapi/src/Api/Request/Tokens.elm b/openapi/src/Api/Request/Tokens.elm new file mode 100644 index 00000000..e486901d --- /dev/null +++ b/openapi/src/Api/Request/Tokens.elm @@ -0,0 +1,38 @@ +{- + GraphSense API + GraphSense API provides programmatic access to various ledgers' addresses, entities, blocks, transactions and tags for automated and highly efficient forensics tasks. + + The version of the OpenAPI document: 1.1.1 + Contact: contact@ikna.io + + NOTE: This file is auto generated by the openapi-generator. + https://github.com/openapitools/openapi-generator.git + + DO NOT EDIT THIS FILE MANUALLY. + + For more info on generating Elm code, see https://eriktim.github.io/openapi-elm/ +-} + + +module Api.Request.Tokens exposing (..) + +import Api +import Api.Data +import Dict +import Http +import Json.Decode +import Json.Encode + + + +listSupportedTokens : (String) -> Api.Request Api.Data.TokenConfigs +listSupportedTokens currency_path = + Api.request + "GET" + "/{currency}/supported_tokens" + [ ( "currency", identity currency_path ) ] + [] + [] + Nothing + Api.Data.tokenConfigsDecoder + diff --git a/public/lang/de.yaml b/public/lang/de.yaml index a34dc473..8c019fd1 100644 --- a/public/lang/de.yaml +++ b/public/lang/de.yaml @@ -282,3 +282,4 @@ no: nein "there are typos": "Es gibt Tippfehler" smart contract: Smart contract "token transactions of {0} ({1})": Token-Transaktionen von {0} ({1}) +"loading supported token currencies": lade unterstützte Token-Währungen diff --git a/src/Effect/Api.elm b/src/Effect/Api.elm index b580d91f..2b739193 100644 --- a/src/Effect/Api.elm +++ b/src/Effect/Api.elm @@ -8,6 +8,7 @@ import Api.Request.Entities import Api.Request.General import Api.Request.MyBulk import Api.Request.Tags +import Api.Request.Tokens import Api.Request.Txs import Dict exposing (Dict) import Http @@ -26,6 +27,7 @@ type Effect msg } (Api.Data.SearchResult -> msg) | GetConceptsEffect String (List Api.Data.Concept -> msg) + | ListSupportedTokensEffect (Api.Data.TokenConfigs -> msg) | GetAddressEffect { currency : String , address : String @@ -268,6 +270,11 @@ map mapMsg effect = >> mapMsg |> GetConceptsEffect eff + ListSupportedTokensEffect m -> + m + >> mapMsg + |> ListSupportedTokensEffect + GetAddressEffect eff m -> m >> mapMsg @@ -406,6 +413,10 @@ perform apiKey wrapMsg effect = Api.Request.Tags.listConcepts taxonomy |> send apiKey wrapMsg effect toMsg + ListSupportedTokensEffect toMsg -> + Api.Request.Tokens.listSupportedTokens "eth" + |> send apiKey wrapMsg effect toMsg + GetEntityNeighborsEffect { currency, entity, isOutgoing, pagesize, onlyIds, includeLabels, nextpage } toMsg -> let direction = diff --git a/src/Init.elm b/src/Init.elm index e03c0115..ac72a100 100644 --- a/src/Init.elm +++ b/src/Init.elm @@ -47,6 +47,7 @@ init plugins flags url key = , height = flags.height , error = "" , statusbar = Statusbar.init + , supportedTokens = Nothing , dialog = Nothing , plugins = pluginStates } @@ -55,6 +56,8 @@ init plugins flags url key = |> ApiEffect , Effect.Api.GetConceptsEffect "abuse" BrowserGotAbuseTaxonomy |> ApiEffect + , Effect.Api.ListSupportedTokensEffect BrowserGotSupportedTokens + |> ApiEffect , PluginEffect cmd ] ) diff --git a/src/Init/Locale.elm b/src/Init/Locale.elm index 95b462fc..3d375347 100644 --- a/src/Init/Locale.elm +++ b/src/Init/Locale.elm @@ -26,6 +26,7 @@ init { locale } = , currency = Coin , relativeTimeOptions = DateFormat.Relative.defaultRelativeOptions , unitToString = Locale.English.unitToString + , supportedTokens = Nothing } |> switch locale , [ Effect.Locale.getTranslationEffect locale diff --git a/src/Model.elm b/src/Model.elm index df008738..21814b7e 100644 --- a/src/Model.elm +++ b/src/Model.elm @@ -53,6 +53,7 @@ type alias Model navigationKey = , error : String , statusbar : Model.Statusbar.Model , dialog : Maybe (Model.Dialog.Model Msg) + , supportedTokens : Maybe Api.Data.TokenConfigs , plugins : Plugin.ModelState --Dict String Json.Encode.Value } @@ -87,6 +88,7 @@ type Msg | BrowserGotEntityTaxonomy (List Api.Data.Concept) | BrowserGotAbuseTaxonomy (List Api.Data.Concept) | BrowserGotElementForPlugin (Result Browser.Dom.Error Browser.Dom.Element -> Plugin.Msg) (Result Browser.Dom.Error Browser.Dom.Element) + | BrowserGotSupportedTokens Api.Data.TokenConfigs | UserClickedStatusbar | UserClosesDialog | LocaleMsg Msg.Locale.Msg diff --git a/src/Model/Locale.elm b/src/Model/Locale.elm index 0a6b14f7..b24ebe2e 100644 --- a/src/Model/Locale.elm +++ b/src/Model/Locale.elm @@ -1,5 +1,6 @@ module Model.Locale exposing (..) +import Api.Data import DateFormat.Language import DateFormat.Relative import Dict exposing (Dict) @@ -41,4 +42,5 @@ type alias Model = , currency : Currency , relativeTimeOptions : DateFormat.Relative.RelativeTimeOptions , unitToString : Int -> Locale.Durations.Unit -> String + , supportedTokens : Maybe Api.Data.TokenConfigs } diff --git a/src/RecordSetter.elm b/src/RecordSetter.elm index 8af39310..64b55761 100644 --- a/src/RecordSetter.elm +++ b/src/RecordSetter.elm @@ -569,11 +569,6 @@ s_caseInsensitive value__ record__ = { record__ | caseInsensitive = value__ } -s_casemgm_preview : a -> { b | casemgm_preview : a } -> { b | casemgm_preview : a } -s_casemgm_preview value__ record__ = - { record__ | casemgm_preview = value__ } - - s_categories : a -> { b | categories : a } -> { b | categories : a } s_categories value__ record__ = { record__ | categories = value__ } @@ -749,6 +744,11 @@ s_contentType value__ record__ = { record__ | contentType = value__ } +s_contents : a -> { b | contents : a } -> { b | contents : a } +s_contents value__ record__ = + { record__ | contents = value__ } + + s_context : a -> { b | context : a } -> { b | context : a } s_context value__ record__ = { record__ | context = value__ } @@ -764,6 +764,11 @@ s_contextStack value__ record__ = { record__ | contextStack = value__ } +s_contractCreation : a -> { b | contractCreation : a } -> { b | contractCreation : a } +s_contractCreation value__ record__ = + { record__ | contractCreation = value__ } + + s_coords : a -> { b | coords : a } -> { b | coords : a } s_coords value__ record__ = { record__ | coords = value__ } @@ -1664,9 +1669,9 @@ s_graph value__ record__ = { record__ | graph = value__ } -s_graphRoot : a -> { b | graphRoot : a } -> { b | graphRoot : a } -s_graphRoot value__ record__ = - { record__ | graphRoot = value__ } +s_graphNavbarLeft : a -> { b | graphNavbarLeft : a } -> { b | graphNavbarLeft : a } +s_graphNavbarLeft value__ record__ = + { record__ | graphNavbarLeft = value__ } s_green : a -> { b | green : a } -> { b | green : a } @@ -2554,6 +2559,11 @@ s_logo_lightmode value__ record__ = { record__ | logo_lightmode = value__ } +s_logout : a -> { b | logout : a } -> { b | logout : a } +s_logout value__ record__ = + { record__ | logout = value__ } + + s_logoutButton : a -> { b | logoutButton : a } -> { b | logoutButton : a } s_logoutButton value__ record__ = { record__ | logoutButton = value__ } @@ -3444,6 +3454,11 @@ s_pattern value__ record__ = { record__ | pattern = value__ } +s_pegCurrency : a -> { b | pegCurrency : a } -> { b | pegCurrency : a } +s_pegCurrency value__ record__ = + { record__ | pegCurrency = value__ } + + s_ph : a -> { b | ph : a } -> { b | ph : a } s_ph value__ record__ = { record__ | ph = value__ } @@ -4364,6 +4379,11 @@ s_suffix value__ record__ = { record__ | suffix = value__ } +s_supportedTokens : a -> { b | supportedTokens : a } -> { b | supportedTokens : a } +s_supportedTokens value__ record__ = + { record__ | supportedTokens = value__ } + + s_svgRoot : a -> { b | svgRoot : a } -> { b | svgRoot : a } s_svgRoot value__ record__ = { record__ | svgRoot = value__ } @@ -4634,6 +4654,11 @@ s_tickLength value__ record__ = { record__ | tickLength = value__ } +s_ticker : a -> { b | ticker : a } -> { b | ticker : a } +s_ticker value__ record__ = + { record__ | ticker = value__ } + + s_time : a -> { b | time : a } -> { b | time : a } s_time value__ record__ = { record__ | time = value__ } @@ -4724,6 +4749,11 @@ s_tokenBalances value__ record__ = { record__ | tokenBalances = value__ } +s_tokenConfigs : a -> { b | tokenConfigs : a } -> { b | tokenConfigs : a } +s_tokenConfigs value__ record__ = + { record__ | tokenConfigs = value__ } + + s_tokenTxId : a -> { b | tokenTxId : a } -> { b | tokenTxId : a } s_tokenTxId value__ record__ = { record__ | tokenTxId = value__ } diff --git a/src/Update.elm b/src/Update.elm index 5b7a30ee..a30e9822 100644 --- a/src/Update.elm +++ b/src/Update.elm @@ -112,6 +112,20 @@ update plugins uc msg model = } |> n + BrowserGotSupportedTokens configs -> + let + locale = + Locale.supportedTokens configs model.locale + in + { model + | supportedTokens = Just configs + , locale = locale + , config = + model.config + |> s_locale locale + } + |> n + BrowserGotResponseWithHeaders statusbarToken result -> { model | statusbar = @@ -199,9 +213,18 @@ update plugins uc msg model = } |> n - UserSwitchesLocale locale -> - ( { model | locale = Locale.switch locale model.locale } - , Locale.getTranslationEffect locale + UserSwitchesLocale loc -> + let + locale = + Locale.switch loc model.locale + in + ( { model + | locale = locale + , config = + model.config + |> s_locale locale + } + , Locale.getTranslationEffect loc |> LocaleEffect |> List.singleton ) @@ -353,8 +376,7 @@ update plugins uc msg model = UserClickedLogout -> let ( new, outMsg, cmd ) = - Plugin.logout plugins model.plugins - + Plugin.logout plugins model.plugins in ( { model | plugins = new @@ -371,10 +393,10 @@ update plugins uc msg model = ) } , [ PluginEffect cmd - , LogoutEffect - ] + , LogoutEffect + ] ) - |> updateByPluginOutMsg plugins outMsg + |> updateByPluginOutMsg plugins outMsg BrowserGotLoggedOut result -> { model diff --git a/src/Update/Graph/Browser.elm b/src/Update/Graph/Browser.elm index 860641a1..32c18c6f 100644 --- a/src/Update/Graph/Browser.elm +++ b/src/Update/Graph/Browser.elm @@ -2338,12 +2338,12 @@ tableAsCSV locale gc { type_ } = Just (AddressIncomingNeighborsTable t) -> loadableAddressToList loadable |> Locale.interpolated locale "Incoming neighbors of address {0} ({1})" - |> asCsv (AddressNeighborsTable.prepareCSV False (loadableAddressCurrency loadable)) t + |> asCsv (AddressNeighborsTable.prepareCSV locale False (loadableAddressCurrency loadable)) t Just (AddressOutgoingNeighborsTable t) -> loadableAddressToList loadable |> Locale.interpolated locale "Outgoing neighbors of address {0} ({1})" - |> asCsv (AddressNeighborsTable.prepareCSV True (loadableAddressCurrency loadable)) t + |> asCsv (AddressNeighborsTable.prepareCSV locale True (loadableAddressCurrency loadable)) t Nothing -> Nothing @@ -2371,12 +2371,12 @@ tableAsCSV locale gc { type_ } = Just (EntityIncomingNeighborsTable t) -> loadableEntityToList loadable |> Locale.interpolated locale "Incoming neighbors of entity {0} ({1})" - |> asCsv (EntityNeighborsTable.prepareCSV False (loadableEntityCurrency loadable)) t + |> asCsv (EntityNeighborsTable.prepareCSV locale False (loadableEntityCurrency loadable)) t Just (EntityOutgoingNeighborsTable t) -> loadableEntityToList loadable |> Locale.interpolated locale "Outgoing neighbors of entity {0} ({1})" - |> asCsv (EntityNeighborsTable.prepareCSV True (loadableEntityCurrency loadable)) t + |> asCsv (EntityNeighborsTable.prepareCSV locale True (loadableEntityCurrency loadable)) t Nothing -> Nothing diff --git a/src/Update/Locale.elm b/src/Update/Locale.elm index 77bb2296..cb3ab7e5 100644 --- a/src/Update/Locale.elm +++ b/src/Update/Locale.elm @@ -1,5 +1,6 @@ module Update.Locale exposing (..) +import Api.Data import DateFormat.Language import DateFormat.Relative import Dict @@ -127,3 +128,8 @@ changeCurrency curr model = fiat -> Fiat fiat } + + +supportedTokens : Api.Data.TokenConfigs -> Model -> Model +supportedTokens configs model = + { model | supportedTokens = Just configs } diff --git a/src/Update/Statusbar.elm b/src/Update/Statusbar.elm index f4f7bf94..61325a86 100644 --- a/src/Update/Statusbar.elm +++ b/src/Update/Statusbar.elm @@ -197,6 +197,12 @@ messageFromApiEffect model effect = ) |> Just + Api.ListSupportedTokensEffect _ -> + ( "loading supported token currencies" + , [] + ) + |> Just + Api.SearchEffect _ _ -> Nothing diff --git a/src/View/Graph/Table/AddressNeighborsTable.elm b/src/View/Graph/Table/AddressNeighborsTable.elm index fb2584bb..312f4897 100644 --- a/src/View/Graph/Table/AddressNeighborsTable.elm +++ b/src/View/Graph/Table/AddressNeighborsTable.elm @@ -11,6 +11,7 @@ import Init.Graph.Table import Model.Address as A import Model.Graph.Id exposing (AddressId) import Model.Graph.Table exposing (Table) +import Model.Locale as Locale import Msg.Graph exposing (Msg(..)) import Table import Util.Csv @@ -19,11 +20,6 @@ import View.Graph.Table as T exposing (customizations, valueColumn) import View.Locale as Locale -tokenCurrencies : List String -tokenCurrencies = - [ "usdt", "usdc", "weth" ] - - columnTitleFromDirection : Bool -> String columnTitleFromDirection isOutgoing = (if isOutgoing then @@ -121,7 +117,7 @@ config vc isOutgoing coinCode id neighborLayerHasAddress = ++ valueColumns vc coinCode (if coinCode == "eth" then - tokenCurrencies + Locale.tokenCurrencies vc.locale else [] @@ -244,8 +240,8 @@ n s = ( s, [] ) -prepareCSV : Bool -> String -> Api.Data.NeighborAddress -> List ( ( String, List String ), String ) -prepareCSV isOutgoing coinCode row = +prepareCSV : Locale.Model -> Bool -> String -> Api.Data.NeighborAddress -> List ( ( String, List String ), String ) +prepareCSV locale isOutgoing coinCode row = let suffix = if coinCode == "eth" then @@ -269,16 +265,16 @@ prepareCSV isOutgoing coinCode row = ++ Util.Csv.values ("address_received" ++ suffix) row.address.balance ++ Util.Csv.values (estimatedValueTitle ++ suffix) row.value ++ (if coinCode == "eth" then - prepareCsvTokens row + prepareCsvTokens locale row else [] ) -prepareCsvTokens : Api.Data.NeighborAddress -> List ( ( String, List String ), String ) -prepareCsvTokens row = - tokenCurrencies +prepareCsvTokens : Locale.Model -> Api.Data.NeighborAddress -> List ( ( String, List String ), String ) +prepareCsvTokens locale row = + Locale.tokenCurrencies locale |> List.map (\token -> Util.Csv.values ("address_balance_" ++ token) diff --git a/src/View/Graph/Table/EntityNeighborsTable.elm b/src/View/Graph/Table/EntityNeighborsTable.elm index e05b594e..64398c30 100644 --- a/src/View/Graph/Table/EntityNeighborsTable.elm +++ b/src/View/Graph/Table/EntityNeighborsTable.elm @@ -11,6 +11,7 @@ import Init.Graph.Table import Model.Entity as E import Model.Graph.Id exposing (EntityId) import Model.Graph.Table exposing (Table) +import Model.Locale as Locale import Msg.Graph exposing (Msg(..)) import Table import Util.Csv @@ -20,11 +21,6 @@ import View.Graph.Table.AddressNeighborsTable exposing (reduceLabels) import View.Locale as Locale -tokenCurrencies : List String -tokenCurrencies = - [ "usdt", "usdc", "weth" ] - - columnTitleFromDirection : Bool -> String columnTitleFromDirection isOutgoing = (if isOutgoing then @@ -130,7 +126,7 @@ config vc isOutgoing coinCode id neighborLayerHasEntity = ++ valueColumns vc coinCode (if coinCode == "eth" then - [ "usdt", "usdc", "weth" ] + Locale.tokenCurrencies vc.locale else [] @@ -212,8 +208,8 @@ n s = ( s, [] ) -prepareCSV : Bool -> String -> Api.Data.NeighborEntity -> List ( ( String, List String ), String ) -prepareCSV isOutgoing coinCode row = +prepareCSV : Locale.Model -> Bool -> String -> Api.Data.NeighborEntity -> List ( ( String, List String ), String ) +prepareCSV locale isOutgoing coinCode row = let suffix = if coinCode == "eth" then @@ -238,16 +234,16 @@ prepareCSV isOutgoing coinCode row = ++ Util.Csv.values ("entity_balance" ++ suffix) row.entity.balance ++ Util.Csv.values (estimatedValueTitle ++ suffix) row.value ++ (if coinCode == "eth" then - prepareCsvTokens row + prepareCsvTokens locale row else [] ) -prepareCsvTokens : Api.Data.NeighborEntity -> List ( ( String, List String ), String ) -prepareCsvTokens row = - tokenCurrencies +prepareCsvTokens : Locale.Model -> Api.Data.NeighborEntity -> List ( ( String, List String ), String ) +prepareCsvTokens locale row = + Locale.tokenCurrencies locale |> List.map (\token -> Util.Csv.values ("entity_balance_" ++ token) diff --git a/src/View/Locale.elm b/src/View/Locale.elm index cd0a77a3..d02caf51 100644 --- a/src/View/Locale.elm +++ b/src/View/Locale.elm @@ -13,6 +13,7 @@ module View.Locale exposing , text , timestamp , timestampWithFormat + , tokenCurrencies , tokenCurrency ) @@ -34,17 +35,24 @@ import Time import Tuple exposing (..) -fixpointFactor : Dict String ( Float, String ) -fixpointFactor = +fixpointFactor : Maybe Api.Data.TokenConfigs -> Dict String ( Float, String ) +fixpointFactor configs = [ ( "eth", ( 1.0e18, "wei" ) ) - , ( "weth", ( 1.0e18, "wei" ) ) - , ( "usdc", ( 1.0e6, "wei" ) ) - , ( "usdt", ( 1.0e6, "wei" ) ) , ( "btc", ( 1.0e8, "s" ) ) , ( "bch", ( 1.0e8, "s" ) ) , ( "ltc", ( 1.0e8, "s" ) ) , ( "zec", ( 1.0e8, "s" ) ) ] + ++ (configs + |> Maybe.map + (.tokenConfigs + >> List.map + (\{ decimals, ticker } -> + ( ticker, ( 10 ^ toFloat decimals, "wei" ) ) + ) + ) + |> Maybe.withDefault [] + ) |> Dict.fromList @@ -256,7 +264,8 @@ fiat model coinCode vis { code, value } = coin : Model -> Bool -> String -> Int -> String coin model hideCode code v = - Dict.get code fixpointFactor + fixpointFactor model.supportedTokens + |> Dict.get code |> Maybe.map (mapFirst (\f -> @@ -296,3 +305,10 @@ durationToString { unitToString } dur = , separator = " " } dur + + +tokenCurrencies : Model -> List String +tokenCurrencies model = + model.supportedTokens + |> Maybe.map (.tokenConfigs >> List.map .ticker) + |> Maybe.withDefault []