diff options
74 files changed, 1320 insertions, 396 deletions
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index aea66845f..26d0422cb 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -692,9 +692,27 @@ "newRecipient": { "message": "New Recipient" }, - "newRPC": { + "newNetwork": { + "message": "New Network" + }, + "rpcURL": { "message": "New RPC URL" }, + "showAdvancedOptions": { + "message": "Show Advanced Options" + }, + "hideAdvancedOptions": { + "message": "Hide Advanced Options" + }, + "optionalChainId": { + "message": "ChainID (optional)" + }, + "optionalSymbol": { + "message": "Symbol (optional)" + }, + "optionalNickname": { + "message": "Nickname (optional)" + }, "next": { "message": "Next" }, @@ -803,7 +821,7 @@ "message": "Primary Currency" }, "primaryCurrencySettingDescription": { - "message": "Select ETH to prioritize displaying values in ETH. Select Fiat to prioritize displaying values in your selected currency." + "message": "Select native to prioritize displaying values in the native currency of the chain (e.g. ETH). Select Fiat to prioritize displaying values in your selected fiat currency." }, "privacyMsg": { "message": "Privacy Policy" diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index a4b04d34b..242cf66bf 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -1,6 +1,48 @@ { + "privacyMode": { + "message": "Način zasebnosti" + }, + "privacyModeDescription": { + "message": "Spletne strani morajo zahtevati dostop za ogled podatkov o vašem računu." + }, + "exposeAccounts": { + "message": "Razkrij račune" + }, + "exposeDescription": { + "message": "Razkrij račune trenutni spletni strani. Priporočeno za starejše dApps." + }, + "confirmExpose": { + "message": "Ste prepričani da želite razkriti račune trenutni spletni strani?" + }, + "confirmClear": { + "message": "Ste prepričani da želite počistiti odobrene spletne strani?" + }, + "clearApprovalDataSuccess": { + "message": "Odobrene spletne strani uspešno počiščene." + }, + "approvalData": { + "message": "Zasebni podatki" + }, + "approvalDataDescription": { + "message": "Počistite zasebne podatke, tako da bodo morale vse spletne strani ponovno zahtevati dovoljenje." + }, + "clearApprovalData": { + "message": "Počisti zasebne podatke" + }, + "providerAPIRequest": { + "message": "Zahteva za Ethereum API" + }, + "reviewProviderRequest": { + "message": "Preglejte zahtevo za Ethereum API." + }, + "providerRequestInfo": { + "message": "Domena zahteva dostop do verige blokov in ogled vašega računa. Pred potrditvjo vedno preverite ali ste na želeni spletni strani." + }, "accept": { - "message": "Sprejmi" + "message": "Potrdi" + }, + "accessingYourCamera": { + "message": "Dostopanje do vaše kamere ..." }, "account": { "message": "Račun" @@ -11,6 +53,15 @@ "accountName": { "message": "Ime računa" }, + "accountOptions": { + "message": "Možnosti računa" + }, + "accountSelectionRequired": { + "message": "Izbrati morate račun!" + }, + "activityLog": { + "message": "dnevnik dejavnosti" + }, "address": { "message": "Naslov" }, @@ -23,6 +74,12 @@ "addTokens": { "message": "Dodaj žetone" }, + "addSuggestedTokens": { + "message": "Dodaj priporočene žetone" + }, + "addAcquiredTokens": { + "message": "Dodaj žetone pridobljene z MetaMask" + }, "amount": { "message": "Znesek" }, @@ -37,9 +94,21 @@ "message": "MetaMask", "description": "The name of the application" }, + "approve": { + "message": "Potrdi" + }, + "approved": { + "message": "Potrjeno" + }, "attemptingConnect": { "message": "Povezovanje z verigo blokov ..." }, + "attemptToCancel": { + "message": "Želite preklicati?" + }, + "attemptToCancelDescription": { + "message": "Če pošljete ta poskus, ne boste zagotovili, da bo vaša prvotna transakcija preklicana. Če bo poskus preklica uspešen, se bo zaračunala zgornja transakcija." + }, "attributions": { "message": "Dodelitve" }, @@ -50,13 +119,13 @@ "message": "Nazaj" }, "balance": { - "message": "Znesek:" + "message": "Znesek" }, "balances": { - "message": "Vaš znesek" + "message": "Znesek žetonov" }, "balanceIsInsufficientGas": { - "message": "Napačen znesek za skupno gas vrednost" + "message": "Nezadnosten znesek za trenutni gas" }, "beta": { "message": "BETA" @@ -66,13 +135,16 @@ "description": "helper for inputting hex as decimal input" }, "blockiesIdenticon": { - "message": "Uporabite Blockies Identicon" + "message": "Uporabi identifikacijo Blockies" }, "borrowDharma": { "message": "Izposoja z Dharma (Beta)" }, + "browserNotSupported": { + "message": "Vaš brskalnik ni podptrt ..." + }, "builtInCalifornia": { - "message": "MetaMask je ustvarjen v Kaliforniji." + "message": "MetaMask je zasnovan in ustvarjen v Kaliforniji." }, "buy": { "message": "Kupi" @@ -83,18 +155,45 @@ "buyCoinbaseExplainer": { "message": "Coinbase je najpopularnejši načun za kupovanje in prodajo bitcoinov, ethereuma, in litecoina." }, + "bytes": { + "message": "Bajti" + }, + "ok": { + "message": "V redu" + }, "cancel": { "message": "Prekliči" }, + "cancelAttempt": { + "message": "Prekliči poskus" + }, + "cancellationGasFee": { + "message": "Preklicani znesek gas" + }, + "cancelN": { + "message": "Prekliči vseh $1 transakcij" + }, "classicInterface": { - "message": "Uporabi navaden način" + "message": "Uporabi klasični vmesnik" }, "clickCopy": { "message": "Kliknite za kopiranje" }, + "clickToAdd": { + "message": "Kliknite na $1 za dodajo v vaš račun" + }, + "close": { + "message": "Zapri" + }, + "chromeRequiredForHardwareWallets": { + "message": "Za uporabo strojne denarnice potrebujete Google Chrome." + }, "confirm": { "message": "Potrdi" }, + "confirmed": { + "message": "Potrjeno" + }, "confirmContract": { "message": "Potrdi pogodbo" }, @@ -104,6 +203,36 @@ "confirmTransaction": { "message": "Potrdi transakcijo" }, + "connectHardwareWallet": { + "message": "Poveži strojno denarnico" + }, + "connect": { + "message": "Poveži" + }, + "connecting": { + "message": "Povezovanje ..." + }, + "connectingToKovan": { + "message": "Povezovanje na testno omrežje Kovan" + }, + "connectingToMainnet": { + "message": "Povezovanje na glavno omrežje" + }, + "connectingToRopsten": { + "message": "Povezovanje na testno omrežje Ropsten" + }, + "connectingToRinkeby": { + "message": "Povezovanje na testno omrežje Rinkeby" + }, + "connectingToUnknown": { + "message": "Povezovanje na neznano omrežje" + }, + "connectToLedger": { + "message": "Poveži z Ledger" + }, + "connectToTrezor": { + "message": "Poveži z Trezor" + }, "continue": { "message": "Nadaljuj" }, @@ -114,23 +243,26 @@ "message": "Ustvarjanje pogodbe" }, "conversionProgress": { - "message": "Poteka pretvorba" + "message": "Pretvorba v teku" }, "copiedButton": { "message": "Kopirano" }, "copiedClipboard": { - "message": "Kopirano v odložišče" + "message": "Kopirano v odložišče!" }, "copiedExclamation": { "message": "Kopirano!" }, "copiedSafe": { - "message": "Prilepil sem ga na varno!" + "message": "Prilepil sem ga na varno" }, "copy": { "message": "Kopiraj" }, + "copyAddress": { + "message": "Kopiraj naslov v odložišče" + }, "copyToClipboard": { "message": "Kopiraj v odložišče" }, @@ -154,31 +286,40 @@ "description": "Exchange type (cryptocurrencies)" }, "currentConversion": { - "message": "Trenutna cena" + "message": "Trenutna pretvorba" + }, + "currentLanguage": { + "message": "Trenutni jezik" }, "currentNetwork": { "message": "Trenutno omrežje" }, + "currentRpc": { + "message": "Trenutni RPC" + }, "customGas": { "message": "Prilagodi gas" }, + "customToken": { + "message": "Žeton po meri" + }, "customize": { "message": "Prilagodi" }, "customRPC": { - "message": "Poljuben RPC" + "message": "RPC po meri" }, "decimalsMustZerotoTen": { - "message": "Decimalk mora biti vsaj 0, in ne več kot 36." + "message": "Decimalk mora biti med 0 in 36." }, "decimal": { - "message": "Decimalke natančnosti" + "message": "Decimalna natančnost" }, "defaultNetwork": { - "message": "Privzeto omrežje za transakcije je Main Net." + "message": "Privzeto omrežje za transkacije je glavno omrežje." }, "denExplainer": { - "message": "DEN je vaša šifrirana shramba v MetaMasku." + "message": "Vaš DEN je z geslom šifrirana shramba v MetaMask." }, "deposit": { "message": "Vplačaj" @@ -187,14 +328,14 @@ "message": "Vplačajte vaš BTC na spodnji naslov:" }, "depositCoin": { - "message": "Vplačajte $1 na spodnji naslov", + "message": "Vplačajte vaš $1 na spodnji naslov", "description": "Tells the user what coin they have selected to deposit with shapeshift" }, "depositEth": { "message": "Vplačilo ETH" }, "depositEther": { - "message": "Vplačilo ethera" + "message": "Vplačilo ethra" }, "depositFiat": { "message": "Vplačilo s klasičnimi valutami" @@ -206,25 +347,34 @@ "message": "Vplačilo z ShapeShift" }, "depositShapeShiftExplainer": { - "message": "Če imate druge kriptovalute, lahko vpačate ether neposredno v MetaMask. Brez računov." + "message": "Če imate druge kriptovalute, lahko Ether vplačate neposredno v MetaMask. Brez računov." }, "details": { "message": "Podrobnosti" }, "directDeposit": { - "message": "Direktno vplačilo" + "message": "Neposredno vplačilo" }, "directDepositEther": { - "message": "Direktno vplačilo ehera" + "message": "Neposredno vplačilo ehera" }, "directDepositEtherExplainer": { - "message": "Če že imate ether, ga lahko najhitreje dobite v MetaMask z direktnim vplačilom." + "message": "Če že imate Ether, ga lahko najhitreje dobite v MetaMask z neposrednim vplačilom." }, "done": { "message": "Končano" }, + "downloadGoogleChrome": { + "message": "Prenesi Google Chrome" + }, "downloadStateLogs": { - "message": "Prenesi state dnevnike" + "message": "Prenesi dnevnike state" + }, + "dontHaveAHardwareWallet": { + "message": "Nimate strojne denarnice?" + }, + "dropped": { + "message": "Izpusti" }, "edit": { "message": "Uredi" @@ -232,62 +382,83 @@ "editAccountName": { "message": "Uredi ime računa" }, + "editingTransaction": { + "message": "Uredite transakcijo" + }, "emailUs": { "message": "Pišite nam!" }, "encryptNewDen": { - "message": "Šifrirajte DEN" + "message": "Šifrirajte vaš DEN" + }, + "ensNameNotFound": { + "message": "Ime ENS ni najdeno" }, "enterPassword": { - "message": "Vpišite geslo" + "message": "Vnesite geslo" }, "enterPasswordConfirm": { "message": "Potrdite geslo" }, + "enterPasswordContinue": { + "message": "Za nadaljevanje vnesite geslo" + }, + "eth": { + "message": "ETH" + }, "etherscanView": { - "message": "Poglejte račun na Etherscan" + "message": "Poglej račun na Etherscan" }, "exchangeRate": { "message": "Menjalni tečaj" }, + "expandView": { + "message": "Razširi pogled" + }, "exportPrivateKey": { "message": "Izvozi zasebni ključ" }, "exportPrivateKeyWarning": { - "message": "Izvažanje zasebnih ključev je na lastno odgovornost." + "message": "Izvoz zasebnega ključa na lastno odgovornost." }, "failed": { "message": "Ni uspelo" }, "fiat": { - "message": "FIAT", + "message": "Klasične", "description": "Exchange type" }, "fileImportFail": { - "message": "Uvoz z datoteko ni uspel? Kliknite tukaj!", + "message": "Uvoz z datoteko ne deluje? Kliknite tukaj!", "description": "Helps user import their account from a JSON file" }, "followTwitter": { "message": "Sledite nam na Twitterju" }, + "forgetDevice": { + "message": "Pozabi to napravo" + }, "from": { "message": "Od" }, "fromToSame": { - "message": "From and To address cannot be the same" + "message": "Naslova pošiljatelja in prejemnika ne smeta biti enaka" }, "fromShapeShift": { "message": "Od ShapeShift" }, + "functionType": { + "message": "Vrsta funkcije" + }, "gas": { "message": "Gas", "description": "Short indication of gas cost" }, "gasFee": { - "message": "Gas fee" + "message": "Gas Fee" }, "gasLimit": { - "message": "Gas limit" + "message": "Gas Limit" }, "gasLimitCalculation": { "message": "Priporočen gas limit je izračunan glede na omrežje." @@ -296,37 +467,64 @@ "message": "Gas limit je zahtevan" }, "gasLimitTooLow": { - "message": "Gas limit mora biti najmanj 21000" + "message": "Gas limit mora biti vsaj 21000" + }, + "gasUsed": { + "message": "Uporabljen gas" }, "generatingSeed": { "message": "Ustvarjenje seed ..." }, "gasPrice": { - "message": "Gas price (GWEI)" + "message": "Gas Price (GWEI)" }, "gasPriceCalculation": { - "message": "Priporočen gas price je izračunan glede na omrežje" + "message": "Priporočen gas price je izračunan glede na omrežje." }, "gasPriceRequired": { "message": "Gas price je zahtevan" }, + "generatingTransaction": { + "message": "Ustvarjanje transakcije" + }, "getEther": { - "message": "Pridobite ether" + "message": "Pridobi Ether" }, "getEtherFromFaucet": { - "message": "Pridobite ether iz fauceta za $1", + "message": "Pridobite Ether iz fauceta za $1", "description": "Displays network name for Ether faucet" }, + "getHelp": { + "message": "Get Help." + }, "greaterThanMin": { - "message": "mora biti višji ali enak $1.", + "message": "mora biti večji ali enak $1.", "description": "helper for inputting hex as decimal input" }, + "hardware": { + "message": "strojna" + }, + "hardwareWalletConnected": { + "message": "Strojna denarnica povezana" + }, + "hardwareWallets": { + "message": "Poveži strojno denarnico" + }, + "hardwareWalletsMsg": { + "message": "Izberite vrsto strojne denarnice" + }, + "havingTroubleConnecting": { + "message": "Imate težave?" + }, "here": { "message": "tukaj", "description": "as in -click here- for more information (goes with troubleTokenBalances)" }, "hereList": { - "message": "Tukaj je seznam!!!" + "message": "Tukaj je seznam!!!!" + }, + "hexData": { + "message": "Hex Data" }, "hide": { "message": "Skrij" @@ -337,24 +535,27 @@ "hideTokenPrompt": { "message": "Skrijem žeton?" }, + "history": { + "message": "Zgodovina" + }, "howToDeposit": { - "message": "Kako želite vplačati ether?" + "message": "Kako želite vplačati Ether?" }, "holdEther": { - "message": "Omogoča vam, da imate eter in žetone in služi kot most za decentralizirane aplikacije." + "message": "Omogoča vam shranjevanje ethra in žetonov ter povezovanje decentraliziranih aplikacij." }, "import": { - "message": "Uvozi", + "message": "Uvoz", "description": "Button to import an account from a selected file" }, "importAccount": { - "message": "Uvozi račun" + "message": "Uvoz računa" }, "importAccountMsg": { - "message": " Uvoženi računi ne bodo povezani s prvotnim seedphaseom. Preberite več o uvoženih računih " + "message": " Uvoženi računa ne bodo povezani s prvotnim seed phase. Preberite več o uvoženih računih " }, "importAnAccount": { - "message": "Uvozi račun" + "message": "IUvozi račun" }, "importDen": { "message": "Uvozi DEN" @@ -363,9 +564,18 @@ "message": "Uvoženo", "description": "status showing that an account has been fully loaded into the keyring" }, + "importUsingSeed": { + "message": "Uvozi z seed phase" + }, + "info": { + "message": "Info" + }, "infoHelp": { "message": "Info & Pomoč" }, + "initialTransactionConfirmed": { + "message": "Vaša prvotna transakcija je bila potrjena. Pritisnite V redu in se vrnite nazaj." + }, "insufficientFunds": { "message": "Nezadostna sredstva." }, @@ -373,45 +583,63 @@ "message": "Nezadostni žetoni." }, "invalidAddress": { - "message": "Nepravilen naslov" + "message": "Neveljaven naslov" }, "invalidAddressRecipient": { - "message": "Prejemnikov naslov je neveljaven" + "message": "Neveljaven nasklov prejemnika" }, "invalidGasParams": { - "message": "Nepravilno nastavljen gas" + "message": "Neveljavne gas nastavitve" }, "invalidInput": { - "message": "Napačen vnos." + "message": "Neveljaven vnos." }, "invalidRequest": { - "message": "Napačna zahteva" + "message": "Neveljavna zahteva" }, "invalidRPC": { - "message": "Napačen RPC URI" + "message": "Neveljaven RPC URL" + }, + "invalidSeedPhrase": { + "message": "Neveljavna seed phrase" }, "jsonFail": { - "message": "Nekaj je bilo narobe. Prepričajte se, da je JSON datoteka pravilno oblikovana." + "message": "Nekaj je bilo narobe. Prepričajte se, da je datoteka JSON pravilno oblikovana." }, "jsonFile": { - "message": "JSON datoteka", + "message": "Datoteka JSON", "description": "format for importing an account" }, + "keepTrackTokens": { + "message": "Sledite žetonom, ki ste jih pridobili z MetaMask." + }, "kovan": { "message": "Testno omrežje Kovan" }, "knowledgeDataBase": { "message": "Obiščite našo pomoč" }, + "max": { + "message": "Max" + }, + "learnMore": { + "message": "Preberite več" + }, + "ledgerAccountRestriction": { + "message": "Za dodajanje novega računa morate uporabiti zadnji račun." + }, "lessThanMax": { - "message": "mora biti večji ali enak $1.", + "message": "mora biti manjši ali enak $1.", "description": "helper for inputting hex as decimal input" }, "likeToAddTokens": { "message": "Želite dodati te žetone?" }, + "links": { + "message": "Povezave" + }, "limit": { - "message": "Omejitev" + "message": "Meja" }, "loading": { "message": "Nalaganje ..." @@ -432,20 +660,32 @@ "message": "Loose" }, "loweCaseWords": { - "message": "seed words imajo lahko le male črke" + "message": "seed words lahko vsebujejo samo male črke" }, "mainnet": { "message": "Glavno omrežje" }, + "menu": { + "message": "Meni" + }, "message": { "message": "Sporočilo" }, "metamaskDescription": { "message": "MetaMask je varen identitetni sklad za Ethereum." }, + "metamaskSeedWords": { + "message": "Seed Words" + }, + "metamaskVersion": { + "message": "Različica" + }, "min": { "message": "Najmanj" }, + "missingYourTokens": { + "message": "Ne vidite vaših žetonov?" + }, "myAccounts": { "message": "Moji računi" }, @@ -453,7 +693,7 @@ "message": "Izbran mora biti vsaj 1 žeton." }, "needEtherInWallet": { - "message": "Za interakcijo z decentraliziranimi aplikacijami, ki uporabljajo MetaMask, boste v svoji denarnici potrebovali eter." + "message": "Za interakcijo z decentraliziranimi aplikacijami boste v svoji denarnici potrebovali Eter." }, "needImportFile": { "message": "Za uvoz morate izbrati datoteko.", @@ -464,11 +704,14 @@ "description": "Password and file needed to import an account" }, "negativeETH": { - "message": "Ni mogoče poslati negativne vsote ETH." + "message": "Negativnih zneskov ETH ni mogoče poslati." }, "networks": { "message": "Omrežja" }, + "nevermind": { + "message": "Pozabi" + }, "newAccount": { "message": "Nov račun" }, @@ -480,31 +723,64 @@ "message": "Nova pogodba" }, "newPassword": { - "message": "Novo geslo (min. 8. črk)" + "message": "Novo geslo (min 8 znakov)" + }, + "newPassword8Chars": { + "message": "Novo geslo (min 8 znakov)" }, "newRecipient": { "message": "Nov prejemnik" }, - "newRPC": { + "newNetwork": { + "message": "Novo omrežje" + }, + "rpcURL": { "message": "Nov RPC URL" }, + "showAdvancedOptions": { + "message": "Pokaži napredne možnosti" + }, + "hideAdvancedOptions": { + "message": "Skrij napredne možnosti" + }, + "optionalChainId": { + "message": "ChainID (nezahtevano)" + }, + "optionalSymbol": { + "message": "Simbol (nezahtevano)" + }, + "optionalNickname": { + "message": "Uporabniško ime (nezahtevano)" + }, "next": { "message": "Naprej" }, "noAddressForName": { - "message": "Za to ime ni bil nastavljen noben naslov." + "message": "Za to ime ni naslovov." }, "noDeposits": { - "message": "Ni prejetih vplačil" + "message": "Prejetih ni nič vplačil" + }, + "noConversionRateAvailable": { + "message": "Menjalni tečaj ni na voljo" }, "noTransactionHistory": { "message": "Ni zgodovine transakcij." }, "noTransactions": { - "message": "Ni transakcij" + "message": "Nimate transakcij" + }, + "notFound": { + "message": "Ni najdeno" }, "notStarted": { - "message": "Ni se začelo" + "message": "Ni začeto" + }, + "noWebcamFoundTitle": { + "message": "Spletna kamera ni najdena" + }, + "noWebcamFound": { + "message": "Spletna kamera ni najdena. Poskusite znova kasneje." }, "oldUI": { "message": "Star UI" @@ -512,43 +788,89 @@ "oldUIMessage": { "message": "Vrnili ste se v star uporabniški vmesnik. V novega se lahko vrnete z možnostjo v spustnem meniju v zgornjem desnem kotu." }, + "onlySendToEtherAddress": { + "message": "Na Ethereum naslov pošljute samo ETH." + }, + "onlySendTokensToAccountAddress": { + "message": "Na Ethereum naslov pošljute samo $1.", + "description": "displays token symbol" + }, + "openInTab": { + "message": "Odpri v zavihku" + }, "or": { "message": "ali", "description": "choice between creating or importing a new account" }, + "orderOneHere": { + "message": "Naročite Trezor ali Ledger i n zavarujte svoje premoženje s strojno denarnico" + }, + "origin": { + "message": "Izvor" + }, + "outgoing": { + "message": "Odhodni" + }, + "parameters": { + "message": "Parametri" + }, + "password": { + "message": "Geslo" + }, "passwordCorrect": { "message": "Prepričajte se, da je geslo pravilno." }, + "passwordsDontMatch": { + "message": "Gesli se ne ujemata" + }, "passwordMismatch": { "message": "gesli se ne ujemata", "description": "in password creation process, the two new password fields did not match" }, + "passwordNotLongEnough": { + "message": "Geslo ni dovolj dolgo" + }, "passwordShort": { "message": "geslo ni dovolj dolgo", "description": "in password creation process, the password is not long enough to be secure" }, "pastePrivateKey": { - "message": "Tukaj prilepite zasebni ključ:", + "message": "Tukaj prilepite vaš zasebni ključ:", "description": "For importing an account from a private key" }, "pasteSeed": { - "message": "Tukaj prilepite seed phrase!" + "message": "Tukaj prilepite seed phase!" + }, + "pending": { + "message": "v obdelavi" }, "personalAddressDetected": { - "message": "Osebni naslov je zaznan. Vnesite naslov žetona." + "message": "Zaznan je osebni naslov. Vnesite naslov pogodbe žetona." }, "pleaseReviewTransaction": { - "message": "Preglejte transakcijo." + "message": "Preglejte vašo transakcijo." + }, + "popularTokens": { + "message": "Priljubljeni žetoni" + }, + "prev": { + "message": "Prej" + }, + "primaryCurrencySetting": { + "message": "Glavna valuta" + }, + "primaryCurrencySettingDescription": { + "message": "Izberite Native za prikaz vrednosti v privzeti valuti verige (npr. ETH). Izberite Klasične za prikaz vrednosti v izbrani klasični valuti." }, "privacyMsg": { - "message": "Politika zasebnosti" + "message": "Zasebnost" }, "privateKey": { - "message": "Zasebni ključ", + "message": "Zasebni lljuč", "description": "select this type of file to use to import an account" }, "privateKeyWarning": { - "message": "Opozorilo: Nikoli ne razkrijte tega ključa. Vsakdo s svojimi zasebnimi ključi lahko ukrade vse premoženje v računu." + "message": "Opozorilo: Nikoli ne razkrijte tega ključa. Kdorkoli lahko z njim ukrade vse vaše premoženje v računu." }, "privateNetwork": { "message": "Zasebno omrežje" @@ -556,47 +878,98 @@ "qrCode": { "message": "Prikaži QR kodo" }, + "queue": { + "message": "Čakalna vrsta" + }, "readdToken": { - "message": "Ta žeton lahko dodate tudi v prihodnosti, tako da odprete možnost »Dodaj žeton« v meniju z računi." + "message": "Ta žeton lahko dodate tudi kasneje z uporabo gumba “Dodaj žeton” v možnostih vašega računa." }, "readMore": { - "message": "Preberite več." + "message": "Tukaj preberite več." }, "readMore2": { "message": "Preberite več." }, "receive": { - "message": "Prejmite" + "message": "Prejmi" }, "recipientAddress": { "message": "Prejemnikov naslov" }, "refundAddress": { - "message": "Vaš naslov za vračilo" + "message": "Naslov za vračilo." + }, + "reject": { + "message": "Zavrni" + }, + "rejectAll": { + "message": "Zavrni vse" + }, + "rejectTxsN": { + "message": "Zavrni $1 transakcij" + }, + "rejectTxsDescription": { + "message": "Zavrnili boste $1 transakcij." }, "rejected": { "message": "Zavrnjeno" }, + "reset": { + "message": "Ponastavi" + }, "resetAccount": { "message": "Ponastavi račun" }, + "resetAccountDescription": { + "message": "Ponastavljanje računa bo izbrisalo zgodovino transakcij." + }, "restoreFromSeed": { - "message": "Obnovi iz seed phrase" + "message": "Obnovim račun?" + }, + "restoreVault": { + "message": "Obnovi shrambo" + }, + "restoreAccountWithSeed": { + "message": "Obnovi račun z seed phrase" }, "required": { "message": "Zahtevano" }, "retryWithMoreGas": { - "message": "Poskusi z višjim gas price" + "message": "Poskusite z večjim gas price" + }, + "restore": { + "message": "Obnovi" }, "revealSeedWords": { - "message": "Prikaži seed words" + "message": "Razkrij seed words" + }, + "revealSeedWordsTitle": { + "message": "Seed Phrase" + }, + "revealSeedWordsDescription": { + "message": "Če želite zamenjati brskalnik ali računalnik, potrebujete vaš seed phase za dostop do računa. Shranite ga na varno skrito mesto." + }, + "revealSeedWordsWarningTitle": { + "message": "Tega ne delite z nikomer!" }, "revealSeedWordsWarning": { - "message": "Ne obnovite seed words na javnem mestu! Te besede se lahko uporabijo za krajo vseh vaših računov." + "message": "S temi besedami lahko kdorkoli ukrade vse vaše račune." }, "revert": { - "message": "Povrni" + "message": "Obnovi" + }, + "remove": { + "message": "izbriši" + }, + "removeAccount": { + "message": "Izbriši račun" + }, + "removeAccountDescription": { + "message": "Ta račun bo izbrisan. Prepričajte se, da imate seed phase ali zasebni ključ tega računa, da ga boste lahko kasneje obnovili. " + }, + "readyToConnect": { + "message": "Pripravljeni na povezovanje?" }, "rinkeby": { "message": "Testno omrežje Rinkeby" @@ -604,13 +977,19 @@ "ropsten": { "message": "Testno omrežje Ropsten" }, + "rpc": { + "message": "RPC po meri" + }, "sampleAccountName": { - "message": "npr. Moj nov račun", + "message": "npr. Moj račun", "description": "Help user understand concept of adding a human-readable name to their account" }, "save": { "message": "Shrani" }, + "saveAsCsvFile": { + "message": "Shrani kot CSV datoteko" + }, "saveAsFile": { "message": "Shrani kot datoteko", "description": "Account export process" @@ -618,14 +997,23 @@ "saveSeedAsFile": { "message": "Shrani seed words kot datoteko" }, + "scanInstructions": { + "message": "Postavite QR kodo pred vašo kamero" + }, + "scanQrCode": { + "message": "Skeniraj QR kodo" + }, "search": { "message": "Iskanje" }, + "searchResults": { + "message": "Rezultati iskanja" + }, "secretPhrase": { - "message": "Tukaj vnesite svoje seed words, da obnovite svoje račune." + "message": "Vnesite vaših dvanajst besed za obnovitev vaših računov." }, "seedPhraseReq": { - "message": "seed phrases so dolgi 12 besed" + "message": "Seed phrase mora biti dolg 12 besed" }, "select": { "message": "Izberi" @@ -633,6 +1021,9 @@ "selectCurrency": { "message": "Izberi valuto" }, + "selectLocale": { + "message": "Izberi jezik" + }, "selectService": { "message": "Izberi storitev" }, @@ -648,24 +1039,63 @@ "sendTokens": { "message": "Pošlji žetone" }, + "sentEther": { + "message": "poslani ether" + }, + "sentTokens": { + "message": "poslani žetoni" + }, + "separateEachWord": { + "message": "Vsako besedo ločite z enim presledkom" + }, + "searchTokens": { + "message": "Iskanje žetonov" + }, + "selectAnAddress": { + "message": "Izberi naslov" + }, + "selectAnAccount": { + "message": "Izberi račun" + }, + "selectAnAccountHelp": { + "message": "Izberi račun za prikaz v MetaMask" + }, + "selectHdPath": { + "message": "Izberi HD Path" + }, + "selectPathHelp": { + "message": "Če obstoječih Ledger ne vidite, poskusite izbrati \"Legacy (MEW / MyCrypto)\"" + }, "sendTokensAnywhere": { - "message": "Pošljite žetone vsem, ki imajo Ethereum račun" + "message": "Pošljite žetone komurkoli z Ethereum naslovom" }, "settings": { "message": "Nastavitve" }, "shapeshiftBuy": { - "message": "Kupite z Shapeshift" + "message": "Kupi z Shapeshift" }, "showPrivateKeys": { - "message": "Prikaži zasebne ključe" + "message": "Pokaži zasebni ključ" }, "showQRCode": { - "message": "Prikaži QR kodo" + "message": "Pokaži QR kodo" + }, + "showHexData": { + "message": "Pokaži Hex Data" + }, + "showHexDataDescription": { + "message": "Izberite za prikaz hex podatkov na zaslonu za pošiljanje" }, "sign": { "message": "Podpiši" }, + "signatureRequest": { + "message": "Zahteva za podpis" + }, + "signed": { + "message": "Podpisano" + }, "signMessage": { "message": "Podpiši sporočilo" }, @@ -676,11 +1106,20 @@ "message": "Zahteva za podpis" }, "sigRequested": { - "message": "Podpis je zahtevan" + "message": "Podpis zahtevan" }, "spaceBetween": { "message": "med besedami je lahko samo presledek" }, + "speedUp": { + "message": "pospeši" + }, + "speedUpTitle": { + "message": "Pospeši transakcijo" + }, + "speedUpSubtitle": { + "message": "Povečajte gas prise za pospešitev transakcije" + }, "status": { "message": "Status" }, @@ -688,19 +1127,43 @@ "message": "State dnevniki" }, "stateLogsDescription": { - "message": "State dnevniki vsebujejo naslove vašega računa in poslane transakcije.." + "message": "State vsebujejo vaš javni nasklov in zgodovino transakcij." + }, + "stateLogError": { + "message": "Napaka pri pridobivanju state dnevnikov." + }, + "step1HardwareWallet": { + "message": "1. Povežite strojno denarnico" + }, + "step1HardwareWalletMsg": { + "message": "Z računalnikom povežite strojno denarnico." + }, + "step2HardwareWallet": { + "message": "2. Izberite račun" + }, + "step2HardwareWalletMsg": { + "message": "Izberite račun, ki ga želute uporabiti. Trenutno lahko izberete le en račun na enkrat." + }, + "step3HardwareWallet": { + "message": "3. Začnite uporabljati dApps in več!" + }, + "step3HardwareWalletMsg": { + "message": "Uporabite strojno denarnico kot katerikoli drug Ethereum račun. Prijavite se v dApps, pošljite Ether in ERC20 žetone in žetone kot CryptoKitties." }, "submit": { "message": "Potrdi" }, + "submitted": { + "message": "Potrjeno" + }, "supportCenter": { - "message": "Obiščite našo podporo" + "message": "Obiščite naše središče za podporo" }, "symbolBetweenZeroTen": { - "message": "Simbol mora biti dolg od 0 do 10 znakov." + "message": "Simbol mora imeti med 0 in 10 znakov." }, "takesTooLong": { - "message": "Traja predolgo?" + "message": "Trava predolgo?" }, "terms": { "message": "Pogoji uporabe" @@ -715,79 +1178,151 @@ "message": "$1 v ETH prek ShapeShift", "description": "system will fill in deposit type in start of message" }, + "token": { + "message": "Žeton" + }, "tokenAddress": { "message": "Naslov žetona" }, "tokenAlreadyAdded": { - "message": "Žeton je že bil dodan." + "message": "Žeton je bil že dodan." }, "tokenBalance": { - "message": "Vaš znesek žetona:" + "message": "Vaš znesek žetonov je:" }, "tokenSelection": { - "message": "Poiščite žetone ali jih izberite z našega seznama priljubljenih žetonov." + "message": "Iščite žetone ali pa jih izberite iz seznama priljubljenih." }, "tokenSymbol": { "message": "Simbol žetona" }, "tokenWarning1": { - "message": "Spremljajte žetone, ki ste jih kupili s svojim MetaMask računom. Če ste kupili žetone z drugačnim računom, ti žetoni ne bodo prikazani tukaj." + "message": "Sledite žetonom, ki ste jih kupili z MetaMask metamask računom. Če ste jih kupili drugje, ne bodo prikazani tukaj." }, "total": { "message": "Skupno" }, + "transaction": { + "message": "transakcija" + }, + "transactionConfirmed": { + "message": "Transakcija potrjena na $2." + }, + "transactionCreated": { + "message": "Transakcija z vrednostjo $1 ustvarjena na $2." + }, + "transactionWithNonce": { + "message": "Transakcija $1" + }, + "transactionDropped": { + "message": "Transakcija na $2 preklicana." + }, + "transactionSubmitted": { + "message": "Transakcija na $2 oddana." + }, + "transactionUpdated": { + "message": "Transakcija na $2 spremenjena." + }, + "transactionUpdatedGas": { + "message": "Transakcija spremenjena z gas price $1 na $2." + }, + "transactionErrored": { + "message": "Napaka pri transakciji." + }, "transactions": { "message": "transakcije" }, + "transactionError": { + "message": "Napaka pri transakciji. Izjema sprožena v kodi pogodbe." + }, "transactionMemo": { - "message": "Opis transakcije (ni zahtevano)" + "message": "Opomba transakcije (nezahtevano)" }, "transactionNumber": { "message": "Številka transakcije" }, + "transfer": { + "message": "Prenesi" + }, + "transferFrom": { + "message": "Prenesi od" + }, "transfers": { "message": "Prenosi" }, + "trezorHardwareWallet": { + "message": "Strojna denarnica TREZOR" + }, "troubleTokenBalances": { - "message": "Imeli smo težave pri nalaganju vaših žetonov. Ogledate si jih lahko ", + "message": "Če imate težave pri ogledu zneskov žetonov si jih lahko ogledate ", "description": "Followed by a link (here) to view token balances" }, + "tryAgain": { + "message": "Poskusi znova" + }, "twelveWords": { "message": "Edini način za obnovitev MetaMask računa, je teh 12 besed.\nShranite jih na varno in skrivno mesto." }, "typePassword": { - "message": "Vpišite vaše geslo" + "message": "Vnesite vaše MetaMask geslo" }, "uiWelcome": { "message": "Dobrodošli v nov UI (Beta)" }, "uiWelcomeMessage": { - "message": "Zdaj uporabljate novi MetaMask uporabniški vmesnik. Razglejte se, preizkusite nove funkcije, kot so pošiljanje žetonov, in nas obvestite, če imate kakšne težave." + "message": "Uporabljate nov uporabniški vmesnik." + }, + "unapproved": { + "message": "Neodobreno" }, "unavailable": { "message": "Ni na voljo" }, + "units": { + "message": "enote" + }, "unknown": { "message": "Neznano" }, + "unknownFunction": { + "message": "Neznana funkcija" + }, "unknownNetwork": { "message": "Neznano zasebno omrežje" }, "unknownNetworkId": { "message": "Neznan ID omrežja" }, + "unknownQrCode": { + "message": "Napaka: Te QR kode ni bilo mogoče prepoznati" + }, + "unknownCameraErrorTitle": { + "message": "Ooops! Nekaj je šlo narobe ...." + }, + "unknownCameraError": { + "message": "Pri dostopanju do vaše kamere je prišlo do napake. Poskusite znova kasneje ..." + }, + "unlock": { + "message": "Odkleni" + }, + "unlockMessage": { + "message": "Decentralizirana spletna denarnica" + }, + "updatedWithDate": { + "message": "Posodobljeno $1" + }, "uriErrorMsg": { - "message": "URI-ji zahtevajo ustrezno HTTP/HTTPS predpono." + "message": "URI zahtevajo ustrezno HTTP/HTTPS predpono." }, "usaOnly": { "message": "Samo za ZDA", "description": "Using this exchange is limited to people inside the USA" }, "usedByClients": { - "message": "Uporablja jih več različnih odjemalcev" + "message": "Uporabljen s strani večih različnih odjemalcev" }, "useOldUI": { - "message": "Uporabi star uporabniški vmesnik" + "message": "Uporabi star UI" }, "validFileImport": { "message": "Za uvoz morate izbrati pravilno datoteko." @@ -798,22 +1333,40 @@ "viewAccount": { "message": "Poglej račun" }, + "viewOnEtherscan": { + "message": "Poglej na Etherscan" + }, "visitWebSite": { "message": "Obiščite našo spletno stran" }, + "walletSeed": { + "message": "Wallet Seed" + }, "warning": { "message": "Opozorilo" }, + "welcomeBack": { + "message": "Dobrodošli nazaj!" + }, "welcomeBeta": { "message": "Dobrodošli v MetaMask Beta" }, "whatsThis": { "message": "Kaj je to?" }, + "yesLetsTry": { + "message": "Pa poskusimo" + }, + "youNeedToAllowCameraAccess": { + "message": "Za uporabo te funkcije boste potrebovali dostop do kamere." + }, "yourSigRequested": { - "message": "Vaš podpis je bil zahtevan" + "message": "Zahtevan je bil vaš podpis" }, "youSign": { - "message": "Podpisani ste" + "message": "Podpisali boste" + }, + "yourPrivateSeedPhrase": { + "message": "Vaš zasebni seed phrase" } } diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js index d5bc5fe2b..1e866d2c9 100644 --- a/app/scripts/controllers/currency.js +++ b/app/scripts/controllers/currency.js @@ -21,6 +21,7 @@ class CurrencyController { * since midnight of January 1, 1970 * @property {number} conversionInterval The id of the interval created by the scheduleConversionInterval method. * Used to clear an existing interval on subsequent calls of that method. + * @property {string} nativeCurrency The ticker/symbol of the native chain currency * */ constructor (opts = {}) { @@ -28,6 +29,7 @@ class CurrencyController { currentCurrency: 'usd', conversionRate: 0, conversionDate: 'N/A', + nativeCurrency: 'ETH', }, opts.initState) this.store = new ObservableStore(initState) } @@ -37,6 +39,29 @@ class CurrencyController { // /** + * A getter for the nativeCurrency property + * + * @returns {string} A 2-4 character shorthand that describes the specific currency + * + */ + getNativeCurrency () { + return this.store.getState().nativeCurrency + } + + /** + * A setter for the nativeCurrency property + * + * @param {string} nativeCurrency The new currency to set as the nativeCurrency in the store + * + */ + setNativeCurrency (nativeCurrency) { + this.store.updateState({ + nativeCurrency, + ticker: nativeCurrency, + }) + } + + /** * A getter for the currentCurrency property * * @returns {string} A 2-4 character shorthand that describes a specific currency, currently selected by the user @@ -104,15 +129,32 @@ class CurrencyController { * */ async updateConversionRate () { - let currentCurrency + let currentCurrency, nativeCurrency try { currentCurrency = this.getCurrentCurrency() - const response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) + nativeCurrency = this.getNativeCurrency() + let apiUrl + if (nativeCurrency === 'ETH') { + apiUrl = `https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}` + } else { + apiUrl = `https://min-api.cryptocompare.com/data/price?fsym=${nativeCurrency.toUpperCase()}&tsyms=${currentCurrency.toUpperCase()}` + } + const response = await fetch(apiUrl) const parsedResponse = await response.json() - this.setConversionRate(Number(parsedResponse.bid)) - this.setConversionDate(Number(parsedResponse.timestamp)) + if (nativeCurrency === 'ETH') { + this.setConversionRate(Number(parsedResponse.bid)) + this.setConversionDate(Number(parsedResponse.timestamp)) + } else { + if (parsedResponse[currentCurrency.toUpperCase()]) { + this.setConversionRate(Number(parsedResponse[currentCurrency.toUpperCase()])) + this.setConversionDate(parseInt((new Date()).getTime() / 1000)) + } else { + this.setConversionRate(0) + this.setConversionDate('N/A') + } + } } catch (err) { - log.warn(`MetaMask - Failed to query currency conversion:`, currentCurrency, err) + log.warn(`MetaMask - Failed to query currency conversion:`, nativeCurrency, currentCurrency, err) this.setConversionRate(0) this.setConversionDate('N/A') } diff --git a/app/scripts/controllers/network/createMetamaskMiddleware.js b/app/scripts/controllers/network/createMetamaskMiddleware.js index 9e6a45888..319c5bf3e 100644 --- a/app/scripts/controllers/network/createMetamaskMiddleware.js +++ b/app/scripts/controllers/network/createMetamaskMiddleware.js @@ -11,6 +11,7 @@ function createMetamaskMiddleware ({ processTransaction, processEthSignMessage, processTypedMessage, + processTypedMessageV3, processPersonalMessage, getPendingNonce, }) { @@ -25,6 +26,7 @@ function createMetamaskMiddleware ({ processTransaction, processEthSignMessage, processTypedMessage, + processTypedMessageV3, processPersonalMessage, }), createPendingNonceMiddleware({ getPendingNonce }), diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index c1667d9a6..c21e9c764 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -11,6 +11,8 @@ const createInfuraClient = require('./createInfuraClient') const createJsonRpcClient = require('./createJsonRpcClient') const createLocalhostClient = require('./createLocalhostClient') const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy') +const extend = require('extend') +const networks = { networkList: {} } const { ROPSTEN, @@ -29,6 +31,10 @@ const defaultProviderConfig = { type: testMode ? RINKEBY : MAINNET, } +const defaultNetworkConfig = { + ticker: 'ETH', +} + module.exports = class NetworkController extends EventEmitter { constructor (opts = {}) { @@ -39,7 +45,8 @@ module.exports = class NetworkController extends EventEmitter { // create stores this.providerStore = new ObservableStore(providerConfig) this.networkStore = new ObservableStore('loading') - this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore }) + this.networkConfig = new ObservableStore(defaultNetworkConfig) + this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore, settings: this.networkConfig }) this.on('networkDidChange', this.lookupNetwork) // provider and block tracker this._provider = null @@ -51,8 +58,8 @@ module.exports = class NetworkController extends EventEmitter { initializeProvider (providerParams) { this._baseProviderParams = providerParams - const { type, rpcTarget } = this.providerStore.getState() - this._configureProvider({ type, rpcTarget }) + const { type, rpcTarget, chainId, ticker, nickname } = this.providerStore.getState() + this._configureProvider({ type, rpcTarget, chainId, ticker, nickname }) this.lookupNetwork() } @@ -72,7 +79,20 @@ module.exports = class NetworkController extends EventEmitter { return this.networkStore.getState() } - setNetworkState (network) { + getNetworkConfig () { + return this.networkConfig.getState() + } + + setNetworkState (network, type) { + if (network === 'loading') { + return this.networkStore.putState(network) + } + + // type must be defined + if (!type) { + return + } + network = networks.networkList[type] && networks.networkList[type].chainId ? networks.networkList[type].chainId : network return this.networkStore.putState(network) } @@ -85,18 +105,32 @@ module.exports = class NetworkController extends EventEmitter { if (!this._provider) { return log.warn('NetworkController - lookupNetwork aborted due to missing provider') } + var { type } = this.providerStore.getState() const ethQuery = new EthQuery(this._provider) - ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { - if (err) return this.setNetworkState('loading') - log.info('web3.getNetwork returned ' + network) - this.setNetworkState(network) + // first attempt to perform lookup via eth_chainId + ethQuery.sendAsync({ method: 'eth_chainId' }, (err, chainIdHex) => { + if (err) { + // if eth_chainId is not supported, fallback to net_verion + ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { + if (err) return this.setNetworkState('loading') + log.info(`net_version returned ${network}`) + this.setNetworkState(network, type) + }) + return + } + const chainId = Number.parseInt(chainIdHex, 16) + log.info(`net_version returned ${chainId}`) + this.setNetworkState(chainId, type) }) } - setRpcTarget (rpcTarget) { + setRpcTarget (rpcTarget, chainId, ticker = 'ETH', nickname = '') { const providerConfig = { type: 'rpc', rpcTarget, + chainId, + ticker, + nickname, } this.providerConfig = providerConfig } @@ -132,7 +166,7 @@ module.exports = class NetworkController extends EventEmitter { } _configureProvider (opts) { - const { type, rpcTarget } = opts + const { type, rpcTarget, chainId, ticker, nickname } = opts // infura type-based endpoints const isInfura = INFURA_PROVIDER_TYPES.includes(type) if (isInfura) { @@ -142,7 +176,7 @@ module.exports = class NetworkController extends EventEmitter { this._configureLocalhostProvider() // url-based rpc endpoints } else if (type === 'rpc') { - this._configureStandardProvider({ rpcUrl: rpcTarget }) + this._configureStandardProvider({ rpcUrl: rpcTarget, chainId, ticker, nickname }) } else { throw new Error(`NetworkController - _configureProvider - unknown type "${type}"`) } @@ -152,6 +186,11 @@ module.exports = class NetworkController extends EventEmitter { log.info('NetworkController - configureInfuraProvider', type) const networkClient = createInfuraClient({ network: type }) this._setNetworkClient(networkClient) + // setup networkConfig + var settings = { + ticker: 'ETH', + } + this.networkConfig.putState(settings) } _configureLocalhostProvider () { @@ -160,9 +199,22 @@ module.exports = class NetworkController extends EventEmitter { this._setNetworkClient(networkClient) } - _configureStandardProvider ({ rpcUrl }) { + _configureStandardProvider ({ rpcUrl, chainId, ticker, nickname }) { log.info('NetworkController - configureStandardProvider', rpcUrl) const networkClient = createJsonRpcClient({ rpcUrl }) + // hack to add a 'rpc' network with chainId + networks.networkList['rpc'] = { + chainId: chainId, + rpcUrl, + ticker: ticker || 'ETH', + nickname, + } + // setup networkConfig + var settings = { + network: chainId, + } + settings = extend(settings, networks.networkList['rpc']) + this.networkConfig.putState(settings) this._setNetworkClient(networkClient) } diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 20b13398c..eaeaee499 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -25,7 +25,7 @@ class PreferencesController { */ constructor (opts = {}) { const initState = extend({ - frequentRpcList: [], + frequentRpcListDetail: [], currentAccountTab: 'history', accountTokens: {}, assetImages: {}, @@ -39,7 +39,7 @@ class PreferencesController { seedWords: null, forgottenPassword: false, preferences: { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, }, }, opts.initState) @@ -392,19 +392,22 @@ class PreferencesController { * Adds custom RPC url to state. * * @param {string} url The RPC url to add to frequentRpcList. + * @param {number} chainId Optional chainId of the selected network. + * @param {string} ticker Optional ticker symbol of the selected network. + * @param {string} nickname Optional nickname of the selected network. * @returns {Promise<array>} Promise resolving to updated frequentRpcList. * */ - addToFrequentRpcList (url) { - const rpcList = this.getFrequentRpcList() - const index = rpcList.findIndex((element) => { return element === url }) + addToFrequentRpcList (url, chainId, ticker = 'ETH', nickname = '') { + const rpcList = this.getFrequentRpcListDetail() + const index = rpcList.findIndex((element) => { return element.rpcUrl === url }) if (index !== -1) { rpcList.splice(index, 1) } if (url !== 'http://localhost:8545') { - rpcList.push(url) + rpcList.push({ rpcUrl: url, chainId, ticker, nickname }) } - this.store.updateState({ frequentRpcList: rpcList }) + this.store.updateState({ frequentRpcListDetail: rpcList }) return Promise.resolve(rpcList) } @@ -416,23 +419,23 @@ class PreferencesController { * */ removeFromFrequentRpcList (url) { - const rpcList = this.getFrequentRpcList() - const index = rpcList.findIndex((element) => { return element === url }) + const rpcList = this.getFrequentRpcListDetail() + const index = rpcList.findIndex((element) => { return element.rpcUrl === url }) if (index !== -1) { rpcList.splice(index, 1) } - this.store.updateState({ frequentRpcList: rpcList }) + this.store.updateState({ frequentRpcListDetail: rpcList }) return Promise.resolve(rpcList) } /** - * Getter for the `frequentRpcList` property. + * Getter for the `frequentRpcListDetail` property. * - * @returns {array<string>} An array of one or two rpc urls. + * @returns {array<array>} An array of rpc urls. * */ - getFrequentRpcList () { - return this.store.getState().frequentRpcList + getFrequentRpcListDetail () { + return this.store.getState().frequentRpcListDetail } /** diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 7913662d4..1f6a8659b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -138,12 +138,12 @@ module.exports = class MetamaskController extends EventEmitter { this.accountTracker.stop() } }) - + // ensure accountTracker updates balances after network change this.networkController.on('networkDidChange', () => { this.accountTracker._updateAccounts() }) - + // key mgmt const additionalKeyrings = [TrezorKeyring, LedgerBridgeKeyring] this.keyringController = new KeyringController({ @@ -197,6 +197,8 @@ module.exports = class MetamaskController extends EventEmitter { }) this.networkController.on('networkDidChange', () => { this.balancesController.updateAllBalances() + var currentCurrency = this.currencyController.getCurrentCurrency() + this.setCurrentCurrency(currentCurrency, function() {}) }) this.balancesController.updateAllBalances() @@ -275,6 +277,8 @@ module.exports = class MetamaskController extends EventEmitter { processTransaction: this.newUnapprovedTransaction.bind(this), // msg signing processEthSignMessage: this.newUnsignedMessage.bind(this), + processTypedMessage: this.newUnsignedTypedMessage.bind(this), + processTypedMessageV3: this.newUnsignedTypedMessage.bind(this), processPersonalMessage: this.newUnsignedPersonalMessage.bind(this), getPendingNonce: this.getPendingNonce.bind(this), } @@ -978,8 +982,8 @@ module.exports = class MetamaskController extends EventEmitter { * @param {Object} msgParams - The params passed to eth_signTypedData. * @param {Function} cb - The callback function, called with the signature. */ - newUnsignedTypedMessage (msgParams, req) { - const promise = this.typedMessageManager.addUnapprovedMessageAsync(msgParams, req) + newUnsignedTypedMessage (msgParams, req, version) { + const promise = this.typedMessageManager.addUnapprovedMessageAsync(msgParams, req, version) this.sendUpdate() this.opts.showUnconfirmedMessage() return promise @@ -1273,10 +1277,6 @@ module.exports = class MetamaskController extends EventEmitter { engine.push(subscriptionManager.middleware) // watch asset engine.push(this.preferencesController.requestWatchAsset.bind(this.preferencesController)) - // sign typed data middleware - engine.push(this.createTypedDataMiddleware('eth_signTypedData', 'V1').bind(this)) - engine.push(this.createTypedDataMiddleware('eth_signTypedData_v1', 'V1').bind(this)) - engine.push(this.createTypedDataMiddleware('eth_signTypedData_v3', 'V3', true).bind(this)) // forward to metamask primary provider engine.push(createProviderMiddleware({ provider })) @@ -1412,10 +1412,13 @@ module.exports = class MetamaskController extends EventEmitter { * @param {Function} cb - A callback function returning currency info. */ setCurrentCurrency (currencyCode, cb) { + const { ticker } = this.networkController.getNetworkConfig() try { + this.currencyController.setNativeCurrency(ticker) this.currencyController.setCurrentCurrency(currencyCode) this.currencyController.updateConversionRate() const data = { + nativeCurrency: ticker || 'ETH', conversionRate: this.currencyController.getConversionRate(), currentCurrency: this.currencyController.getCurrentCurrency(), conversionDate: this.currencyController.getConversionDate(), @@ -1454,11 +1457,14 @@ module.exports = class MetamaskController extends EventEmitter { /** * A method for selecting a custom URL for an ethereum RPC provider. * @param {string} rpcTarget - A URL for a valid Ethereum RPC API. + * @param {number} chainId - The chainId of the selected network. + * @param {string} ticker - The ticker symbol of the selected network. + * @param {string} nickname - Optional nickname of the selected network. * @returns {Promise<String>} - The RPC Target URL confirmed. */ - async setCustomRpc (rpcTarget) { - this.networkController.setRpcTarget(rpcTarget) - await this.preferencesController.addToFrequentRpcList(rpcTarget) + async setCustomRpc (rpcTarget, chainId, ticker = 'ETH', nickname = '') { + this.networkController.setRpcTarget(rpcTarget, chainId, ticker, nickname) + await this.preferencesController.addToFrequentRpcList(rpcTarget, chainId, ticker, nickname) return rpcTarget } @@ -1542,27 +1548,6 @@ module.exports = class MetamaskController extends EventEmitter { * @param {Function} - next * @param {Function} - end */ - createTypedDataMiddleware (methodName, version, reverse) { - return async (req, res, next, end) => { - const { method, params } = req - if (method === methodName) { - const promise = this.typedMessageManager.addUnapprovedMessageAsync({ - data: reverse ? params[1] : params[0], - from: reverse ? params[0] : params[1], - }, req, version) - this.sendUpdate() - this.opts.showUnconfirmedMessage() - try { - res.result = await promise - end() - } catch (error) { - end(error) - } - } else { - next() - } - } - } /** * Adds a domain to the {@link BlacklistController} whitelist diff --git a/development/states/add-token.json b/development/states/add-token.json index 6a525f2b3..b59e9b757 100644 --- a/development/states/add-token.json +++ b/development/states/add-token.json @@ -109,7 +109,7 @@ }, "currentLocale": "en", "preferences": { - "useETHAsPrimaryCurrency": true + "useNativeCurrencyAsPrimaryCurrency": true } }, "appState": { diff --git a/development/states/confirm-sig-requests.json b/development/states/confirm-sig-requests.json index c7103cd13..1ffde3938 100644 --- a/development/states/confirm-sig-requests.json +++ b/development/states/confirm-sig-requests.json @@ -152,7 +152,7 @@ }, "currentLocale": "en", "preferences": { - "useETHAsPrimaryCurrency": true + "useNativeCurrencyAsPrimaryCurrency": true } }, "appState": { diff --git a/development/states/currency-localization.json b/development/states/currency-localization.json index 7dea42ade..ef28891a3 100644 --- a/development/states/currency-localization.json +++ b/development/states/currency-localization.json @@ -110,7 +110,7 @@ }, "currentLocale": "en", "preferences": { - "useETHAsPrimaryCurrency": true + "useNativeCurrencyAsPrimaryCurrency": true } }, "appState": { diff --git a/development/states/first-time.json b/development/states/first-time.json index 3206b67a3..ff7078720 100644 --- a/development/states/first-time.json +++ b/development/states/first-time.json @@ -39,7 +39,7 @@ "tokens": [], "currentLocale": "en", "preferences": { - "useETHAsPrimaryCurrency": true + "useNativeCurrencyAsPrimaryCurrency": true } }, "appState": { diff --git a/development/states/send-new-ui.json b/development/states/send-new-ui.json index d9924dd74..0cd2f23f2 100644 --- a/development/states/send-new-ui.json +++ b/development/states/send-new-ui.json @@ -111,7 +111,7 @@ }, "currentLocale": "en", "preferences": { - "useETHAsPrimaryCurrency": true + "useNativeCurrencyAsPrimaryCurrency": true } }, "appState": { diff --git a/development/states/tx-list-items.json b/development/states/tx-list-items.json index cbffa98e5..e83179a17 100644 --- a/development/states/tx-list-items.json +++ b/development/states/tx-list-items.json @@ -104,7 +104,7 @@ "send": {}, "currentLocale": "en", "preferences": { - "useETHAsPrimaryCurrency": true + "useNativeCurrencyAsPrimaryCurrency": true } }, "appState": { diff --git a/old-ui/app/app.js b/old-ui/app/app.js index 9be21ebad..f5e03d4f6 100644 --- a/old-ui/app/app.js +++ b/old-ui/app/app.js @@ -73,7 +73,7 @@ function mapStateToProps (state) { forgottenPassword: state.appState.forgottenPassword, nextUnreadNotice: state.metamask.nextUnreadNotice, lostAccounts: state.metamask.lostAccounts, - frequentRpcList: state.metamask.frequentRpcList || [], + frequentRpcListDetail: state.metamask.frequentRpcListDetail || [], featureFlags, suggestedTokens: state.metamask.suggestedTokens, diff --git a/old-ui/app/components/app-bar.js b/old-ui/app/components/app-bar.js index 234c06a01..fa8e499ed 100644 --- a/old-ui/app/components/app-bar.js +++ b/old-ui/app/components/app-bar.js @@ -17,7 +17,7 @@ module.exports = class AppBar extends Component { static propTypes = { dispatch: PropTypes.func.isRequired, - frequentRpcList: PropTypes.array.isRequired, + frequentRpcListDetail: PropTypes.array.isRequired, isMascara: PropTypes.bool.isRequired, isOnboarding: PropTypes.bool.isRequired, identities: PropTypes.any.isRequired, @@ -196,7 +196,7 @@ module.exports = class AppBar extends Component { renderNetworkDropdown () { const { dispatch, - frequentRpcList: rpcList, + frequentRpcListDetail: rpcList, provider, } = this.props const { @@ -321,8 +321,8 @@ module.exports = class AppBar extends Component { ]) } - renderCustomOption ({ rpcTarget, type }) { - const {dispatch} = this.props + renderCustomOption ({ rpcTarget, type, ticker }) { + const {dispatch, network} = this.props if (type !== 'rpc') { return null @@ -340,7 +340,7 @@ module.exports = class AppBar extends Component { default: return h(DropdownMenuItem, { key: rpcTarget, - onClick: () => dispatch(actions.setRpcTarget(rpcTarget)), + onClick: () => dispatch(actions.setRpcTarget(rpcTarget, network, ticker)), closeMenu: () => this.setState({ isNetworkMenuOpen: false }), }, [ h('i.fa.fa-question-circle.fa-lg.menu-icon'), @@ -354,7 +354,8 @@ module.exports = class AppBar extends Component { const {dispatch} = this.props const reversedRpcList = rpcList.slice().reverse() - return reversedRpcList.map((rpc) => { + return reversedRpcList.map((entry) => { + const rpc = entry.rpcUrl const currentRpcTarget = provider.type === 'rpc' && rpc === provider.rpcTarget if ((rpc === LOCALHOST_RPC_URL) || currentRpcTarget) { @@ -363,7 +364,7 @@ module.exports = class AppBar extends Component { return h(DropdownMenuItem, { key: `common${rpc}`, closeMenu: () => this.setState({ isNetworkMenuOpen: false }), - onClick: () => dispatch(actions.setRpcTarget(rpc)), + onClick: () => dispatch(actions.setRpcTarget(rpc, entry.chainId, entry.ticker)), }, [ h('i.fa.fa-question-circle.fa-lg.menu-icon'), rpc, diff --git a/old-ui/app/components/balance.js b/old-ui/app/components/balance.js index 57ca84564..8995f961f 100644 --- a/old-ui/app/components/balance.js +++ b/old-ui/app/components/balance.js @@ -1,12 +1,18 @@ const Component = require('react').Component const h = require('react-hyperscript') +const connect = require('react-redux').connect const inherits = require('util').inherits const formatBalance = require('../util').formatBalance const generateBalanceObject = require('../util').generateBalanceObject const Tooltip = require('./tooltip.js') const FiatValue = require('./fiat-value.js') -module.exports = EthBalanceComponent +module.exports = connect(mapStateToProps)(EthBalanceComponent) +function mapStateToProps (state) { + return { + ticker: state.metamask.ticker, + } +} inherits(EthBalanceComponent, Component) function EthBalanceComponent () { @@ -16,9 +22,10 @@ function EthBalanceComponent () { EthBalanceComponent.prototype.render = function () { var props = this.props let { value } = props + const { ticker } = props var style = props.style var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true - value = value ? formatBalance(value, 6, needsParse) : '...' + value = value ? formatBalance(value, 6, needsParse, ticker) : '...' var width = props.width return ( diff --git a/old-ui/app/components/eth-balance.js b/old-ui/app/components/eth-balance.js index 4f538fd31..4458e6a9a 100644 --- a/old-ui/app/components/eth-balance.js +++ b/old-ui/app/components/eth-balance.js @@ -1,12 +1,18 @@ const Component = require('react').Component const h = require('react-hyperscript') +const connect = require('react-redux').connect const inherits = require('util').inherits const formatBalance = require('../util').formatBalance const generateBalanceObject = require('../util').generateBalanceObject const Tooltip = require('./tooltip.js') const FiatValue = require('./fiat-value.js') -module.exports = EthBalanceComponent +module.exports = connect(mapStateToProps)(EthBalanceComponent) +function mapStateToProps (state) { + return { + ticker: state.metamask.ticker, + } +} inherits(EthBalanceComponent, Component) function EthBalanceComponent () { @@ -16,9 +22,9 @@ function EthBalanceComponent () { EthBalanceComponent.prototype.render = function () { var props = this.props let { value } = props - const { style, width } = props + const { ticker, style, width } = props var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true - value = value ? formatBalance(value, 6, needsParse) : '...' + value = value ? formatBalance(value, 6, needsParse, ticker) : '...' return ( diff --git a/old-ui/app/config.js b/old-ui/app/config.js index 392a6dba7..7a93887a5 100644 --- a/old-ui/app/config.js +++ b/old-ui/app/config.js @@ -68,7 +68,7 @@ ConfigScreen.prototype.render = function () { currentProviderDisplay(metamaskState), - h('div', { style: {display: 'flex'} }, [ + h('div', { style: {display: 'block'} }, [ h('input#new_rpc', { placeholder: 'New RPC URL', style: { @@ -81,7 +81,70 @@ ConfigScreen.prototype.render = function () { if (event.key === 'Enter') { var element = event.target var newRpc = element.value - rpcValidation(newRpc, state) + var chainid = document.querySelector('input#chainid') + var ticker = document.querySelector('input#ticker') + var nickname = document.querySelector('input#nickname') + rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state) + } + }, + }), + h('br'), + h('input#chainid', { + placeholder: 'ChainId (optional)', + style: { + width: 'inherit', + flex: '1 0 auto', + height: '30px', + margin: '8px', + }, + onKeyPress (event) { + if (event.key === 'Enter') { + var element = document.querySelector('input#new_rpc') + var newRpc = element.value + var chainid = document.querySelector('input#chainid') + var ticker = document.querySelector('input#ticker') + var nickname = document.querySelector('input#nickname') + rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state) + } + }, + }), + h('br'), + h('input#ticker', { + placeholder: 'Symbol (optional)', + style: { + width: 'inherit', + flex: '1 0 auto', + height: '30px', + margin: '8px', + }, + onKeyPress (event) { + if (event.key === 'Enter') { + var element = document.querySelector('input#new_rpc') + var newRpc = element.value + var chainid = document.querySelector('input#chainid') + var ticker = document.querySelector('input#ticker') + var nickname = document.querySelector('input#nickname') + rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state) + } + }, + }), + h('br'), + h('input#nickname', { + placeholder: 'Nickname (optional)', + style: { + width: 'inherit', + flex: '1 0 auto', + height: '30px', + margin: '8px', + }, + onKeyPress (event) { + if (event.key === 'Enter') { + var element = document.querySelector('input#new_rpc') + var newRpc = element.value + var chainid = document.querySelector('input#chainid') + var ticker = document.querySelector('input#ticker') + var nickname = document.querySelector('input#nickname') + rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state) } }, }), @@ -93,7 +156,10 @@ ConfigScreen.prototype.render = function () { event.preventDefault() var element = document.querySelector('input#new_rpc') var newRpc = element.value - rpcValidation(newRpc, state) + var chainid = document.querySelector('input#chainid') + var ticker = document.querySelector('input#ticker') + var nickname = document.querySelector('input#nickname') + rpcValidation(newRpc, chainid.value, ticker.value, nickname.value, state) }, }, 'Save'), ]), @@ -189,9 +255,9 @@ ConfigScreen.prototype.render = function () { ) } -function rpcValidation (newRpc, state) { +function rpcValidation (newRpc, chainid, ticker = 'ETH', nickname = '', state) { if (validUrl.isWebUri(newRpc)) { - state.dispatch(actions.setRpcTarget(newRpc)) + state.dispatch(actions.setRpcTarget(newRpc, chainid, ticker, nickname)) } else { var appendedRpc = `http://${newRpc}` if (validUrl.isWebUri(appendedRpc)) { diff --git a/old-ui/app/util.js b/old-ui/app/util.js index 962832ce7..40e79b88c 100644 --- a/old-ui/app/util.js +++ b/old-ui/app/util.js @@ -102,7 +102,7 @@ function parseBalance (balance) { // Takes wei hex, returns an object with three properties. // Its "formatted" property is what we generally use to render values. -function formatBalance (balance, decimalsToKeep, needsParse = true) { +function formatBalance (balance, decimalsToKeep, needsParse = true, ticker = 'ETH') { var parsed = needsParse ? parseBalance(balance) : balance.split('.') var beforeDecimal = parsed[0] var afterDecimal = parsed[1] @@ -112,14 +112,14 @@ function formatBalance (balance, decimalsToKeep, needsParse = true) { if (afterDecimal !== '0') { var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits if (sigFigs) { afterDecimal = sigFigs[0] } - formatted = '0.' + afterDecimal + ' ETH' + formatted = '0.' + afterDecimal + ` ${ticker}` } } else { - formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ' ETH' + formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ` ${ticker}` } } else { afterDecimal += Array(decimalsToKeep).join('0') - formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ' ETH' + formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ` ${ticker}` } return formatted } diff --git a/package-lock.json b/package-lock.json index 22f0f3ab9..c6cfedb0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9570,9 +9570,9 @@ } }, "eth-block-tracker": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-4.0.3.tgz", - "integrity": "sha512-Uy+5hEvOT1/C6N1Lw/uQ10v03ArnNEQEkM0yhJQWwpd8Ymy3sw4jk75SE58s1spfOBBtnr8JaSAFioAFSeg6HA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-4.1.0.tgz", + "integrity": "sha512-991xTy6CzYYbizkHmgRFFI9iGx1OCISve8sSLuOlt7/yD7VFH1Jd8mOmBqxaG5ywGkIXdwAR78nQ2WDReETzBg==", "requires": { "eth-json-rpc-infura": "^3.1.2", "eth-query": "^2.1.0", @@ -9604,7 +9604,7 @@ }, "eth-json-rpc-middleware": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", + "resolved": "http://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==", "requires": { "async": "^2.5.0", @@ -9643,12 +9643,12 @@ }, "node-fetch": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" }, "whatwg-fetch": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" } } @@ -9899,29 +9899,26 @@ } }, "eth-json-rpc-middleware": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-3.1.3.tgz", - "integrity": "sha512-glp/mCefhsqrgVOTTuYlHYiTL+9mMPfaZsuQv4vnRg3kqNigblS1nqARaMeVW9WOM8ssh9TqIFpuUr7JDgNmKQ==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-3.1.6.tgz", + "integrity": "sha512-yf17/rAM4ElKMul8oSvuK7JuYIYEFFdy2YGPo2EZbuOEv2Wq1bteMlppgqZ9NYHriXLAOWV+ojY9kWHGbcU4xA==", "dev": true, "requires": { - "async": "^2.5.0", "btoa": "^1.2.1", "clone": "^2.1.1", "eth-query": "^2.1.2", "eth-sig-util": "^1.4.2", - "eth-tx-summary": "^3.1.2", + "eth-tx-summary": "^3.2.3", "ethereumjs-block": "^1.6.0", "ethereumjs-tx": "^1.3.3", "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", + "ethereumjs-vm": "^2.4.0", "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.3", + "json-rpc-engine": "^3.8.0", "json-rpc-error": "^2.0.0", "json-stable-stringify": "^1.0.1", "pify": "^3.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1", - "tape": "^4.6.3" + "safe-event-emitter": "^1.0.1" }, "dependencies": { "eth-sig-util": { @@ -9930,24 +9927,14 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" - }, - "dependencies": { - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "dev": true, - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - } - } } }, "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "dev": true, "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9957,6 +9944,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", + "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -9966,6 +9954,31 @@ "safe-buffer": "^5.1.1", "secp256k1": "^3.0.1" } + }, + "ethereumjs-vm": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.4.0.tgz", + "integrity": "sha512-MJ4lCWa5c6LhahhhvoDKW+YGjK00ZQn0RHHLh4L+WaH1k6Qv7/q3uTluew6sJGNCZdlO0yYMDXYW9qyxLHKlgQ==", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~1.7.0", + "ethereumjs-common": "~0.4.0", + "ethereumjs-util": "^5.2.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.1.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true } } }, @@ -10916,6 +10929,12 @@ } } }, + "ethereumjs-common": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-0.4.1.tgz", + "integrity": "sha512-ywYGsOeGCsMNWso5Y4GhjWI24FJv9FK7+VyVKiQgXg8ZRDPXJ7F/kJ1CnjtkjTvDF4e0yqU+FWswlqR3bmZQ9Q==", + "dev": true + }, "ethereumjs-tx": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.3.tgz", @@ -12788,8 +12807,7 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", @@ -12797,8 +12815,7 @@ }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -12901,8 +12918,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -12912,7 +12928,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -13030,8 +13045,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -13041,7 +13055,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -13147,7 +13160,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -26768,7 +26780,7 @@ }, "pretty-hrtime": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" }, "printf": { @@ -35267,4 +35279,4 @@ "dev": true } } -}
\ No newline at end of file +} diff --git a/package.json b/package.json index ef72d7bfb..3e922c454 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "ensnare": "^1.0.0", "eslint-plugin-react": "^7.4.0", "eth-bin-to-ops": "^1.0.1", - "eth-block-tracker": "^4.0.3", + "eth-block-tracker": "^4.1.0", "eth-contract-metadata": "github:MetaMask/eth-contract-metadata#master", "eth-ens-namehash": "^2.0.8", "eth-hd-keyring": "^1.2.2", @@ -261,7 +261,7 @@ "eslint-plugin-json": "^1.2.0", "eslint-plugin-mocha": "^5.0.0", "eslint-plugin-react": "^7.4.0", - "eth-json-rpc-middleware": "^3.1.3", + "eth-json-rpc-middleware": "^3.1.6", "eth-keyring-controller": "^3.3.1", "fetch-mock": "^6.5.2", "file-loader": "^1.1.11", diff --git a/test/data/mock-state.json b/test/data/mock-state.json index 7e083c60e..8deff5531 100644 --- a/test/data/mock-state.json +++ b/test/data/mock-state.json @@ -111,7 +111,9 @@ "0x108cf70c7d384c552f42c07c41c0e1e46d77ea0d": 0.00039345803819379796, "0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5": 0.00008189274407698049 }, + "ticker": "ETH", "currentCurrency": "usd", + "nativeCurrency": "ETH", "conversionRate": 556.12, "addressBook": [ { @@ -1248,4 +1250,4 @@ "context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc" } } -}
\ No newline at end of file +} diff --git a/test/unit/app/controllers/network-contoller-test.js b/test/unit/app/controllers/network-contoller-test.js index 822311931..7959e6cc1 100644 --- a/test/unit/app/controllers/network-contoller-test.js +++ b/test/unit/app/controllers/network-contoller-test.js @@ -47,7 +47,7 @@ describe('# Network Controller', function () { describe('#setNetworkState', function () { it('should update the network', function () { - networkController.setNetworkState(1) + networkController.setNetworkState(1, 'rpc') const networkState = networkController.getNetworkState() assert.equal(networkState, 1, 'network is 1') }) diff --git a/test/unit/app/controllers/preferences-controller-test.js b/test/unit/app/controllers/preferences-controller-test.js index 7f2804a83..c64c47ae9 100644 --- a/test/unit/app/controllers/preferences-controller-test.js +++ b/test/unit/app/controllers/preferences-controller-test.js @@ -487,20 +487,20 @@ describe('preferences controller', function () { describe('on updateFrequentRpcList', function () { it('should add custom RPC url to state', function () { - preferencesController.addToFrequentRpcList('rpc_url') - preferencesController.addToFrequentRpcList('http://localhost:8545') - assert.deepEqual(preferencesController.store.getState().frequentRpcList, ['rpc_url']) - preferencesController.addToFrequentRpcList('rpc_url') - assert.deepEqual(preferencesController.store.getState().frequentRpcList, ['rpc_url']) + preferencesController.addToFrequentRpcList('rpc_url', 1) + preferencesController.addToFrequentRpcList('http://localhost:8545', 1) + assert.deepEqual(preferencesController.store.getState().frequentRpcListDetail, [{ rpcUrl: 'rpc_url', chainId: 1, ticker: 'ETH', nickname: '' }] ) + preferencesController.addToFrequentRpcList('rpc_url', 1) + assert.deepEqual(preferencesController.store.getState().frequentRpcListDetail, [{ rpcUrl: 'rpc_url', chainId: 1, ticker: 'ETH', nickname: '' }] ) }) it('should remove custom RPC url from state', function () { - preferencesController.addToFrequentRpcList('rpc_url') - assert.deepEqual(preferencesController.store.getState().frequentRpcList, ['rpc_url']) + preferencesController.addToFrequentRpcList('rpc_url', 1) + assert.deepEqual(preferencesController.store.getState().frequentRpcListDetail, [{ rpcUrl: 'rpc_url', chainId: 1, ticker: 'ETH', nickname: '' }] ) preferencesController.removeFromFrequentRpcList('other_rpc_url') preferencesController.removeFromFrequentRpcList('http://localhost:8545') preferencesController.removeFromFrequentRpcList('rpc_url') - assert.deepEqual(preferencesController.store.getState().frequentRpcList, []) + assert.deepEqual(preferencesController.store.getState().frequentRpcListDetail, []) }) }) }) diff --git a/test/unit/ui/app/actions.spec.js b/test/unit/ui/app/actions.spec.js index 748a58b32..df7d2ee8f 100644 --- a/test/unit/ui/app/actions.spec.js +++ b/test/unit/ui/app/actions.spec.js @@ -1133,7 +1133,7 @@ describe('Actions', () => { { type: 'DISPLAY_WARNING', value: 'Had a problem changing networks!' }, ] - setRpcTargetSpy.callsFake((newRpc, callback) => { + setRpcTargetSpy.callsFake((newRpc, chainId, ticker, nickname, callback) => { callback(new Error('error')) }) diff --git a/ui/app/actions.js b/ui/app/actions.js index f8a375e2f..a8b9189e9 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -309,7 +309,7 @@ var actions = { setPreference, updatePreferences, UPDATE_PREFERENCES: 'UPDATE_PREFERENCES', - setUseETHAsPrimaryCurrencyPreference, + setUseNativeCurrencyAsPrimaryCurrencyPreference, setMouseUserState, SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE', @@ -1874,10 +1874,10 @@ function updateProviderType (type) { } } -function setRpcTarget (newRpc) { +function setRpcTarget (newRpc, chainId, ticker = 'ETH', nickname = '') { return (dispatch) => { - log.debug(`background.setRpcTarget: ${newRpc}`) - background.setCustomRpc(newRpc, (err, result) => { + log.debug(`background.setRpcTarget: ${newRpc} ${chainId} ${ticker} ${nickname}`) + background.setCustomRpc(newRpc, chainId, ticker, nickname, (err, result) => { if (err) { log.error(err) return dispatch(actions.displayWarning('Had a problem changing networks!')) @@ -2330,8 +2330,8 @@ function updatePreferences (value) { } } -function setUseETHAsPrimaryCurrencyPreference (value) { - return setPreference('useETHAsPrimaryCurrency', value) +function setUseNativeCurrencyAsPrimaryCurrencyPreference (value) { + return setPreference('useNativeCurrencyAsPrimaryCurrency', value) } function setNetworkNonce (networkNonce) { diff --git a/ui/app/app.js b/ui/app/app.js index aeb3d05ee..b3aff1f39 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -101,7 +101,7 @@ class App extends Component { network, isMouseUser, provider, - frequentRpcList, + frequentRpcListDetail, currentView, setMouseUserState, sidebar, @@ -147,7 +147,7 @@ class App extends Component { // network dropdown h(NetworkDropdown, { provider, - frequentRpcList, + frequentRpcListDetail, }, []), h(AccountMenu), @@ -230,7 +230,7 @@ App.propTypes = { alertMessage: PropTypes.string, network: PropTypes.string, provider: PropTypes.object, - frequentRpcList: PropTypes.array, + frequentRpcListDetail: PropTypes.array, currentView: PropTypes.object, sidebar: PropTypes.object, alertOpen: PropTypes.bool, @@ -322,7 +322,7 @@ function mapStateToProps (state) { forgottenPassword: state.appState.forgottenPassword, nextUnreadNotice, lostAccounts, - frequentRpcList: state.metamask.frequentRpcList || [], + frequentRpcListDetail: state.metamask.frequentRpcListDetail || [], currentCurrency: state.metamask.currentCurrency, isMouseUser: state.appState.isMouseUser, betaUI: state.metamask.featureFlags.betaUI, diff --git a/ui/app/components/balance-component.js b/ui/app/components/balance-component.js index 799ed20db..0f8514c81 100644 --- a/ui/app/components/balance-component.js +++ b/ui/app/components/balance-component.js @@ -6,7 +6,7 @@ import TokenBalance from './token-balance' import Identicon from './identicon' import UserPreferencedCurrencyDisplay from './user-preferenced-currency-display' import { PRIMARY, SECONDARY } from '../constants/common' -const { getAssetImages, conversionRateSelector, getCurrentCurrency} = require('../selectors') +const { getNativeCurrency, getAssetImages, conversionRateSelector, getCurrentCurrency} = require('../selectors') const { formatBalance } = require('../util') @@ -21,6 +21,7 @@ function mapStateToProps (state) { return { account, network, + nativeCurrency: getNativeCurrency(state), conversionRate: conversionRateSelector(state), currentCurrency: getCurrentCurrency(state), assetImages: getAssetImages(state), @@ -66,10 +67,10 @@ BalanceComponent.prototype.renderTokenBalance = function () { BalanceComponent.prototype.renderBalance = function () { const props = this.props - const { account } = props + const { account, nativeCurrency } = props const balanceValue = account && account.balance const needsParse = 'needsParse' in props ? props.needsParse : true - const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, needsParse) : '...' + const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, needsParse, nativeCurrency) : '...' const showFiat = 'showFiat' in props ? props.showFiat : true if (formattedBalance === 'None' || formattedBalance === '...') { diff --git a/ui/app/components/currency-display/currency-display.component.js b/ui/app/components/currency-display/currency-display.component.js index f39e60269..2d7413b57 100644 --- a/ui/app/components/currency-display/currency-display.component.js +++ b/ui/app/components/currency-display/currency-display.component.js @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' -import { ETH, GWEI } from '../../constants/common' +import { GWEI } from '../../constants/common' export default class CurrencyDisplay extends PureComponent { static propTypes = { @@ -12,7 +12,7 @@ export default class CurrencyDisplay extends PureComponent { style: PropTypes.object, suffix: PropTypes.string, // Used in container - currency: PropTypes.oneOf([ETH]), + currency: PropTypes.string, denomination: PropTypes.oneOf([GWEI]), value: PropTypes.string, numberOfDecimals: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), diff --git a/ui/app/components/currency-input/currency-input.component.js b/ui/app/components/currency-input/currency-input.component.js index 54cd0e1ac..0761a75c5 100644 --- a/ui/app/components/currency-input/currency-input.component.js +++ b/ui/app/components/currency-input/currency-input.component.js @@ -14,6 +14,7 @@ export default class CurrencyInput extends PureComponent { static propTypes = { conversionRate: PropTypes.number, currentCurrency: PropTypes.string, + nativeCurrency: PropTypes.string, onChange: PropTypes.func, onBlur: PropTypes.func, suffix: PropTypes.string, @@ -77,13 +78,13 @@ export default class CurrencyInput extends PureComponent { } renderConversionComponent () { - const { useFiat, currentCurrency } = this.props + const { useFiat, currentCurrency, nativeCurrency } = this.props const { hexValue } = this.state let currency, numberOfDecimals if (useFiat) { // Display ETH - currency = ETH + currency = nativeCurrency || ETH numberOfDecimals = 6 } else { // Display Fiat diff --git a/ui/app/components/currency-input/currency-input.container.js b/ui/app/components/currency-input/currency-input.container.js index 18e5533de..1d1ed7b41 100644 --- a/ui/app/components/currency-input/currency-input.container.js +++ b/ui/app/components/currency-input/currency-input.container.js @@ -3,18 +3,19 @@ import CurrencyInput from './currency-input.component' import { ETH } from '../../constants/common' const mapStateToProps = state => { - const { metamask: { currentCurrency, conversionRate } } = state + const { metamask: { nativeCurrency, currentCurrency, conversionRate } } = state return { + nativeCurrency, currentCurrency, conversionRate, } } const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { currentCurrency } = stateProps + const { nativeCurrency, currentCurrency } = stateProps const { useFiat } = ownProps - const suffix = useFiat ? currentCurrency.toUpperCase() : ETH + const suffix = useFiat ? currentCurrency.toUpperCase() : nativeCurrency || ETH return { ...stateProps, diff --git a/ui/app/components/currency-input/tests/currency-input.component.test.js b/ui/app/components/currency-input/tests/currency-input.component.test.js index 5db53066f..a33889f94 100644 --- a/ui/app/components/currency-input/tests/currency-input.component.test.js +++ b/ui/app/components/currency-input/tests/currency-input.component.test.js @@ -22,6 +22,7 @@ describe('CurrencyInput Component', () => { it('should render properly with a suffix', () => { const mockStore = { metamask: { + nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, }, @@ -32,6 +33,7 @@ describe('CurrencyInput Component', () => { <Provider store={store}> <CurrencyInput suffix="ETH" + nativeCurrency="ETH" /> </Provider> ) @@ -45,6 +47,7 @@ describe('CurrencyInput Component', () => { it('should render properly with an ETH value', () => { const mockStore = { metamask: { + nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, }, @@ -56,6 +59,7 @@ describe('CurrencyInput Component', () => { <CurrencyInput value="de0b6b3a7640000" suffix="ETH" + nativeCurrency="ETH" currentCurrency="usd" conversionRate={231.06} /> @@ -75,6 +79,7 @@ describe('CurrencyInput Component', () => { it('should render properly with a fiat value', () => { const mockStore = { metamask: { + nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, }, @@ -87,6 +92,7 @@ describe('CurrencyInput Component', () => { value="f602f2234d0ea" suffix="USD" useFiat + nativeCurrency="ETH" currentCurrency="usd" conversionRate={231.06} /> @@ -116,6 +122,7 @@ describe('CurrencyInput Component', () => { it('should call onChange and onBlur on input changes with the hex value for ETH', () => { const mockStore = { metamask: { + nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, }, @@ -127,6 +134,7 @@ describe('CurrencyInput Component', () => { onChange={handleChangeSpy} onBlur={handleBlurSpy} suffix="ETH" + nativeCurrency="ETH" currentCurrency="usd" conversionRate={231.06} /> @@ -160,6 +168,7 @@ describe('CurrencyInput Component', () => { it('should call onChange and onBlur on input changes with the hex value for fiat', () => { const mockStore = { metamask: { + nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, }, @@ -171,6 +180,7 @@ describe('CurrencyInput Component', () => { onChange={handleChangeSpy} onBlur={handleBlurSpy} suffix="USD" + nativeCurrency="ETH" currentCurrency="usd" conversionRate={231.06} useFiat @@ -205,6 +215,7 @@ describe('CurrencyInput Component', () => { it('should change the state and pass in a new decimalValue when props.value changes', () => { const mockStore = { metamask: { + nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, }, @@ -216,6 +227,7 @@ describe('CurrencyInput Component', () => { onChange={handleChangeSpy} onBlur={handleBlurSpy} suffix="USD" + nativeCurrency="ETH" currentCurrency="usd" conversionRate={231.06} useFiat diff --git a/ui/app/components/currency-input/tests/currency-input.container.test.js b/ui/app/components/currency-input/tests/currency-input.container.test.js index e77945e4d..5d72958e6 100644 --- a/ui/app/components/currency-input/tests/currency-input.container.test.js +++ b/ui/app/components/currency-input/tests/currency-input.container.test.js @@ -20,12 +20,14 @@ describe('CurrencyInput container', () => { metamask: { conversionRate: 280.45, currentCurrency: 'usd', + nativeCurrency: 'ETH', }, } assert.deepEqual(mapStateToProps(mockState), { conversionRate: 280.45, currentCurrency: 'usd', + nativeCurrency: 'ETH', }) }) }) @@ -35,12 +37,14 @@ describe('CurrencyInput container', () => { const mockStateProps = { conversionRate: 280.45, currentCurrency: 'usd', + nativeCurrency: 'ETH', } const mockDispatchProps = {} assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, { useFiat: true }), { conversionRate: 280.45, currentCurrency: 'usd', + nativeCurrency: 'ETH', useFiat: true, suffix: 'USD', }) @@ -48,6 +52,7 @@ describe('CurrencyInput container', () => { assert.deepEqual(mergeProps(mockStateProps, mockDispatchProps, {}), { conversionRate: 280.45, currentCurrency: 'usd', + nativeCurrency: 'ETH', suffix: 'ETH', }) }) diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js index 9ffcb12cb..e6b3e0c0c 100644 --- a/ui/app/components/dropdowns/components/account-dropdowns.js +++ b/ui/app/components/dropdowns/components/account-dropdowns.js @@ -26,14 +26,14 @@ class AccountDropdowns extends Component { } renderAccounts () { - const { identities, accounts, selected, menuItemStyles, actions, keyrings } = this.props + const { identities, accounts, selected, menuItemStyles, actions, keyrings, ticker } = this.props return Object.keys(identities).map((key, index) => { const identity = identities[key] const isSelected = identity.address === selected const balanceValue = accounts[key].balance - const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' + const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, true, ticker) : '...' const simpleAddress = identity.address.substring(2).toLowerCase() const keyring = keyrings.find((kr) => { @@ -421,6 +421,7 @@ AccountDropdowns.propTypes = { network: PropTypes.number, // actions.showExportPrivateKeyModal: , style: PropTypes.object, + ticker: PropTypes.string, enableAccountsSelector: PropTypes.bool, enableAccountOption: PropTypes.bool, enableAccountOptions: PropTypes.bool, @@ -458,6 +459,7 @@ const mapDispatchToProps = (dispatch) => { function mapStateToProps (state) { return { + ticker: state.metamask.ticker, keyrings: state.metamask.keyrings, sidebarOpen: state.appState.sidebar.isOpen, } diff --git a/ui/app/components/dropdowns/network-dropdown.js b/ui/app/components/dropdowns/network-dropdown.js index b252b25d9..d4cc695a6 100644 --- a/ui/app/components/dropdowns/network-dropdown.js +++ b/ui/app/components/dropdowns/network-dropdown.js @@ -24,8 +24,9 @@ const notToggleElementClassnames = [ function mapStateToProps (state) { return { provider: state.metamask.provider, - frequentRpcList: state.metamask.frequentRpcList || [], + frequentRpcListDetail: state.metamask.frequentRpcListDetail || [], networkDropdownOpen: state.appState.networkDropdownOpen, + network: state.metamask.network, } } @@ -40,8 +41,8 @@ function mapDispatchToProps (dispatch) { setDefaultRpcTarget: type => { dispatch(actions.setDefaultRpcTarget(type)) }, - setRpcTarget: (target) => { - dispatch(actions.setRpcTarget(target)) + setRpcTarget: (target, network, ticker, nickname) => { + dispatch(actions.setRpcTarget(target, network, ticker, nickname)) }, delRpcTarget: (target) => { dispatch(actions.delRpcTarget(target)) @@ -71,7 +72,7 @@ module.exports = compose( NetworkDropdown.prototype.render = function () { const props = this.props const { provider: { type: providerType, rpcTarget: activeNetwork } } = props - const rpcList = props.frequentRpcList + const rpcListDetail = props.frequentRpcListDetail const isOpen = this.props.networkDropdownOpen const dropdownMenuItemStyle = { fontSize: '16px', @@ -225,7 +226,7 @@ NetworkDropdown.prototype.render = function () { ), this.renderCustomOption(props.provider), - this.renderCommonRpc(rpcList, props.provider), + this.renderCommonRpc(rpcListDetail, props.provider), h( DropdownMenuItem, @@ -267,28 +268,33 @@ NetworkDropdown.prototype.getNetworkName = function () { } else if (providerName === 'rinkeby') { name = this.context.t('rinkeby') } else { - name = this.context.t('unknownNetwork') + name = provider.nickname || this.context.t('unknownNetwork') } return name } -NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) { +NetworkDropdown.prototype.renderCommonRpc = function (rpcListDetail, provider) { const props = this.props - const reversedRpcList = rpcList.slice().reverse() + const reversedRpcListDetail = rpcListDetail.slice().reverse() + const network = props.network - return reversedRpcList.map((rpc) => { + return reversedRpcListDetail.map((entry) => { + const rpc = entry.rpcUrl + const ticker = entry.ticker || 'ETH' + const nickname = entry.nickname || '' const currentRpcTarget = provider.type === 'rpc' && rpc === provider.rpcTarget if ((rpc === 'http://localhost:8545') || currentRpcTarget) { return null } else { + const chainId = entry.chainId || network return h( DropdownMenuItem, { key: `common${rpc}`, closeMenu: () => this.props.hideNetworkDropdown(), - onClick: () => props.setRpcTarget(rpc), + onClick: () => props.setRpcTarget(rpc, chainId, ticker, nickname), style: { fontSize: '16px', lineHeight: '20px', @@ -302,7 +308,7 @@ NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) { style: { color: currentRpcTarget ? '#ffffff' : '#9b9b9b', }, - }, rpc), + }, nickname || rpc), h('i.fa.fa-times.delete', { onClick: (e) => { @@ -317,8 +323,9 @@ NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) { } NetworkDropdown.prototype.renderCustomOption = function (provider) { - const { rpcTarget, type } = provider + const { rpcTarget, type, ticker, nickname } = provider const props = this.props + const network = props.network if (type !== 'rpc') return null @@ -332,7 +339,7 @@ NetworkDropdown.prototype.renderCustomOption = function (provider) { DropdownMenuItem, { key: rpcTarget, - onClick: () => props.setRpcTarget(rpcTarget), + onClick: () => props.setRpcTarget(rpcTarget, network, ticker, nickname), closeMenu: () => this.props.hideNetworkDropdown(), style: { fontSize: '16px', @@ -347,7 +354,7 @@ NetworkDropdown.prototype.renderCustomOption = function (provider) { style: { color: '#ffffff', }, - }, rpcTarget), + }, nickname || rpcTarget), ] ) } diff --git a/ui/app/components/dropdowns/tests/network-dropdown.test.js b/ui/app/components/dropdowns/tests/network-dropdown.test.js index 699b54605..88ad56851 100644 --- a/ui/app/components/dropdowns/tests/network-dropdown.test.js +++ b/ui/app/components/dropdowns/tests/network-dropdown.test.js @@ -45,8 +45,8 @@ describe('Network Dropdown', () => { provider: { 'type': 'test', }, - frequentRpcList: [ - 'http://localhost:7545', + frequentRpcListDetail: [ + { rpcUrl: 'http://localhost:7545' }, ], }, appState: { diff --git a/ui/app/components/eth-balance.js b/ui/app/components/eth-balance.js index c3d084bdc..2f6395a2d 100644 --- a/ui/app/components/eth-balance.js +++ b/ui/app/components/eth-balance.js @@ -1,5 +1,6 @@ const { Component } = require('react') const h = require('react-hyperscript') +const connect = require('react-redux').connect const { inherits } = require('util') const { formatBalance, @@ -8,7 +9,12 @@ const { const Tooltip = require('./tooltip.js') const FiatValue = require('./fiat-value.js') -module.exports = EthBalanceComponent +module.exports = connect(mapStateToProps)(EthBalanceComponent) +function mapStateToProps (state) { + return { + ticker: state.metamask.ticker, + } +} inherits(EthBalanceComponent, Component) function EthBalanceComponent () { @@ -17,9 +23,9 @@ function EthBalanceComponent () { EthBalanceComponent.prototype.render = function () { const props = this.props - const { value, style, width, needsParse = true } = props + const { ticker, value, style, width, needsParse = true } = props - const formattedValue = value ? formatBalance(value, 6, needsParse) : '...' + const formattedValue = value ? formatBalance(value, 6, needsParse, ticker) : '...' return ( diff --git a/ui/app/components/network-display/network-display.component.js b/ui/app/components/network-display/network-display.component.js index 38626af20..82f9ff9c3 100644 --- a/ui/app/components/network-display/network-display.component.js +++ b/ui/app/components/network-display/network-display.component.js @@ -41,7 +41,7 @@ export default class NetworkDisplay extends Component { } render () { - const { network, provider: { type } } = this.props + const { network, provider: { type, nickname } } = this.props const networkClass = networkToClassHash[network] return ( @@ -61,7 +61,7 @@ export default class NetworkDisplay extends Component { /> } <div className="network-display__name"> - { this.context.t(type) } + { type === 'rpc' && nickname ? nickname : this.context.t(type) } </div> </div> ) diff --git a/ui/app/components/network.js b/ui/app/components/network.js index 83297c4f2..611aadb7b 100644 --- a/ui/app/components/network.js +++ b/ui/app/components/network.js @@ -23,9 +23,10 @@ Network.prototype.render = function () { const props = this.props const context = this.context const networkNumber = props.network - let providerName + let providerName, providerNick try { providerName = props.provider.type + providerNick = props.provider.nickname || '' } catch (e) { providerName = null } @@ -131,7 +132,7 @@ Network.prototype.render = function () { }, }), - h('.network-name', context.t('privateNetwork')), + h('.network-name', providerNick || context.t('privateNetwork')), h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) } diff --git a/ui/app/components/pages/settings/settings-tab/index.scss b/ui/app/components/pages/settings/settings-tab/index.scss index 3bf840c86..ef32b0e4c 100644 --- a/ui/app/components/pages/settings/settings-tab/index.scss +++ b/ui/app/components/pages/settings/settings-tab/index.scss @@ -5,12 +5,9 @@ color: $crimson; } - &__rpc-save-button { - align-self: flex-end; - padding: 5px; - text-transform: uppercase; - color: $dusty-gray; - cursor: pointer; + &__advanced-link { + color: $curious-blue; + padding-left: 5px; } &__rpc-save-button { @@ -19,6 +16,9 @@ text-transform: uppercase; color: $dusty-gray; cursor: pointer; + width: 25%; + min-width: 80px; + height: 33px; } &__button--red { diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js index a9e2a723e..cd81491a8 100644 --- a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js +++ b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js @@ -55,12 +55,17 @@ export default class SettingsTab extends PureComponent { sendHexData: PropTypes.bool, currentCurrency: PropTypes.string, conversionDate: PropTypes.number, - useETHAsPrimaryCurrency: PropTypes.bool, - setUseETHAsPrimaryCurrencyPreference: PropTypes.func, + nativeCurrency: PropTypes.string, + useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, + setUseNativeCurrencyAsPrimaryCurrencyPreference: PropTypes.func, } state = { newRpc: '', + chainId: '', + showOptions: false, + ticker: '', + nickname: '', } renderCurrentConversion () { @@ -121,37 +126,98 @@ export default class SettingsTab extends PureComponent { renderNewRpcUrl () { const { t } = this.context - const { newRpc } = this.state + const { newRpc, chainId, ticker, nickname } = this.state return ( <div className="settings-page__content-row"> <div className="settings-page__content-item"> - <span>{ t('newRPC') }</span> + <span>{ t('newNetwork') }</span> </div> <div className="settings-page__content-item"> <div className="settings-page__content-item-col"> <TextField type="text" id="new-rpc" - placeholder={t('newRPC')} + placeholder={t('rpcURL')} value={newRpc} onChange={e => this.setState({ newRpc: e.target.value })} onKeyPress={e => { if (e.key === 'Enter') { - this.validateRpc(newRpc) + this.validateRpc(newRpc, chainId, ticker, nickname) } }} fullWidth - margin="none" + margin="dense" /> - <div - className="settings-tab__rpc-save-button" - onClick={e => { - e.preventDefault() - this.validateRpc(newRpc) + <TextField + type="text" + id="chainid" + placeholder={t('optionalChainId')} + value={chainId} + onChange={e => this.setState({ chainId: e.target.value })} + onKeyPress={e => { + if (e.key === 'Enter') { + this.validateRpc(newRpc, chainId, ticker, nickname) + } }} - > - { t('save') } + style={{ + display: this.state.showOptions ? null : 'none', + }} + fullWidth + margin="dense" + /> + <TextField + type="text" + id="ticker" + placeholder={t('optionalSymbol')} + value={ticker} + onChange={e => this.setState({ ticker: e.target.value })} + onKeyPress={e => { + if (e.key === 'Enter') { + this.validateRpc(newRpc, chainId, ticker, nickname) + } + }} + style={{ + display: this.state.showOptions ? null : 'none', + }} + fullWidth + margin="dense" + /> + <TextField + type="text" + id="nickname" + placeholder={t('optionalNickname')} + value={nickname} + onChange={e => this.setState({ nickname: e.target.value })} + onKeyPress={e => { + if (e.key === 'Enter') { + this.validateRpc(newRpc, chainId, ticker, nickname) + } + }} + style={{ + display: this.state.showOptions ? null : 'none', + }} + fullWidth + margin="dense" + /> + <div className="flex-row flex-align-center space-between"> + <span className="settings-tab__advanced-link" + onClick={e => { + e.preventDefault() + this.setState({ showOptions: !this.state.showOptions }) + }} + > + { t(this.state.showOptions ? 'hideAdvancedOptions' : 'showAdvancedOptions') } + </span> + <button + className="button btn-primary settings-tab__rpc-save-button" + onClick={e => { + e.preventDefault() + this.validateRpc(newRpc, chainId, ticker, nickname) + }} + > + { t('save') } + </button> </div> </div> </div> @@ -159,11 +225,11 @@ export default class SettingsTab extends PureComponent { ) } - validateRpc (newRpc) { + validateRpc (newRpc, chainId, ticker = 'ETH', nickname) { const { setRpcTarget, displayWarning } = this.props if (validUrl.isWebUri(newRpc)) { - setRpcTarget(newRpc) + setRpcTarget(newRpc, chainId, ticker, nickname) } else { const appendedRpc = `http://${newRpc}` @@ -341,9 +407,13 @@ export default class SettingsTab extends PureComponent { ) } - renderUseEthAsPrimaryCurrency () { + renderUsePrimaryCurrencyOptions () { const { t } = this.context - const { useETHAsPrimaryCurrency, setUseETHAsPrimaryCurrencyPreference } = this.props + const { + nativeCurrency, + setUseNativeCurrencyAsPrimaryCurrencyPreference, + useNativeCurrencyAsPrimaryCurrency, + } = this.props return ( <div className="settings-page__content-row"> @@ -359,23 +429,23 @@ export default class SettingsTab extends PureComponent { <div className="settings-tab__radio-button"> <input type="radio" - id="eth-primary-currency" - onChange={() => setUseETHAsPrimaryCurrencyPreference(true)} - checked={Boolean(useETHAsPrimaryCurrency)} + id="native-primary-currency" + onChange={() => setUseNativeCurrencyAsPrimaryCurrencyPreference(true)} + checked={Boolean(useNativeCurrencyAsPrimaryCurrency)} /> <label - htmlFor="eth-primary-currency" + htmlFor="native-primary-currency" className="settings-tab__radio-label" > - { t('eth') } + { nativeCurrency } </label> </div> <div className="settings-tab__radio-button"> <input type="radio" id="fiat-primary-currency" - onChange={() => setUseETHAsPrimaryCurrencyPreference(false)} - checked={!useETHAsPrimaryCurrency} + onChange={() => setUseNativeCurrencyAsPrimaryCurrencyPreference(false)} + checked={!useNativeCurrencyAsPrimaryCurrency} /> <label htmlFor="fiat-primary-currency" @@ -398,7 +468,7 @@ export default class SettingsTab extends PureComponent { <div className="settings-page__content"> { warning && <div className="settings-tab__error">{ warning }</div> } { this.renderCurrentConversion() } - { this.renderUseEthAsPrimaryCurrency() } + { this.renderUsePrimaryCurrencyOptions() } { this.renderCurrentLocale() } { this.renderNewRpcUrl() } { this.renderStateLogs() } diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.container.js b/ui/app/components/pages/settings/settings-tab/settings-tab.container.js index de30f309c..f4110207e 100644 --- a/ui/app/components/pages/settings/settings-tab/settings-tab.container.js +++ b/ui/app/components/pages/settings/settings-tab/settings-tab.container.js @@ -11,7 +11,7 @@ import { updateCurrentLocale, setFeatureFlag, showModal, - setUseETHAsPrimaryCurrencyPreference, + setUseNativeCurrencyAsPrimaryCurrencyPreference, } from '../../../../actions' import { preferencesSelector } from '../../../../selectors' @@ -20,13 +20,14 @@ const mapStateToProps = state => { const { currentCurrency, conversionDate, + nativeCurrency, useBlockie, featureFlags: { sendHexData } = {}, provider = {}, isMascara, currentLocale, } = metamask - const { useETHAsPrimaryCurrency } = preferencesSelector(state) + const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state) return { warning, @@ -34,17 +35,18 @@ const mapStateToProps = state => { currentLocale, currentCurrency, conversionDate, + nativeCurrency, useBlockie, sendHexData, provider, - useETHAsPrimaryCurrency, + useNativeCurrencyAsPrimaryCurrency, } } const mapDispatchToProps = dispatch => { return { setCurrentCurrency: currency => dispatch(setCurrentCurrency(currency)), - setRpcTarget: newRpc => dispatch(setRpcTarget(newRpc)), + setRpcTarget: (newRpc, chainId, ticker, nickname) => dispatch(setRpcTarget(newRpc, chainId, ticker, nickname)), displayWarning: warning => dispatch(displayWarning(warning)), revealSeedConfirmation: () => dispatch(revealSeedConfirmation()), setUseBlockie: value => dispatch(setUseBlockie(value)), @@ -54,8 +56,8 @@ const mapDispatchToProps = dispatch => { }, setHexDataFeatureFlag: shouldShow => dispatch(setFeatureFlag('sendHexData', shouldShow)), showResetAccountConfirmationModal: () => dispatch(showModal({ name: 'CONFIRM_RESET_ACCOUNT' })), - setUseETHAsPrimaryCurrencyPreference: value => { - return dispatch(setUseETHAsPrimaryCurrencyPreference(value)) + setUseNativeCurrencyAsPrimaryCurrencyPreference: value => { + return dispatch(setUseNativeCurrencyAsPrimaryCurrencyPreference(value)) }, } } diff --git a/ui/app/components/send/account-list-item/account-list-item.container.js b/ui/app/components/send/account-list-item/account-list-item.container.js index 4b4519288..f8e73d923 100644 --- a/ui/app/components/send/account-list-item/account-list-item.container.js +++ b/ui/app/components/send/account-list-item/account-list-item.container.js @@ -2,6 +2,7 @@ import { connect } from 'react-redux' import { getConversionRate, getCurrentCurrency, + getNativeCurrency, } from '../send.selectors.js' import AccountListItem from './account-list-item.component' @@ -11,5 +12,6 @@ function mapStateToProps (state) { return { conversionRate: getConversionRate(state), currentCurrency: getCurrentCurrency(state), + nativeCurrency: getNativeCurrency(state), } } diff --git a/ui/app/components/send/account-list-item/tests/account-list-item-component.test.js b/ui/app/components/send/account-list-item/tests/account-list-item-component.test.js index f88c0dbd0..6ffc0b1c6 100644 --- a/ui/app/components/send/account-list-item/tests/account-list-item-component.test.js +++ b/ui/app/components/send/account-list-item/tests/account-list-item-component.test.js @@ -28,6 +28,7 @@ describe('AccountListItem Component', function () { className={'mockClassName'} conversionRate={4} currentCurrency={'mockCurrentyCurrency'} + nativeCurrency={'ETH'} displayAddress={false} displayBalance={false} handleClick={propsMethodSpies.handleClick} diff --git a/ui/app/components/send/account-list-item/tests/account-list-item-container.test.js b/ui/app/components/send/account-list-item/tests/account-list-item-container.test.js index af0859117..7c2f5fcb2 100644 --- a/ui/app/components/send/account-list-item/tests/account-list-item-container.test.js +++ b/ui/app/components/send/account-list-item/tests/account-list-item-container.test.js @@ -13,6 +13,7 @@ proxyquire('../account-list-item.container.js', { '../send.selectors.js': { getConversionRate: (s) => `mockConversionRate:${s}`, getCurrentCurrency: (s) => `mockCurrentCurrency:${s}`, + getNativeCurrency: (s) => `mockNativeCurrency:${s}`, }, }) @@ -24,6 +25,7 @@ describe('account-list-item container', () => { assert.deepEqual(mapStateToProps('mockState'), { conversionRate: 'mockConversionRate:mockState', currentCurrency: 'mockCurrentCurrency:mockState', + nativeCurrency: 'mockNativeCurrency:mockState', }) }) diff --git a/ui/app/components/send/send.selectors.js b/ui/app/components/send/send.selectors.js index 22e379693..eb22a08b7 100644 --- a/ui/app/components/send/send.selectors.js +++ b/ui/app/components/send/send.selectors.js @@ -19,6 +19,7 @@ const selectors = { getCurrentNetwork, getCurrentViewContext, getForceGasMin, + getNativeCurrency, getGasLimit, getGasPrice, getGasPriceFromRecentBlocks, @@ -111,6 +112,10 @@ function getCurrentCurrency (state) { return state.metamask.currentCurrency } +function getNativeCurrency (state) { + return state.metamask.nativeCurrency +} + function getCurrentNetwork (state) { return state.metamask.network } diff --git a/ui/app/components/send/tests/send-selectors-test-data.js b/ui/app/components/send/tests/send-selectors-test-data.js index 8b939dadb..30a2666cf 100644 --- a/ui/app/components/send/tests/send-selectors-test-data.js +++ b/ui/app/components/send/tests/send-selectors-test-data.js @@ -26,6 +26,7 @@ module.exports = { 'currentCurrency': 'USD', 'conversionRate': 1200.88200327, 'conversionDate': 1489013762, + 'nativeCurrency': 'ETH', 'noActiveNotices': true, 'frequentRpcList': [], 'network': '3', diff --git a/ui/app/components/send/tests/send-selectors.test.js b/ui/app/components/send/tests/send-selectors.test.js index 1a47cd209..e7e901f0d 100644 --- a/ui/app/components/send/tests/send-selectors.test.js +++ b/ui/app/components/send/tests/send-selectors.test.js @@ -12,6 +12,7 @@ const { getCurrentCurrency, getCurrentNetwork, getCurrentViewContext, + getNativeCurrency, getForceGasMin, getGasLimit, getGasPrice, @@ -178,6 +179,15 @@ describe('send selectors', () => { }) }) + describe('getNativeCurrency()', () => { + it('should return the ticker symbol of the selected network', () => { + assert.equal( + getNativeCurrency(mockState), + 'ETH' + ) + }) + }) + describe('getCurrentNetwork()', () => { it('should return the id of the currently selected network', () => { assert.equal( diff --git a/ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js b/ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js index 85d56a6a2..a7c35f51e 100644 --- a/ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js +++ b/ui/app/components/transaction-activity-log/tests/transaction-activity-log.container.test.js @@ -18,10 +18,11 @@ describe('TransactionActivityLog container', () => { const mockState = { metamask: { conversionRate: 280.45, + nativeCurrency: 'ETH', }, } - assert.deepEqual(mapStateToProps(mockState), { conversionRate: 280.45 }) + assert.deepEqual(mapStateToProps(mockState), { conversionRate: 280.45, nativeCurrency: 'ETH' }) }) }) }) diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.component.js b/ui/app/components/transaction-activity-log/transaction-activity-log.component.js index 0e6c2376f..58d932a0f 100644 --- a/ui/app/components/transaction-activity-log/transaction-activity-log.component.js +++ b/ui/app/components/transaction-activity-log/transaction-activity-log.component.js @@ -4,7 +4,6 @@ import classnames from 'classnames' import { getActivities } from './transaction-activity-log.util' import Card from '../card' import { getEthConversionFromWeiHex, getValueFromWeiHex } from '../../helpers/conversions.util' -import { ETH } from '../../constants/common' import { formatDate } from '../../util' export default class TransactionActivityLog extends PureComponent { @@ -16,6 +15,7 @@ export default class TransactionActivityLog extends PureComponent { transaction: PropTypes.object, className: PropTypes.string, conversionRate: PropTypes.number, + nativeCurrency: PropTypes.string, } state = { @@ -45,16 +45,17 @@ export default class TransactionActivityLog extends PureComponent { } renderActivity (activity, index) { - const { conversionRate } = this.props + const { conversionRate, nativeCurrency } = this.props const { eventKey, value, timestamp } = activity const ethValue = index === 0 ? `${getValueFromWeiHex({ value, - toCurrency: ETH, + fromCurrency: nativeCurrency, + toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6, - })} ${ETH}` - : getEthConversionFromWeiHex({ value, toCurrency: ETH, conversionRate }) + })} ${nativeCurrency}` + : getEthConversionFromWeiHex({ value, fromCurrency: nativeCurrency, conversionRate }) const formattedTimestamp = formatDate(timestamp) const activityText = this.context.t(eventKey, [ethValue, formattedTimestamp]) diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.container.js b/ui/app/components/transaction-activity-log/transaction-activity-log.container.js index 4c8b6d971..622f77df1 100644 --- a/ui/app/components/transaction-activity-log/transaction-activity-log.container.js +++ b/ui/app/components/transaction-activity-log/transaction-activity-log.container.js @@ -1,10 +1,11 @@ import { connect } from 'react-redux' import TransactionActivityLog from './transaction-activity-log.component' -import { conversionRateSelector } from '../../selectors' +import { conversionRateSelector, getNativeCurrency } from '../../selectors' const mapStateToProps = state => { return { conversionRate: conversionRateSelector(state), + nativeCurrency: getNativeCurrency(state), } } diff --git a/ui/app/components/transaction-breakdown/index.js b/ui/app/components/transaction-breakdown/index.js index c887f504f..4a5b52663 100644 --- a/ui/app/components/transaction-breakdown/index.js +++ b/ui/app/components/transaction-breakdown/index.js @@ -1 +1 @@ -export { default } from './transaction-breakdown.component' +export { default } from './transaction-breakdown.container' diff --git a/ui/app/components/transaction-breakdown/transaction-breakdown.component.js b/ui/app/components/transaction-breakdown/transaction-breakdown.component.js index 77bedcad7..3a7647873 100644 --- a/ui/app/components/transaction-breakdown/transaction-breakdown.component.js +++ b/ui/app/components/transaction-breakdown/transaction-breakdown.component.js @@ -6,7 +6,7 @@ import Card from '../card' import CurrencyDisplay from '../currency-display' import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display' import HexToDecimal from '../hex-to-decimal' -import { ETH, GWEI, PRIMARY, SECONDARY } from '../../constants/common' +import { GWEI, PRIMARY, SECONDARY } from '../../constants/common' import { getHexGasTotal } from '../../helpers/confirm-transaction/util' import { sumHexes } from '../../helpers/transactions.util' @@ -18,6 +18,7 @@ export default class TransactionBreakdown extends PureComponent { static propTypes = { transaction: PropTypes.object, className: PropTypes.string, + nativeCurrency: PropTypes.string.isRequired, } static defaultProps = { @@ -26,7 +27,7 @@ export default class TransactionBreakdown extends PureComponent { render () { const { t } = this.context - const { transaction, className } = this.props + const { transaction, className, nativeCurrency } = this.props const { txParams: { gas, gasPrice, value } = {}, txReceipt: { gasUsed } = {} } = transaction const gasLimit = typeof gasUsed === 'string' ? gasUsed : gas @@ -72,7 +73,7 @@ export default class TransactionBreakdown extends PureComponent { <TransactionBreakdownRow title={t('gasPrice')}> <CurrencyDisplay className="transaction-breakdown__value" - currency={ETH} + currency={nativeCurrency} denomination={GWEI} value={gasPrice} hideLabel diff --git a/ui/app/components/transaction-breakdown/transaction-breakdown.container.js b/ui/app/components/transaction-breakdown/transaction-breakdown.container.js new file mode 100644 index 000000000..ed2708e03 --- /dev/null +++ b/ui/app/components/transaction-breakdown/transaction-breakdown.container.js @@ -0,0 +1,11 @@ +import { connect } from 'react-redux' +import TransactionBreakdown from './transaction-breakdown.component' +import { getNativeCurrency } from '../../selectors' + +const mapStateToProps = (state) => { + return { + nativeCurrency: getNativeCurrency(state), + } +} + +export default connect(mapStateToProps)(TransactionBreakdown) diff --git a/ui/app/components/transaction-view-balance/transaction-view-balance.container.js b/ui/app/components/transaction-view-balance/transaction-view-balance.container.js index 30c5cab16..cb8078ec1 100644 --- a/ui/app/components/transaction-view-balance/transaction-view-balance.container.js +++ b/ui/app/components/transaction-view-balance/transaction-view-balance.container.js @@ -2,7 +2,7 @@ import { connect } from 'react-redux' import { withRouter } from 'react-router-dom' import { compose } from 'recompose' import TransactionViewBalance from './transaction-view-balance.component' -import { getSelectedToken, getSelectedAddress, getSelectedTokenAssetImage } from '../../selectors' +import { getSelectedToken, getSelectedAddress, getNativeCurrency, getSelectedTokenAssetImage } from '../../selectors' import { showModal } from '../../actions' const mapStateToProps = state => { @@ -15,6 +15,7 @@ const mapStateToProps = state => { selectedToken: getSelectedToken(state), network, balance, + nativeCurrency: getNativeCurrency(state), assetImage: getSelectedTokenAssetImage(state), } } diff --git a/ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js b/ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js index 41ad3b73e..ba1c23d83 100644 --- a/ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js +++ b/ui/app/components/user-preferenced-currency-display/tests/user-preferenced-currency-display.container.test.js @@ -18,14 +18,16 @@ describe('UserPreferencedCurrencyDisplay container', () => { it('should return the correct props', () => { const mockState = { metamask: { + nativeCurrency: 'ETH', preferences: { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, }, }, } assert.deepEqual(mapStateToProps(mockState), { - useETHAsPrimaryCurrency: true, + nativeCurrency: 'ETH', + useNativeCurrencyAsPrimaryCurrency: true, }) }) }) @@ -37,33 +39,38 @@ describe('UserPreferencedCurrencyDisplay container', () => { const tests = [ { stateProps: { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, + nativeCurrency: 'ETH', }, ownProps: { type: 'PRIMARY', }, result: { currency: 'ETH', + nativeCurrency: 'ETH', numberOfDecimals: 6, prefix: undefined, }, }, { stateProps: { - useETHAsPrimaryCurrency: false, + useNativeCurrencyAsPrimaryCurrency: false, + nativeCurrency: 'ETH', }, ownProps: { type: 'PRIMARY', }, result: { currency: undefined, + nativeCurrency: 'ETH', numberOfDecimals: 2, prefix: undefined, }, }, { stateProps: { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, + nativeCurrency: 'ETH', }, ownProps: { type: 'SECONDARY', @@ -71,6 +78,7 @@ describe('UserPreferencedCurrencyDisplay container', () => { fiatPrefix: '-', }, result: { + nativeCurrency: 'ETH', currency: undefined, numberOfDecimals: 4, prefix: '-', @@ -78,7 +86,8 @@ describe('UserPreferencedCurrencyDisplay container', () => { }, { stateProps: { - useETHAsPrimaryCurrency: false, + useNativeCurrencyAsPrimaryCurrency: false, + nativeCurrency: 'ETH', }, ownProps: { type: 'SECONDARY', @@ -89,6 +98,7 @@ describe('UserPreferencedCurrencyDisplay container', () => { }, result: { currency: 'ETH', + nativeCurrency: 'ETH', numberOfDecimals: 3, prefix: 'b', }, diff --git a/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js b/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js index 4d948ca6a..f2a834ea7 100644 --- a/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js +++ b/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.component.js @@ -21,6 +21,7 @@ export default class UserPreferencedCurrencyDisplay extends PureComponent { fiatPrefix: PropTypes.string, // From container currency: PropTypes.string, + nativeCurrency: PropTypes.string, } renderEthLogo () { diff --git a/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js b/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js index 23240c649..7999301ad 100644 --- a/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js +++ b/ui/app/components/user-preferenced-currency-display/user-preferenced-currency-display.container.js @@ -4,15 +4,16 @@ import { preferencesSelector } from '../../selectors' import { ETH, PRIMARY, SECONDARY } from '../../constants/common' const mapStateToProps = (state, ownProps) => { - const { useETHAsPrimaryCurrency } = preferencesSelector(state) + const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state) return { - useETHAsPrimaryCurrency, + useNativeCurrencyAsPrimaryCurrency, + nativeCurrency: state.metamask.nativeCurrency, } } const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { useETHAsPrimaryCurrency, ...restStateProps } = stateProps + const { useNativeCurrencyAsPrimaryCurrency, nativeCurrency, ...restStateProps } = stateProps const { type, numberOfDecimals: propsNumberOfDecimals, @@ -26,14 +27,14 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { let currency, numberOfDecimals, prefix - if (type === PRIMARY && useETHAsPrimaryCurrency || - type === SECONDARY && !useETHAsPrimaryCurrency) { + if (type === PRIMARY && useNativeCurrencyAsPrimaryCurrency || + type === SECONDARY && !useNativeCurrencyAsPrimaryCurrency) { // Display ETH - currency = ETH + currency = nativeCurrency || ETH numberOfDecimals = propsNumberOfDecimals || ethNumberOfDecimals || 6 prefix = propsPrefix || ethPrefix - } else if (type === SECONDARY && useETHAsPrimaryCurrency || - type === PRIMARY && !useETHAsPrimaryCurrency) { + } else if (type === SECONDARY && useNativeCurrencyAsPrimaryCurrency || + type === PRIMARY && !useNativeCurrencyAsPrimaryCurrency) { // Display Fiat numberOfDecimals = propsNumberOfDecimals || fiatNumberOfDecimals || 2 prefix = propsPrefix || fiatPrefix @@ -43,6 +44,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...restStateProps, ...dispatchProps, ...restOwnProps, + nativeCurrency, currency, numberOfDecimals, prefix, diff --git a/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js b/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js index 0af80a03d..710b5d519 100644 --- a/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js +++ b/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.component.test.js @@ -15,17 +15,17 @@ describe('UserPreferencedCurrencyInput Component', () => { assert.equal(wrapper.find(CurrencyInput).length, 1) }) - it('should render useFiat for CurrencyInput based on preferences.useETHAsPrimaryCurrency', () => { + it('should render useFiat for CurrencyInput based on preferences.useNativeCurrencyAsPrimaryCurrency', () => { const wrapper = shallow( <UserPreferencedCurrencyInput - useETHAsPrimaryCurrency + useNativeCurrencyAsPrimaryCurrency /> ) assert.ok(wrapper) assert.equal(wrapper.find(CurrencyInput).length, 1) assert.equal(wrapper.find(CurrencyInput).props().useFiat, false) - wrapper.setProps({ useETHAsPrimaryCurrency: false }) + wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }) assert.equal(wrapper.find(CurrencyInput).props().useFiat, true) }) }) diff --git a/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js b/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js index d860c38da..959726443 100644 --- a/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js +++ b/ui/app/components/user-preferenced-currency-input/tests/user-preferenced-currency-input.container.test.js @@ -18,13 +18,13 @@ describe('UserPreferencedCurrencyInput container', () => { const mockState = { metamask: { preferences: { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, }, }, } assert.deepEqual(mapStateToProps(mockState), { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, }) }) }) diff --git a/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js b/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js index 6e0e00a1d..463e66b80 100644 --- a/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js +++ b/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.component.js @@ -4,16 +4,16 @@ import CurrencyInput from '../currency-input' export default class UserPreferencedCurrencyInput extends PureComponent { static propTypes = { - useETHAsPrimaryCurrency: PropTypes.bool, + useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, } render () { - const { useETHAsPrimaryCurrency, ...restProps } = this.props + const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props return ( <CurrencyInput {...restProps} - useFiat={!useETHAsPrimaryCurrency} + useFiat={!useNativeCurrencyAsPrimaryCurrency} /> ) } diff --git a/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js b/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js index 397cdc7cc..0b88eb5a7 100644 --- a/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js +++ b/ui/app/components/user-preferenced-currency-input/user-preferenced-currency-input.container.js @@ -3,10 +3,10 @@ import UserPreferencedCurrencyInput from './user-preferenced-currency-input.comp import { preferencesSelector } from '../../selectors' const mapStateToProps = state => { - const { useETHAsPrimaryCurrency } = preferencesSelector(state) + const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state) return { - useETHAsPrimaryCurrency, + useNativeCurrencyAsPrimaryCurrency, } } diff --git a/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js b/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js index 910c7089f..d85bddeeb 100644 --- a/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js +++ b/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.component.test.js @@ -15,17 +15,17 @@ describe('UserPreferencedCurrencyInput Component', () => { assert.equal(wrapper.find(TokenInput).length, 1) }) - it('should render showFiat for TokenInput based on preferences.useETHAsPrimaryCurrency', () => { + it('should render showFiat for TokenInput based on preferences.useNativeCurrencyAsPrimaryCurrency', () => { const wrapper = shallow( <UserPreferencedTokenInput - useETHAsPrimaryCurrency + useNativeCurrencyAsPrimaryCurrency /> ) assert.ok(wrapper) assert.equal(wrapper.find(TokenInput).length, 1) assert.equal(wrapper.find(TokenInput).props().showFiat, false) - wrapper.setProps({ useETHAsPrimaryCurrency: false }) + wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }) assert.equal(wrapper.find(TokenInput).props().showFiat, true) }) }) diff --git a/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js b/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js index e3509149a..2f89fba90 100644 --- a/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js +++ b/ui/app/components/user-preferenced-token-input/tests/user-preferenced-token-input.container.test.js @@ -18,13 +18,13 @@ describe('UserPreferencedTokenInput container', () => { const mockState = { metamask: { preferences: { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, }, }, } assert.deepEqual(mapStateToProps(mockState), { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, }) }) }) diff --git a/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js b/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js index f2b537f11..8f14231ac 100644 --- a/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js +++ b/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.component.js @@ -4,16 +4,16 @@ import TokenInput from '../token-input' export default class UserPreferencedTokenInput extends PureComponent { static propTypes = { - useETHAsPrimaryCurrency: PropTypes.bool, + useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, } render () { - const { useETHAsPrimaryCurrency, ...restProps } = this.props + const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props return ( <TokenInput {...restProps} - showFiat={!useETHAsPrimaryCurrency} + showFiat={!useNativeCurrencyAsPrimaryCurrency} /> ) } diff --git a/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js b/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js index 416d069dd..3305d4e29 100644 --- a/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js +++ b/ui/app/components/user-preferenced-token-input/user-preferenced-token-input.container.js @@ -3,10 +3,10 @@ import UserPreferencedTokenInput from './user-preferenced-token-input.component' import { preferencesSelector } from '../../selectors' const mapStateToProps = state => { - const { useETHAsPrimaryCurrency } = preferencesSelector(state) + const { useNativeCurrencyAsPrimaryCurrency } = preferencesSelector(state) return { - useETHAsPrimaryCurrency, + useNativeCurrencyAsPrimaryCurrency, } } diff --git a/ui/app/css/itcss/components/buttons.scss b/ui/app/css/itcss/components/buttons.scss index e4d379a02..5826a8b49 100644 --- a/ui/app/css/itcss/components/buttons.scss +++ b/ui/app/css/itcss/components/buttons.scss @@ -82,6 +82,7 @@ box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.08); padding: 6px; height: initial; + min-height: initial; width: initial; min-width: initial; } diff --git a/ui/app/ducks/confirm-transaction.duck.js b/ui/app/ducks/confirm-transaction.duck.js index 328943cd3..275eb1551 100644 --- a/ui/app/ducks/confirm-transaction.duck.js +++ b/ui/app/ducks/confirm-transaction.duck.js @@ -2,6 +2,7 @@ import { conversionRateSelector, currentCurrencySelector, unconfirmedTransactionsHashSelector, + getNativeCurrency, } from '../selectors/confirm-transaction' import { @@ -292,16 +293,17 @@ export function updateTxDataAndCalculate (txData) { const state = getState() const currentCurrency = currentCurrencySelector(state) const conversionRate = conversionRateSelector(state) + const nativeCurrency = getNativeCurrency(state) dispatch(updateTxData(txData)) const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {} } = txData const fiatTransactionAmount = getValueFromWeiHex({ - value, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2, + value, fromCurrency: nativeCurrency, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2, }) const ethTransactionAmount = getValueFromWeiHex({ - value, toCurrency: 'ETH', conversionRate, numberOfDecimals: 6, + value, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6, }) dispatch(updateTransactionAmounts({ @@ -314,13 +316,15 @@ export function updateTxDataAndCalculate (txData) { const fiatTransactionFee = getTransactionFee({ value: hexTransactionFee, + fromCurrency: nativeCurrency, toCurrency: currentCurrency, numberOfDecimals: 2, conversionRate, }) const ethTransactionFee = getTransactionFee({ value: hexTransactionFee, - toCurrency: 'ETH', + fromCurrency: nativeCurrency, + toCurrency: nativeCurrency, numberOfDecimals: 6, conversionRate, }) diff --git a/ui/app/helpers/confirm-transaction/util.js b/ui/app/helpers/confirm-transaction/util.js index bcac22500..eb334a4b8 100644 --- a/ui/app/helpers/confirm-transaction/util.js +++ b/ui/app/helpers/confirm-transaction/util.js @@ -55,6 +55,7 @@ export function addFiat (...args) { export function getValueFromWeiHex ({ value, + fromCurrency = 'ETH', toCurrency, conversionRate, numberOfDecimals, @@ -63,7 +64,7 @@ export function getValueFromWeiHex ({ return conversionUtil(value, { fromNumericBase: 'hex', toNumericBase: 'dec', - fromCurrency: 'ETH', + fromCurrency, toCurrency, numberOfDecimals, fromDenomination: 'WEI', @@ -74,6 +75,7 @@ export function getValueFromWeiHex ({ export function getTransactionFee ({ value, + fromCurrency = 'ETH', toCurrency, conversionRate, numberOfDecimals, @@ -82,7 +84,7 @@ export function getTransactionFee ({ fromNumericBase: 'BN', toNumericBase: 'dec', fromDenomination: 'WEI', - fromCurrency: 'ETH', + fromCurrency, toCurrency, numberOfDecimals, conversionRate, @@ -99,6 +101,7 @@ export function formatCurrency (value, currencyCode) { export function convertTokenToFiat ({ value, + fromCurrency = 'ETH', toCurrency, conversionRate, contractExchangeRate, @@ -108,6 +111,7 @@ export function convertTokenToFiat ({ return conversionUtil(value, { fromNumericBase: 'dec', toNumericBase: 'dec', + fromCurrency, toCurrency, numberOfDecimals: 2, conversionRate: totalExchangeRate, diff --git a/ui/app/helpers/conversions.util.js b/ui/app/helpers/conversions.util.js index 777537e1e..cb5e1b90b 100644 --- a/ui/app/helpers/conversions.util.js +++ b/ui/app/helpers/conversions.util.js @@ -20,8 +20,8 @@ export function decimalToHex (decimal) { }) } -export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDecimals = 6 }) { - const denominations = [ETH, GWEI, WEI] +export function getEthConversionFromWeiHex ({ value, fromCurrency = ETH, conversionRate, numberOfDecimals = 6 }) { + const denominations = [fromCurrency, GWEI, WEI] let nonZeroDenomination @@ -29,7 +29,8 @@ export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDec const convertedValue = getValueFromWeiHex({ value, conversionRate, - toCurrency: ETH, + fromCurrency, + toCurrency: fromCurrency, numberOfDecimals, toDenomination: denominations[i], }) @@ -45,6 +46,7 @@ export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDec export function getValueFromWeiHex ({ value, + fromCurrency = ETH, toCurrency, conversionRate, numberOfDecimals, @@ -53,7 +55,7 @@ export function getValueFromWeiHex ({ return conversionUtil(value, { fromNumericBase: 'hex', toNumericBase: 'dec', - fromCurrency: ETH, + fromCurrency, toCurrency, numberOfDecimals, fromDenomination: WEI, diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index 37d8a9187..22fa53098 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -52,7 +52,7 @@ function reduceMetamask (state, action) { welcomeScreenSeen: false, currentLocale: '', preferences: { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, }, }, state.metamask) diff --git a/ui/app/selectors.js b/ui/app/selectors.js index 9f11551be..7209f19d1 100644 --- a/ui/app/selectors.js +++ b/ui/app/selectors.js @@ -26,6 +26,7 @@ const selectors = { getAddressBook, getSendFrom, getCurrentCurrency, + getNativeCurrency, getSendAmount, getSelectedTokenToFiatRate, getSelectedTokenContract, @@ -143,6 +144,10 @@ function getCurrentCurrency (state) { return state.metamask.currentCurrency } +function getNativeCurrency (state) { + return state.metamask.nativeCurrency +} + function getSelectedTokenToFiatRate (state) { const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state) const conversionRate = conversionRateSelector(state) diff --git a/ui/app/selectors/confirm-transaction.js b/ui/app/selectors/confirm-transaction.js index 86b10bac3..90924c036 100644 --- a/ui/app/selectors/confirm-transaction.js +++ b/ui/app/selectors/confirm-transaction.js @@ -93,6 +93,7 @@ export const unconfirmedTransactionsCountSelector = createSelector( export const currentCurrencySelector = state => state.metamask.currentCurrency export const conversionRateSelector = state => state.metamask.conversionRate +export const getNativeCurrency = state => state.metamask.nativeCurrency const txDataSelector = state => state.confirmTransaction.txData const tokenDataSelector = state => state.confirmTransaction.tokenData diff --git a/ui/app/util.js b/ui/app/util.js index 37c0fb698..b19a028cc 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -128,7 +128,7 @@ function parseBalance (balance) { // Takes wei hex, returns an object with three properties. // Its "formatted" property is what we generally use to render values. -function formatBalance (balance, decimalsToKeep, needsParse = true) { +function formatBalance (balance, decimalsToKeep, needsParse = true, ticker = 'ETH') { var parsed = needsParse ? parseBalance(balance) : balance.split('.') var beforeDecimal = parsed[0] var afterDecimal = parsed[1] @@ -138,14 +138,14 @@ function formatBalance (balance, decimalsToKeep, needsParse = true) { if (afterDecimal !== '0') { var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits if (sigFigs) { afterDecimal = sigFigs[0] } - formatted = '0.' + afterDecimal + ' ETH' + formatted = '0.' + afterDecimal + ` ${ticker}` } } else { - formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ' ETH' + formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ` ${ticker}` } } else { afterDecimal += Array(decimalsToKeep).join('0') - formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ' ETH' + formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ` ${ticker}` } return formatted } |